Files
ai-for-dummies/src/pages/full-guide.astro
T
Marcos Paulo ef5e8e8b42
verify-and-publish / gate (push) Successful in 9m16s
verify-and-publish / publish (push) Has been skipped
fix: restore full-guide font scale
2026-09-06 09:38:07 +00:00

3241 lines
99 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
// /full-guide/ — assembled from typed guide collections and the task 10 blocks.
// This route deliberately never imports the legacy full-guide HTML: task 20 removes
// that tree, and both locales must be present in the server-rendered document.
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import FleetDiagram from '../components/blocks/FleetDiagram.astro';
import HandoffTable from '../components/blocks/HandoffTable.astro';
import PhasePanel from '../components/blocks/PhasePanel.astro';
import RouteTable from '../components/blocks/RouteTable.astro';
import SkillPackage from '../components/blocks/SkillPackage.astro';
import WorktreeMap from '../components/blocks/WorktreeMap.astro';
import CopyPrompt from '../components/islands/CopyPrompt.astro';
import GuideSelector from '../components/islands/GuideSelector.astro';
import LanguageToggle from '../components/islands/LanguageToggle.astro';
import ReadingProgress from '../components/islands/ReadingProgress.astro';
import '../../legacy/styles/guide.css';
import '../../legacy/styles/audit.css';
type Entry<T extends { id: string }> = { data: T };
const toRecord = <T extends { id: string }>(entries: Entry<T>[]) =>
Object.fromEntries(entries.map(({ data }) => [data.id, data]));
const [
phaseEntries,
workerEntries,
treeEntries,
routeEntries,
providerEntries,
effortEntries,
skillFileEntries,
workflowEntries,
commonSkillEntries,
promptEntries,
installEntries,
] = await Promise.all([
getCollection('phases'),
getCollection('workers'),
getCollection('trees'),
getCollection('routes'),
getCollection('providers'),
getCollection('efforts'),
getCollection('skillFiles'),
getCollection('skillWorkflow'),
getCollection('commonSkills'),
getCollection('handsOnPrompts'),
getCollection('skillInstallPrompts'),
]);
const phases = toRecord(phaseEntries);
const workers = toRecord(workerEntries);
const trees = toRecord(treeEntries);
const routes = toRecord(routeEntries);
const providers = toRecord(providerEntries);
const efforts = toRecord(effortEntries);
const skillFiles = toRecord(skillFileEntries);
const skillWorkflow = toRecord(workflowEntries);
const commonSkills = toRecord(commonSkillEntries);
const sortedCommonSkills = Object.values(commonSkills).sort((a, b) =>
a.number.localeCompare(b.number),
);
const handsOn = promptEntries.find(({ data }) => data.id === 'tiny-tasks')?.data;
const install = installEntries.find(({ data }) => data.id === 'install')?.data;
if (!handsOn || !install) throw new Error('full-guide content collections are incomplete');
// Selector chrome is page-specific, so it remains an inline bilingual constant.
const labels = {
context: { en: 'context: isolated', pt: 'contexto: isolado' },
owner: { en: 'OWNER', pt: 'RESPONSÁVEL' },
reasoningLoad: { en: 'REASONING LOAD', pt: 'CARGA DE RACIOCÍNIO' },
officialSource: { en: 'OFFICIAL SOURCE ↗', pt: 'FONTE OFICIAL ↗' },
skillFileHint: {
en: 'select another file to explore',
pt: 'clique em outro arquivo para explorar',
},
workflow: {
question: { en: 'QUESTION', pt: 'PERGUNTA' },
action: { en: 'ACTION', pt: 'AÇÃO' },
artifact: { en: 'ARTIFACT', pt: 'ARTEFATO' },
proof: { en: 'PROOF', pt: 'PROVA' },
},
commonSkill: {
whenToUse: { en: 'WHEN TO USE', pt: 'QUANDO USAR' },
example: { en: 'EXAMPLE', pt: 'EXEMPLO' },
watchOut: { en: 'WATCH OUT', pt: 'CUIDADO' },
source: { en: 'GITHUB SOURCE ↗', pt: 'FONTE NO GITHUB ↗' },
},
};
const builderSteps: Record<
string,
{ title: { en: string; pt: string }; tagline: { en: string; pt: string } }
> = {
observe: {
title: { en: 'Observe', pt: 'Observar' },
tagline: { en: 'find repeated friction', pt: 'encontre atrito repetido' },
},
trigger: {
title: { en: 'Define trigger', pt: 'Definir gatilho' },
tagline: { en: 'route precisely', pt: 'roteie com precisão' },
},
scaffold: {
title: { en: 'Choose anatomy', pt: 'Escolher anatomia' },
tagline: { en: 'only needed files', pt: 'apenas arquivos necessários' },
},
write: {
title: { en: 'Write guidance', pt: 'Escrever orientação' },
tagline: { en: 'decisions, not trivia', pt: 'decisões, não trivialidades' },
},
validate: {
title: { en: 'Validate', pt: 'Validar' },
tagline: { en: 'test real behavior', pt: 'teste comportamento real' },
},
};
const selectorData = {
phases,
workers,
trees,
routes,
providers,
efforts,
skillFiles,
skillWorkflow,
commonSkills,
labels,
};
const workerCards = [
{
id: 'ui',
label: 'UI',
strong: { en: 'Component and visual states', pt: 'Componentes e estados visuais' },
code: 'agent/ui',
},
{
id: 'tests',
label: 'TEST',
strong: { en: 'Acceptance cases', pt: 'Casos de aceitação' },
code: 'agent/tests',
},
{
id: 'docs',
label: 'DOCS',
strong: { en: 'Guide and examples', pt: 'Guia e exemplos' },
code: 'agent/docs',
},
];
const treeBranches = [
{
id: 'ui',
label: { en: 'UI AGENT', pt: 'AGENTE DE UI' },
strong: 'agent/ui',
small: { en: '3 files · working', pt: '3 arquivos · trabalhando' },
tone: 'ui',
},
{
id: 'tests',
label: { en: 'TEST AGENT', pt: 'AGENTE DE TESTES' },
strong: 'agent/tests',
small: { en: '8 checks · ready', pt: '8 verificações · pronto' },
tone: 'tests',
},
{
id: 'docs',
label: { en: 'DOCS AGENT', pt: 'AGENTE DE DOCS' },
strong: 'agent/docs',
small: { en: '2 pages · review', pt: '2 páginas · revisão' },
tone: 'docs',
},
];
const base = import.meta.env.BASE_URL;
---
<BaseLayout
title="AI For Dummies — Field Guide"
description="AI For Dummies: a field guide to skills, models, subagents, and worktrees."
>
<ReadingProgress />
<main id="full-guide">
<header class="topbar">
<a class="brand" href="#top"><span class="mark">A</span> field guide</a>
<nav class="chapter-links" aria-label="Chapter sections">
<a href="#fleet"
><span data-language-content="en">01 fleet</span><span data-language-content="pt" hidden
>01 frota</span
></a
><a href="#worktrees"
><span data-language-content="en">02 worktrees</span><span
data-language-content="pt"
hidden>02 worktrees</span
></a
><a href="#models"
><span data-language-content="en">03 models</span><span data-language-content="pt" hidden
>03 modelos</span
></a
><a href="#skills"
><span data-language-content="en">04 skills</span><span data-language-content="pt" hidden
>04 skills</span
></a
><a href="#create-skill"
><span data-language-content="en">05 create</span><span data-language-content="pt" hidden
>05 criar</span
></a
><a href="#field-kit"
><span data-language-content="en">06 field kit</span><span
data-language-content="pt"
hidden>06 kit de campo</span
></a
><a href="#hands-on"
><span data-language-content="en">07 hands-on</span><span
data-language-content="pt"
hidden>07 prática</span
></a
><a href="#verification">08 verify</a>
</nav>
<div class="topbar-tools">
<a class="skills-review-link" href={`${base}skills-review/`}>review submissions </a
><LanguageToggle /><span class="edition"
><span data-language-content="en">AI ENGINEERING <i></i> 01 / 2026</span><span
data-language-content="pt"
hidden>ENGENHARIA DE IA <i></i> 01 / 2026</span
></span
>
</div>
</header>
<section class="hero" id="top" data-language-content="en">
<div>
<p class="eyebrow">
<span data-language-content="en">A presentation for humans who ship</span><span
data-language-content="pt"
hidden>Uma apresentação para quem entrega software</span
>
</p><h1>
AI for<br /><em>dummies.</em>
</h1><p class="lede">
<span data-language-content="en"
>You do not need an army of models. You need a system: one mind to frame the work,
several hands to execute it, and a clean boundary between every task.</span
>
<span data-language-content="pt" hidden
>Você não precisa de um exército de modelos. Precisa de um sistema: uma mente para
enquadrar o trabalho, várias mãos para executá-lo e uma fronteira clara entre cada
tarefa.</span
>
</p>
</div><aside class="hero-index">
<span
><span data-language-content="en">FIELD NOTE / 001</span><span
data-language-content="pt"
hidden>NOTA DE CAMPO / 001</span
></span
><strong
><span data-language-content="en">Ship the<br /><em>system.</em></span><span
data-language-content="pt"
hidden>Entregue o<br /><em>sistema.</em></span
></strong
><small
><span data-language-content="en">Skills · agents · worktrees · proof</span><span
data-language-content="pt"
hidden>Skills · agentes · worktrees · evidências</span
></small
>
</aside>
</section>
<section class="hero" id="top-pt" data-language-content="pt" hidden>
<div>
<p class="eyebrow">Uma apresentação para quem entrega software</p><h1>
AI for<br /><em>dummies.</em>
</h1><p class="lede">
Você não precisa de um exército de modelos. Precisa de um sistema: uma mente para
enquadrar o trabalho, várias mãos para executá-lo e uma fronteira clara entre cada tarefa.
</p>
</div><aside class="hero-index">
<span>NOTA DE CAMPO / 001</span><strong>Entregue o<br /><em>sistema.</em></strong><small
>Skills · agentes · worktrees · evidências</small
>
</aside>
</section>
<section class="hero-stats" aria-label="Chapter summary" data-language-content="en">
<div>
<strong>01</strong><span
><span data-language-content="en">strong model<br />for ambiguity</span><span
data-language-content="pt"
hidden>modelo forte<br />para ambiguidade</span
></span
>
</div><div>
<strong>03</strong><span
><span data-language-content="en">bounded workers<br />in parallel</span><span
data-language-content="pt"
hidden>workers delimitados<br />em paralelo</span
></span
>
</div><div>
<strong></strong><span
><span data-language-content="en">iterations<br />with evidence</span><span
data-language-content="pt"
hidden>iterações<br />com evidências</span
></span
>
</div><p>
<span data-language-content="en">Read this as a route map, not a prompt recipe.</span><span
data-language-content="pt"
hidden>Leia isto como um mapa de rota, não como uma receita de prompt.</span
>
</p>
</section>
<section class="hero-stats" aria-label="Resumo dos capítulos" data-language-content="pt" hidden>
<div><strong>01</strong><span>modelo forte<br />para ambiguidade</span></div><div>
<strong>03</strong><span>workers delimitados<br />em paralelo</span>
</div><div><strong></strong><span>iterações<br />com evidências</span></div><p>
Leia isto como um mapa de rota, não como uma receita de prompt.
</p>
</section>
<section class="thesis" data-language-content="en">
<div>
<span
><span data-language-content="en">RULE ZERO</span><span data-language-content="pt" hidden
>REGRA ZERO</span
></span
><strong
><span data-language-content="en"
>Strong model for ambiguity.<br />Light model for bounded work.</span
><span data-language-content="pt" hidden
>Modelo forte para ambiguidade.<br />Modelo leve para trabalho delimitado.</span
></strong
>
</div><div class="signal" aria-hidden="true">
<b>THINK</b><i></i><i></i><i></i><b>MAKE</b>
</div>
</section>
<section class="thesis" data-language-content="pt" hidden>
<div>
<span>REGRA ZERO</span><strong
>Modelo forte para ambiguidade.<br />Modelo leve para trabalho delimitado.</strong
>
</div><div class="signal" aria-hidden="true">
<b>THINK</b><i></i><i></i><i></i><b>MAKE</b>
</div>
</section>
<section class="fleet" id="fleet">
<div class="section-label">
<span
><span data-language-content="en">A small fleet</span><span
data-language-content="pt"
hidden>Uma pequena frota</span
></span
><span
><span data-language-content="en">coordination before parallelism</span><span
data-language-content="pt"
hidden>coordenação antes do paralelismo</span
></span
>
</div><FleetDiagram
orchestrator={{
eyebrow: { en: 'ORCHESTRATOR', pt: 'ORQUESTRADOR' },
title: {
en: 'Decides what<br />needs to happen.',
pt: 'Decide o que<br />precisa acontecer.',
},
code: 'Opus / reasoning',
}}
workers={workerCards}
/><div class="worker-detail" id="worker-detail" aria-live="polite">
<span>{workers.ui.en[0]}</span><strong>{workers.ui.en[1]}</strong><small
>{workers.ui.en[2]}</small
>
</div><p class="caption">
<span data-language-content="en"
>The orchestrator preserves intent, writes small contracts, and gathers results that can
be verified. It does not need to type every line.</span
><span data-language-content="pt" hidden
>O orquestrador preserva a intenção, escreve pequenos contratos e reúne resultados
verificáveis. Ele não precisa digitar cada linha.</span
>
</p>
</section>
<section class="failure-map">
<div class="section-label">
<span
><span data-language-content="en">Why the boundary matters</span><span
data-language-content="pt"
hidden>Por que a fronteira importa</span
></span
><span
><span data-language-content="en">one vague task / three predictable failures</span><span
data-language-content="pt"
hidden>uma tarefa vaga / três falhas previsíveis</span
></span
>
</div><div class="failure-grid">
<article>
<span>01</span><strong
><span data-language-content="en">Context soup</span><span
data-language-content="pt"
hidden>Sopa de contexto</span
></strong
><p>
<span data-language-content="en"
>Every worker reads everything. Nobody knows which facts are load-bearing.</span
><span data-language-content="pt" hidden
>Cada worker tudo. Ninguém sabe quais fatos são essenciais.</span
>
</p>
</article><article>
<span>02</span><strong
><span data-language-content="en">Branch collision</span><span
data-language-content="pt"
hidden>Colisão de branches</span
></strong
><p>
<span data-language-content="en"
>Two agents touch the same checkout. The fastest path becomes conflict resolution.</span
><span data-language-content="pt" hidden
>Dois agentes usam o mesmo checkout. O caminho mais rápido vira resolução de
conflitos.</span
>
</p>
</article><article>
<span>03</span><strong
><span data-language-content="en">Confident drift</span><span
data-language-content="pt"
hidden>Desvio confiante</span
></strong
><p>
<span data-language-content="en"
>The diff is polished, but no one checks whether it solved the original problem.</span
><span data-language-content="pt" hidden
>O diff parece ótimo, mas ninguém verifica se resolveu o problema original.</span
>
</p>
</article>
</div>
</section>
<section class="workflow" aria-labelledby="workflow-title">
<div class="copy">
<p class="eyebrow">
<span data-language-content="en">The subagent loop</span><span
data-language-content="pt"
hidden>O ciclo de subagentes</span
>
</p><h2 id="workflow-title">
<span data-language-content="en">Click a phase.<br /><em>See the handoff.</em></span><span
data-language-content="pt"
hidden>Clique em uma fase.<br /><em>Veja a passagem.</em></span
>
</h2><!-- The legacy PT render paints this paragraph twice; preserve that output. -->
<p>
<span data-language-content="en"
>Delegation means moving one bounded task into a smaller contextnot giving away
responsibility.</span
><span data-language-content="pt" hidden
>Delegar é mover uma tarefa delimitada para um contexto menor não abrir mão da
responsabilidade.</span
>
</p>
</div><PhasePanel
phases={[
{
id: 'plan',
label: 'PLAN',
number: '01',
title: phases.plan.title.en,
body: phases.plan.copy.en,
meta: { deliverable: phases.plan.model.en, gate: labels.context.en },
evidence: phases.plan.code.en,
},
{
id: 'build',
label: 'BUILD',
number: '02',
title: phases.build.title.en,
body: phases.build.copy.en,
meta: { deliverable: phases.build.model.en, gate: labels.context.en },
evidence: phases.build.code.en,
},
{
id: 'review',
label: 'REVIEW',
number: '03',
title: phases.review.title.en,
body: phases.review.copy.en,
meta: { deliverable: phases.review.model.en, gate: labels.context.en },
evidence: phases.review.code.en,
},
]}
/>
</section>
<section class="handoff">
<div class="section-label">
<span
><span data-language-content="en">What crosses contexts</span><span
data-language-content="pt"
hidden>O que atravessa contextos</span
></span
><span
><span data-language-content="en">brief diff evidence</span><span
data-language-content="pt"
hidden>brief diff evidência</span
></span
>
</div><HandoffTable
columns={[
{ en: 'Package', pt: 'Pacote' },
{ en: 'Contains', pt: 'Contém' },
{ en: 'Why it matters', pt: 'Por que importa' },
]}
rows={[
{
package: 'Brief',
contains: 'goal, files, boundaries',
why: 'stops the worker inventing the problem',
},
{
package: 'Worktree',
contains: 'branch and isolated checkout',
why: 'parallel edits do not collide',
},
{
package: 'Checks',
contains: 'tests, build, criteria',
why: 'turns “looks good” into evidence',
},
{
package: 'Diff',
contains: 'small, reviewable change',
why: 'integration and discard stay cheap',
},
]}
/>
</section>
<section class="worktrees" id="worktrees">
<div class="worktree-intro">
<p class="eyebrow">
<span data-language-content="en">Git worktrees</span><span
data-language-content="pt"
hidden>Git worktrees</span
>
</p><h2>
<span data-language-content="en">One branch<br />per <em>hand.</em></span><span
data-language-content="pt"
hidden>Uma branch<br />por <em>mão.</em></span
>
</h2><p>
<span data-language-content="en"
>A worktree is another directory linked to the same repository. Each agent gets its own
checkout and index; history remains shared.</span
><span data-language-content="pt" hidden
>Um worktree é outro diretório ligado ao mesmo repositório. Cada agente recebe seu
próprio checkout e índice; o histórico continua compartilhado.</span
>
</p><p class="interaction-hint">
<span data-language-content="en"
>Select a node to inspect its checkout, owner, and next action.</span
><span data-language-content="pt" hidden
>Selecione um para inspecionar checkout, responsável e próxima ação.</span
>
</p>
</div><div class="tree-lab">
<div class="tree-toolbar">
<span
><span data-language-content="en">repository topology</span><span
data-language-content="pt"
hidden>topologia do repositório</span
></span
><span class="tree-live"
><span data-language-content="en"><i></i> 4 checkouts</span><span
data-language-content="pt"
hidden><i></i> 4 checkouts</span
></span
>
</div><WorktreeMap
branches={treeBranches}
rootLabel={{ en: 'ROOT', pt: 'RAIZ' }}
rootSmall={{ en: '● clean', pt: '● limpo' }}
/><article class="tree-detail" id="tree-detail" aria-live="polite">
<div><span>{labels.owner.en}</span><strong>{trees.main.owner.en}</strong></div><div>
<span>CHECKOUT</span><strong>{trees.main.path}</strong>
</div><p>{trees.main.note.en}</p><code>{trees.main.command}</code>
</article>
</div>
</section>
<section class="routing">
<div>
<p class="eyebrow">
<span data-language-content="en">Model routing</span><span
data-language-content="pt"
hidden>Roteamento de modelos</span
>
</p><h2>
<span data-language-content="en"
>Do not pay for<br />reasoning where<br />you need <em>rhythm.</em></span
><span data-language-content="pt" hidden
>Não pague por<br />raciocínio onde precisa<br />de <em>ritmo.</em></span
>
</h2><p class="interaction-hint">
<span data-language-content="en">Choose a job to see why the model profile changes.</span
><span data-language-content="pt" hidden
>Escolha um trabalho para entender por que o perfil do modelo muda.</span
>
</p>
</div><div class="route-console">
<RouteTable
headWork={{ en: 'Work', pt: 'Trabalho' }}
headProfile={{ en: 'Profile', pt: 'Perfil' }}
headPromptShape={{ en: 'Prompt shape', pt: 'Formato do prompt' }}
routes={[
{
id: 'plan',
strong: { en: 'Plan', pt: 'Planejar' },
profile: 'strong / broad',
prompt: 'What changes? What can break?',
},
{
id: 'build',
strong: { en: 'Build', pt: 'Construir' },
profile: 'fast / focused',
prompt: 'Implement this slice. Run these checks.',
},
{
id: 'explore',
strong: { en: 'Explore', pt: 'Explorar' },
profile: 'read-only / light',
prompt: 'Find where this contract is used.',
},
{
id: 'review',
strong: { en: 'Review', pt: 'Revisar' },
profile: 'independent',
prompt: 'Does the diff satisfy the brief?',
},
]}
/><article class="route-detail" id="route-detail" aria-live="polite">
<div class="route-meter"><span style={`--score:${routes.plan.score}%`}></span></div><div>
<small>{labels.reasoningLoad.en} · {routes.plan.score}</small><strong
>{routes.plan.label.en}</strong
><p>{routes.plan.why.en}</p>
</div>
</article>
</div>
</section>
<section class="model-gearbox" id="models">
<div class="section-label">
<span
><span data-language-content="en">Model gearbox</span><span
data-language-content="pt"
hidden>Câmbio de modelos</span
></span
><span
><span data-language-content="en">capability tier × thinking effort</span><span
data-language-content="pt"
hidden>nível de capacidade × esforço de raciocínio</span
></span
>
</div>
<div class="gearbox-intro">
<div>
<p class="eyebrow">
<span data-language-content="en">Two separate knobs</span><span
data-language-content="pt"
hidden>Dois controles separados</span
>
</p>
<h2>
<span data-language-content="en"
>Choose the engine.<br />Then choose the <em>gear.</em></span
><span data-language-content="pt" hidden
>Escolha o motor.<br />Depois escolha a <em>marcha.</em></span
>
</h2>
</div>
<p>
<span data-language-content="en"
>A stronger model changes the capability ceiling. Higher reasoning effort gives that
model more room to work. Start with the lightest combination that passes your real
checks, then move one knob at a time.</span
><span data-language-content="pt" hidden
>Um modelo mais forte muda o teto de capacidade. Mais esforço de raciocínio mais
espaço para esse modelo trabalhar. Comece com a combinação mais leve que passa seus
checks e mova um controle por vez.</span
>
</p>
</div>
<div class="gearbox">
<div class="provider-tabs" role="tablist" aria-label="Model providers">
<button class="active" data-model-provider="openai" role="tab" aria-selected="true"
>OPENAI</button
><button data-model-provider="claude" role="tab" aria-selected="false">CLAUDE</button
><button data-model-provider="gemini" role="tab" aria-selected="false">GEMINI</button>
</div><article class="provider-detail" id="provider-detail" aria-live="polite">
<header>
<span>{providers.openai.label}</span><a
href={providers.openai.source}
target="_blank"
rel="noopener">{labels.officialSource.en}</a
>
</header><h3>{providers.openai.title.en}</h3><p>{providers.openai.copy.en}</p>
</article><div class="effort-rail" role="tablist" aria-label="Reasoning effort">
<span
><span data-language-content="en">REASONING / THINKING</span><span
data-language-content="pt"
hidden>RACIOCÍNIO / PENSAMENTO</span
></span
>
<button data-effort="low" role="tab" aria-selected="false"
><b
><span data-language-content="en">LOW</span><span data-language-content="pt" hidden
>BAIXO</span
></b
><small
><span data-language-content="en">bounded + fast</span><span
data-language-content="pt"
hidden>delimitado + rápido</span
></small
></button
><button class="active" data-effort="medium" role="tab" aria-selected="true"
><b
><span data-language-content="en">MEDIUM</span><span data-language-content="pt" hidden
>MÉDIO</span
></b
><small
><span data-language-content="en">default start</span><span
data-language-content="pt"
hidden>ponto inicial</span
></small
></button
><button data-effort="high" role="tab" aria-selected="false"
><b
><span data-language-content="en">HIGH</span><span data-language-content="pt" hidden
>ALTO</span
></b
><small
><span data-language-content="en">complex + costly</span><span
data-language-content="pt"
hidden>complexo + custoso</span
></small
></button
>
</div><article class="effort-detail" id="effort-detail" aria-live="polite">
<span>{efforts.medium.en[0]}</span><p>{efforts.medium.en[1]}</p><code
>{providers.openai.config}</code
>
</article>
</div>
<div class="gearbox-rule">
<span
><span data-language-content="en">ROUTING RULE</span><span
data-language-content="pt"
hidden>REGRA DE ROTEAMENTO</span
></span
>
<strong
><span data-language-content="en"
>Use strong models for ambiguity and judgment. Use lighter models for bounded execution.
Raise effort only when evaluation shows a gain.</span
><span data-language-content="pt" hidden
>Use modelos fortes para ambiguidade e julgamento. Use modelos leves para execução
delimitada. Aumente o esforço apenas quando a avaliação mostrar ganho.</span
></strong
>
</div>
</section>
<section class="skills" id="skills">
<div>
<p class="eyebrow">
{
/* Under Portuguese the legacy page paints the long skill sentence
here, not "Skills": its `.skills > div:first-child > p` selector
also matches this eyebrow and overwrites it. Reproduced on
purpose -- see .agents/rules/content-i18n.md. */
}
<span data-language-content="en">Skills</span><span data-language-content="pt" hidden
>Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências,
scripts e assets. Não é memória mágica e não substitui critérios de aceitação.</span
>
</p><h2>
<span data-language-content="en">Write the right way<br /><em>once.</em></span><span
data-language-content="pt"
hidden>Escreva do jeito certo<br /><em>uma vez.</em></span
>
</h2><p>
<span data-language-content="en"
>A skill is a reusable procedure. It can carry instructions, references, scripts, and
assets. It is not magical memory, and it does not replace acceptance criteria.</span
>
<span data-language-content="pt" hidden
>Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências,
scripts e assets. Não é memória mágica e não substitui critérios de aceitação.</span
>
</p><div class="skill-principles">
<span data-language-content="en">01 / trigger clearly</span><span
data-language-content="pt"
hidden>01 / defina o gatilho</span
>
<span data-language-content="en">02 / load detail on demand</span><span
data-language-content="pt"
hidden>02 / carregue detalhes sob demanda</span
>
<span data-language-content="en">03 / return evidence</span><span
data-language-content="pt"
hidden>03 / devolva evidências</span
>
</div>
</div><div class="skill-explorer">
<SkillPackage
packageLabel={{ en: 'SKILL PACKAGE', pt: 'PACOTE DE SKILL' }}
files={[
{ id: 'skill', path: 'SKILL.md', small: 'procedure and limits' },
{ id: 'references', path: 'references/', small: 'facts to consult' },
{ id: 'scripts', path: 'scripts/', small: 'repeatable checks' },
{ id: 'assets', path: 'assets/', small: 'templates and examples' },
]}
/><article class="skill-detail" id="skill-detail" aria-live="polite">
<span>{skillFiles.skill.icon}</span><div>
<strong>{skillFiles.skill.title}</strong><p>{skillFiles.skill.en}</p><small
>{labels.skillFileHint.en}</small
>
</div>
</article>
</div><pre><code>name: review-ui · check focus, mobile, reduced motion · run verification · return evidence</code></pre>
</section>
<section class="skill-builder" id="create-skill">
<div class="section-label">
<span
><span data-language-content="en">Create a skill</span><span
data-language-content="pt"
hidden>Criar uma skill</span
></span
><span
><span data-language-content="en">repeatable pain reusable judgment</span><span
data-language-content="pt"
hidden>atrito repetido julgamento reutilizável</span
></span
>
</div><div class="builder-intro">
<div>
<p class="eyebrow">
<span data-language-content="en">The skill forge</span><span
data-language-content="pt"
hidden>A forja de skills</span
>
</p><h2>
<span data-language-content="en"
>Teach the decision.<br />Keep the context <em>light.</em></span
><span data-language-content="pt" hidden
>Ensine a decisão.<br />Mantenha o contexto <em>leve.</em></span
>
</h2>
</div><p>
<span data-language-content="en"
>Do not package everything you know. Capture the non-obvious choices that repeatedly
improve an outcome, then prove the skill changes behavior.</span
><span data-language-content="pt" hidden
>Não empacote tudo o que você sabe. Capture as escolhas não óbvias que melhoram
resultados repetidamente e prove que a skill muda o comportamento.</span
>
</p>
</div><div class="builder-workbench">
<nav class="builder-steps" role="tablist" aria-label="Skill creation workflow">
{
['observe', 'trigger', 'scaffold', 'write', 'validate'].map((id) => {
const step = skillWorkflow[id];
return (
<button
class:list={{ active: step.id === 'observe' }}
data-skill-step={step.id}
role="tab"
aria-selected={step.id === 'observe'}
>
<>
<b>{step.number}</b>
<>
<span>
<>
<span data-language-content="en">{builderSteps[step.id].title.en}</span>
<span data-language-content="pt" hidden>
{builderSteps[step.id].title.pt}
</span>
</>
</span>
<small>
<>
<span data-language-content="en">{builderSteps[step.id].tagline.en}</span>
<span data-language-content="pt" hidden>
{builderSteps[step.id].tagline.pt}
</span>
</>
</small>
</>
</>
</button>
);
})
}
</nav><article class="builder-detail" id="builder-detail" aria-live="polite">
<header>
<span>{skillWorkflow.observe.number}</span><small>{labels.workflow.question.en}</small>
</header><h3>{skillWorkflow.observe.title.en}</h3><blockquote>
{skillWorkflow.observe.question.en}
</blockquote><div class="builder-action">
<span>{labels.workflow.action.en}</span><p>{skillWorkflow.observe.action.en}</p>
</div><footer>
<div>
<span>{labels.workflow.artifact.en}</span><strong
>{skillWorkflow.observe.output.en}</strong
>
</div><div>
<span>{labels.workflow.proof.en}</span><strong
>{skillWorkflow.observe.proof.en}</strong
>
</div>
</footer>
</article><aside class="builder-artifact">
<div class="artifact-head">
<span
><span data-language-content="en">OUTPUT / SKILL PACKAGE</span><span
data-language-content="pt"
hidden>SAÍDA / PACOTE DE SKILL</span
></span
><i></i>
</div><pre
aria-label="Example skill structure"><code>review-ui/<br /> SKILL.md<br /> agents/<br /> openai.yaml<br /> references/<br /> accessibility.md<br /> scripts/<br /> verify.mjs</code></pre><div
class="artifact-command"
>
<span
><span data-language-content="en">VALIDATE</span><span
data-language-content="pt"
hidden>VALIDAR</span
></span
><code>quick_validate.py ./review-ui</code>
</div>
</aside>
</div><div class="builder-loop">
<span
><span data-language-content="en">AFTER REAL USE</span><span
data-language-content="pt"
hidden>APÓS USO REAL</span
></span
><div data-language-content="en">
<b>observe failure</b><i></i><b>sharpen one rule</b><i></i><b>retest behavior</b><i></i
><b>keep it narrow</b>
</div><div data-language-content="pt" hidden>
<b>observar falha</b><i></i><b>refinar uma regra</b><i></i><b>retestar comportamento</b
><i></i><b>manter estreita</b>
</div>
</div>
</section>
<section class="skill-catalog" id="field-kit">
<div class="section-label">
<span
><span data-language-content="en">Common skills</span><span
data-language-content="pt"
hidden>Skills comuns</span
></span
><span
><span data-language-content="en">choose behavior before model</span><span
data-language-content="pt"
hidden>escolha o comportamento antes do modelo</span
></span
>
</div><div class="catalog-intro">
<div>
<p class="eyebrow">
<span data-language-content="en">The field kit</span><span
data-language-content="pt"
hidden>O kit de campo</span
>
</p>
<h2>
<span data-language-content="en"
>Different jobs.<br />Different <em>instincts.</em></span
><span data-language-content="pt" hidden
>Trabalhos diferentes.<br />Instintos <em>diferentes.</em></span
>
</h2>
</div>
<p>
<span data-language-content="en"
>A skill changes how an agent approaches work. Some shape communication. Others enforce
research, debugging, review, or completion discipline. Select one to inspect its
operating rule and verified source.</span
><span data-language-content="pt" hidden
>Uma skill muda como o agente aborda o trabalho. Algumas moldam a comunicação. Outras
impõem pesquisa, diagnóstico, revisão ou disciplina de conclusão. Selecione uma para
inspecionar sua regra operacional.</span
>
</p>
</div><div class="skill-deck">
<div class="skill-index" role="tablist" aria-label="Common agent skills">
{
/* getCollection's order is not the deck's order. Sort by the
card number so the tabs stay 01..07 as the legacy page has
them, instead of shifting between builds. */
sortedCommonSkills.map((skill) => (
<button
class:list={{ active: skill.id === 'ponytail' }}
data-common-skill={skill.id}
role="tab"
aria-selected={skill.id === 'ponytail'}
>
<>
{/* The button's two lines are `label` / `tagline`, not the
panel's `kind` / `use`. See src/content/config.ts. */}
<span>
<span data-language-content="en">{skill.label.en}</span>
<span data-language-content="pt" hidden>
{skill.label.pt}
</span>
</span>
<strong>{skill.title}</strong>
<small>
<span data-language-content="en">{skill.tagline.en}</span>
<span data-language-content="pt" hidden>
{skill.tagline.pt}
</span>
</small>
</>
</button>
))
}
</div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite">
<header>
<span>{commonSkills.ponytail.number}</span><small>{commonSkills.ponytail.kind.en}</small
>
</header><h3>{commonSkills.ponytail.title}</h3><blockquote>
{commonSkills.ponytail.rule.en}
</blockquote><div class="common-skill-notes">
<div>
<span>{labels.commonSkill.whenToUse.en}</span><p>{commonSkills.ponytail.use.en}</p>
</div><div>
<span>{labels.commonSkill.example.en}</span><p>{commonSkills.ponytail.example.en}</p>
</div><div>
<span>{labels.commonSkill.watchOut.en}</span><p>{commonSkills.ponytail.caution.en}</p>
</div>
</div><a
class="skill-source"
href={commonSkills.ponytail.source}
target="_blank"
rel="noopener">{labels.commonSkill.source.en}</a
>
</article>
</div><div class="skill-loadout">
<span data-language-content="en">ONE PRACTICAL LOADOUT</span><span
data-language-content="pt"
hidden>UM LOADOUT PRÁTICO</span
>
<div data-language-content="en">
<b>PLAN</b> unlazy <i></i>
<b>BUILD</b> ponytail-lite <i></i>
<b>DEBUG</b> diagnosing-bugs <i></i>
<b>REPORT</b> caveman
</div>
<div data-language-content="pt" hidden>
<b>PLANEJAR</b> unlazy <i></i>
<b>CONSTRUIR</b> ponytail-lite <i></i>
<b>DIAGNOSTICAR</b> diagnosing-bugs <i></i>
<b>REPORTAR</b> caveman
</div>
</div><article class="install-skills">
<header>
<div>
<span
><span data-language-content="en">INSTALL PACK</span><span
data-language-content="pt"
hidden>PACOTE DE INSTALAÇÃO</span
></span
><strong
><span data-language-content="en"
>Ask your coding agent to verify, install, and validate the skills.</span
><span data-language-content="pt" hidden
>Peça ao seu agente para verificar, instalar e validar as skills.</span
></strong
>
</div><CopyPrompt target="prompt-install-skills" />
</header><pre><code id="prompt-install-skills"><span data-language-content="en">{install.en}</span><span data-language-content="pt" hidden>{install.pt}</span></code></pre><footer
>
<span data-language-content="en"
>Review every source before installation. Existing local skills must be preserved.</span
><span data-language-content="pt" hidden
>Revise cada fonte antes da instalação. Skills locais existentes devem ser preservadas.</span
>
</footer>
</article>
</section>
<section class="hands-on" id="hands-on">
<div class="section-label">
<span
><span data-language-content="en">Hands-on</span><span data-language-content="pt" hidden
>Prática</span
></span
><span
><span data-language-content="en">10 minutes / one missing feature</span><span
data-language-content="pt"
hidden>10 minutos / uma feature ausente</span
></span
>
</div><div class="hands-intro">
<div>
<p class="eyebrow">
<span data-language-content="en">Tiny Tasks lab</span><span
data-language-content="pt"
hidden>Laboratório Tiny Tasks</span
>
</p><h2>
<span data-language-content="en">Same task.<br />Better <em>operating system.</em></span
><span data-language-content="pt" hidden
>Mesma tarefa.<br />Melhor <em>sistema operacional.</em></span
>
</h2>
</div><div>
<p data-language-content="en">
Start with a deliberately incomplete static task board. Run one prompt as written,
reset, then run the skill-enabled version. Compare diff size, verification evidence, and
unnecessary complexity.
</p><p data-language-content="pt" hidden>
Comece com um quadro estático propositalmente incompleto. Execute um prompt, restaure e
execute a versão com skills. Compare tamanho do diff, evidências e complexidade
desnecessária.
</p><div class="starter-links">
<div class="starter-link-group">
<a href={`${base}hands-on/starter/`} class="starter-link"
><span data-language-content="en">Open the starter </span><span
data-language-content="pt"
hidden>Abrir o projeto inicial </span
></a
><a
href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/pages/hands-on/starter"
class="starter-link starter-link-source"
><span data-language-content="en">Clone from Gitea </span><span
data-language-content="pt"
hidden>Abrir o projeto inicial </span
></a
>
</div><div class="starter-link-group">
<a href={`${base}hands-on/rules/`} class="starter-link"
><span data-language-content="en">Open the rules lab </span><span
data-language-content="pt"
hidden>Abrir o projeto inicial </span
></a
><a
href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/pages/hands-on/rules"
class="starter-link starter-link-source"
><span data-language-content="en">Clone from Gitea </span><span
data-language-content="pt"
hidden>Abrir o projeto inicial </span
></a
>
</div>
</div>
</div>
</div><div class="exercise-brief">
<span
><span data-language-content="en">THE MISSING FEATURE</span><span
data-language-content="pt"
hidden>A FEATURE AUSENTE</span
></span
><strong
><span data-language-content="en"
>Add All / Open / Done filters that survive reload and browser navigation.</span
><span data-language-content="pt" hidden
>Adicione filtros Todos / Abertos / Concluídos que sobrevivem reload e navegação.</span
></strong
><div>
<span data-language-content="en"
><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDENCIES</b> none <b>FILES</b> 3</span
><span data-language-content="pt" hidden
><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDÊNCIAS</b> nenhuma <b>ARQUIVOS</b> 3</span
>
</div>
</div><div class="prompt-compare">
<article class="prompt-card">
<header>
<div>
<span>RUN A</span><strong
><span data-language-content="en">Good prompt</span><span
data-language-content="pt"
hidden>Bom prompt</span
></strong
>
</div><CopyPrompt target="prompt-basic" />
</header><pre><code id="prompt-basic"><span data-language-content="en">{handsOn.en.basic}</span><span data-language-content="pt" hidden>{handsOn.pt.basic}</span></code></pre><footer
>
<span data-language-content="en"
>Clear context · constraints · acceptance · evidence</span
><span data-language-content="pt" hidden
>Contexto claro · restrições · aceitação · evidência</span
>
</footer>
</article><article class="prompt-card enhanced">
<header>
<div>
<span>RUN B</span><strong
><span data-language-content="en">Good prompt + skills</span><span
data-language-content="pt"
hidden>Bom prompt + skills</span
></strong
>
</div><CopyPrompt target="prompt-skills" />
</header><pre><code id="prompt-skills"><span data-language-content="en">{handsOn.en.skills}</span><span data-language-content="pt" hidden>{handsOn.pt.skills}</span></code></pre><footer
>
<span data-language-content="en"
>Same contract · explicit working methods · stronger proof</span
><span data-language-content="pt" hidden
>Mesmo contrato · métodos explícitos · prova mais forte</span
>
</footer>
</article>
</div><div class="comparison-strip">
<span
><span data-language-content="en">COMPARE THE RUNS</span><span
data-language-content="pt"
hidden>COMPARE AS EXECUÇÕES</span
></span
><div>
<b>01</b>
<span data-language-content="en">Files changed</span><span
data-language-content="pt"
hidden>Arquivos alterados</span
>
</div><div>
<b>02</b>
<span data-language-content="en">New dependencies</span><span
data-language-content="pt"
hidden>Novas dependências</span
>
</div><div>
<b>03</b>
<span data-language-content="en">Checks actually run</span><span
data-language-content="pt"
hidden>Checks executados</span
>
</div><div>
<b>04</b>
<span data-language-content="en">Evidence returned</span><span
data-language-content="pt"
hidden>Evidências retornadas</span
>
</div>
</div><p class="copy-status" id="copy-status" role="status" aria-live="polite"></p>
</section>
<aside class="rule">
<span
><span data-language-content="en">THE HUMAN JOB</span><span
data-language-content="pt"
hidden>O PAPEL HUMANO</span
></span
><strong
><span data-language-content="en"
>The agent may be autonomous in execution. Intent, boundaries, and evidence remain yours.</span
><span data-language-content="pt" hidden
>O agente pode ser autônomo na execução. Intenção, limites e evidências continuam sendo
seus.</span
></strong
>
</aside>
<aside class="callout">
<span
><span data-language-content="en">START HERE</span><span data-language-content="pt" hidden
>COMECE AQUI</span
></span
><strong
><span data-language-content="en"
>Begin with one agent and one skill. Add parallelism only when the tasks are truly
independent.</span
><span data-language-content="pt" hidden
>Comece com um agente e uma skill. Adicione paralelismo apenas quando as tarefas forem
realmente independentes.</span
></strong
>
</aside>
<section class="verification" id="verification">
<div class="section-label">
<span>Verification</span><span>run each gate separately</span>
</div><div class="verify-intro">
<div>
<p class="eyebrow">Checks become evidence</p><h2>
Three layers.<br />Run each one alone.
</h2>
</div><p>
Run a gate on its own line, print its exit code, attach the output. The result is the
deliverable.
</p>
</div><div class="verify-layers">
<article>
<span>01 · STATIC</span><h3>Lint and types</h3><p>
Format, lint, type-check. Fast and scoped to one file. Run on every save.
</p><code>pnpm lint; echo "lint=$?" pnpm typecheck; echo "typecheck=$?"</code>
</article><article>
<span>02 · BEHAVIOR</span><h3>Unit and contract</h3><p>
Tests that repeat. Run before claiming done.
</p><code>pnpm test; echo "test=$?" cd services/api && go test ./...</code>
</article><article>
<span>03 · INTEGRATION</span><h3>Real UI and API</h3><p>
Drive the actual UI, API, or browser. Slower and flakier only this catches mobile
overflow and a missing 404.
</p><code>pnpm check:ui; echo "ui=$?" TURBO_FORCE=true pnpm e2e</code>
</article>
</div><div class="verify-antipatterns">
<span>FOUR WAYS A GREEN REPORT IS FALSE</span><div class="ap-grid">
<article>
<b>1</b><div>
<strong>Pipe a gate</strong><p>
tail, grep, or head hide the real exit code a pipeline returns the last command's
status.
</p>
</div>
</article><article>
<b>2</b><div>
<strong>Swallow a rejection</strong><p>
A silent <code>{'.catch(() => {})'}</code> hides a panic, an upstream limit, or a partial
failure.
</p>
</div>
</article><article>
<b>3</b><div>
<strong>Trust the cache</strong><p>
Turbo caches results. A gate that "passes" may not have run use <code
>TURBO_FORCE=true</code
>.
</p>
</div>
</article><article>
<b>4</b><div>
<strong>Skip the third layer</strong><p>
Lint and unit can both be green while the page breaks on mobile and the API never
returns 404.
</p>
</div>
</article>
</div>
</div><article class="verify-cta">
<span>RUN IT YOURSELF · two labs, under 10 minutes each</span><div class="verify-cta-grid">
<a href={`${base}hands-on/starter/`} class="verify-card"
><strong>Path A · verification lab</strong><p>
Fill the four-row comparison strip on the starter. Run A naively, Run B with <code
>$gate-discipline</code
> and <code>$webapp-testing</code>.
</p><small>Open the starter </small><small class="verify-card-source"
>Clone <span>git.marcospaulo.dev.br/.../src/branch/pages/hands-on/starter</span
></small
></a
><a href={`${base}hands-on/rules/`} class="verify-card"
><strong>Path B · rules lab</strong><p>
Toggle every rule off, run the prompt. Toggle every rule on, run it again. Compare
diff size, gate invocations, and the names of checks the agent names back.
</p><small
><span data-language-content="en">Open the rules lab </span><span
data-language-content="pt"
hidden>Open the rules lab </span
></small
><small class="verify-card-source"
>Clone <span>git.marcospaulo.dev.br/.../src/branch/pages/hands-on/rules</span
></small
></a
>
</div>
</article>
</section>
<section class="sources">
<div class="section-label">
<span
><span data-language-content="en">Keep learning</span><span
data-language-content="pt"
hidden>Continue aprendendo</span
></span
><span
><span data-language-content="en">12 new readings + primary docs</span><span
data-language-content="pt"
hidden>12 novas leituras + documentação primária</span
></span
>
</div><p>
<span data-language-content="en"
>Go deeper with official documentation, production case studies, Medium, and practitioner
workflows. <a href={`${base}rules/`}>Rules and enforcement case study </a>
<a href={`${base}skills-review/`}>Skills review desk </a>
<a href={`${base}docs/references/README.md`}>Primary references </a>
<a href={`${base}docs/references/additional-reading.md`}>12-part reading path </a></span
>
<span data-language-content="pt" hidden
>Aprofunde com documentação oficial, casos de produção, Medium e fluxos de praticantes. <a
href={`${base}rules/`}>Estudo de caso sobre regras e enforcement </a
>
<a href={`${base}docs/references/README.md`}>Referências primárias </a>
<a href={`${base}docs/references/additional-reading.md`}>Trilha com 12 leituras </a
></span
>
</p>
</section>
<!-- Legacy full-guide/index.html closes with this section after `.sources`.
Task 15d dropped it, and nothing caught that: verify.mjs reads the
legacy file, so its chapter-route assertion kept passing. It has no
`translations.pt` entry, so it is English-only on the live site too. -->
<section class="chapter-route">
<div class="section-label">
<span>Navigate by idea</span><span>short chapters / one system</span>
</div>
<p>
Prefer a focused chapter? Start with the <a href={`${base}summary/`}>route map</a>, then
jump directly to <a href={`${base}models/`}>models</a>, <a href={`${base}agents/`}
>agents and worktrees</a
>, <a href={`${base}skills/`}>skill creation</a>, <a href={`${base}rules/`}>rules</a>, or
the <a href={`${base}skills-review/`}>skills review desk</a>.
</p>
</section>
</main>
<GuideSelector rootSelector="#full-guide" data={selectorData} />
</BaseLayout>
<style is:global>
/* Page-owned former responsive.css rules. The legacy file remains loaded only by
full-guide/index.html until task 20 removes that page. */
.topbar-tools {
display: flex;
align-items: center;
gap: 24px;
}
.skills-review-link {
color: var(--blue);
font: 700 var(--step-09) var(--font-mono);
letter-spacing: 0.06em;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
}
.skills-review-link:hover {
color: var(--accent);
}
.lang-switch {
display: flex;
align-items: center;
gap: 6px;
color: var(--muted);
font: 500 var(--step-00) var(--font-mono);
letter-spacing: 0.1em;
}
.lang-switch button {
padding: 0;
border: 0;
color: inherit;
background: transparent;
font: inherit;
cursor: pointer;
}
.lang-switch button.active {
color: var(--ink);
font-weight: 700;
}
.lang-switch button:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 4px;
}
@media (max-width: 800px) {
.topbar-tools {
margin-left: auto;
}
}
/* token-gap: preserve the legacy full-guide layout threshold; responsive.css is gone, so this rule is now the only definition of it */
@media (max-width: 600px) {
.topbar-tools .edition {
display: none;
}
}
/* Interactive operations map */
.interaction-hint {
margin-top: 24px !important;
padding-left: 18px;
border-left: 3px solid var(--gold);
font: 500 var(--step-0)/1.6 var(--font-mono) !important;
color: var(--muted) !important;
}
button {
font-family: inherit;
}
.worker-card {
display: grid;
align-content: space-between;
gap: 20px;
min-height: 180px;
padding: 22px;
border: 0;
color: var(--paper);
background: var(--ink);
text-align: left;
cursor: pointer;
transition:
background 0.2s ease,
transform 0.2s ease;
}
.worker-card span {
color: var(--guide-toolbar-text);
font: 500 var(--step-00) var(--font-mono);
letter-spacing: 0.1em;
}
.worker-card strong {
font-size: var(--step-16);
line-height: 1.2;
}
.worker-card code {
color: var(--gold);
font: var(--step-0) var(--font-mono);
}
.worker-card:hover,
.worker-card.active {
background: var(--guide-panel-blue);
}
.worker-card.active {
box-shadow: inset 0 -4px 0 var(--gold);
}
.worker-card:active {
transform: translateY(2px);
}
.worker-detail {
display: grid;
grid-template-columns: 0.55fr 1.1fr 1.2fr;
gap: 1px;
margin-top: 1px;
background: var(--line);
}
.worker-detail > * {
margin: 0;
padding: 16px 20px;
background: var(--guide-worker-detail-surface);
}
.worker-detail span,
.worker-detail small {
font: 500 var(--step-00)/1.5 var(--font-mono);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.worker-detail span {
color: var(--accent);
}
.worker-detail strong {
font-size: var(--step-13);
}
.worker-detail small {
color: var(--muted);
text-transform: none;
}
.tree-lab {
min-width: 0;
border: 1px solid var(--guide-tree-rule);
background: var(--guide-code-surface);
box-shadow: 18px 18px 0 var(--guide-tree-shadow);
}
.tree-toolbar {
display: flex;
justify-content: space-between;
padding: 14px 18px;
border-bottom: 1px solid var(--guide-tree-rule);
color: var(--guide-toolbar-text);
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.1em;
text-transform: uppercase;
}
.tree-live {
display: flex;
align-items: center;
gap: 8px;
}
.tree-live i {
display: block;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--guide-live);
box-shadow: 0 0 0 4px var(--guide-live-glow);
}
.tree-stage {
position: relative;
height: 330px;
overflow: hidden;
background-image:
linear-gradient(var(--guide-grid-line) 1px, transparent 1px),
linear-gradient(90deg, var(--guide-grid-line) 1px, transparent 1px);
background-size: 24px 24px;
}
.tree-stage svg {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
overflow: visible;
}
.tree-edge {
fill: none;
stroke: var(--blue);
stroke-width: 2;
stroke-dasharray: 5 5;
vector-effect: non-scaling-stroke;
}
.tree-edge.trunk {
stroke: var(--gold);
stroke-dasharray: none;
stroke-width: 3;
}
.tree-node {
position: absolute;
z-index: 2;
display: grid;
gap: 6px;
width: 164px;
padding: 13px 15px;
border: 1px solid var(--guide-tree-border);
color: var(--paper);
background: var(--guide-tree-node);
text-align: left;
cursor: pointer;
transition:
border-color 0.2s ease,
background 0.2s ease,
transform 0.2s ease,
box-shadow 0.2s ease;
}
.tree-node span,
.tree-node small {
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.tree-node span {
color: var(--guide-tree-node-label);
}
.tree-node strong {
font: 600 var(--step-12) var(--font-mono);
}
.tree-node small {
color: var(--guide-tree-node-muted);
}
.tree-node.root {
top: 25px;
left: 50%;
transform: translateX(-50%);
border-color: var(--gold);
}
.tree-node.branch {
top: 220px;
}
.tree-node.ui {
left: 3%;
}
.tree-node.tests {
left: 50%;
transform: translateX(-50%);
}
.tree-node.docs {
right: 3%;
}
.tree-node:hover,
.tree-node.active {
border-color: var(--gold);
background: var(--guide-tree-node-hover);
box-shadow: 0 0 0 4px var(--guide-gold-glow);
}
.tree-node.root:hover,
.tree-node.root.active {
transform: translateX(-50%) translateY(-3px);
}
.tree-node.tests:hover,
.tree-node.tests.active {
transform: translateX(-50%) translateY(-3px);
}
.tree-node.ui:hover,
.tree-node.ui.active,
.tree-node.docs:hover,
.tree-node.docs.active {
transform: translateY(-3px);
}
.tree-detail {
display: grid;
grid-template-columns: 0.7fr 1fr 1.6fr;
gap: 1px;
border-top: 1px solid var(--guide-tree-rule);
background: var(--guide-tree-rule);
}
.tree-detail > div,
.tree-detail > p,
.tree-detail > code {
margin: 0;
padding: 18px;
background: var(--deep);
}
.tree-detail div {
display: grid;
gap: 8px;
}
.tree-detail span {
color: var(--accent);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.1em;
}
.tree-detail strong {
color: var(--paper);
font: 500 var(--step-0) var(--font-mono);
}
.tree-detail p {
color: var(--guide-tree-detail-text);
font-size: var(--step-0);
line-height: 1.55;
}
.tree-detail code {
grid-column: 1/-1;
color: var(--gold);
font: var(--step-0) var(--font-mono);
}
.route-console {
display: grid;
gap: 14px;
}
.route-table button {
display: grid;
grid-template-columns: 0.8fr 0.9fr 1.4fr;
width: 100%;
padding: 0;
border: 0;
color: inherit;
background: transparent;
text-align: left;
cursor: pointer;
}
.route-table button > * {
padding: 15px;
border-right: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.route-table button:hover,
.route-table button.active {
background: var(--guide-phase-hover);
}
.route-table button.active strong {
box-shadow: inset 4px 0 0 var(--gold);
}
.route-detail {
display: grid;
grid-template-columns: 100px 1fr;
gap: 22px;
align-items: center;
padding: 22px;
color: var(--paper);
background: var(--deep);
}
.route-meter {
display: grid;
align-items: end;
width: 76px;
height: 76px;
padding: 7px;
border: 1px solid var(--guide-meter-border);
}
.route-meter span {
display: block;
width: 100%;
height: 100%;
background: var(--gold);
transform: scaleY(var(--score));
transform-origin: bottom;
transition: transform 0.35s ease;
}
.route-detail > div:last-child {
display: grid;
gap: 7px;
}
.route-detail small {
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.route-detail strong {
font-size: var(--step-17);
}
.route-detail p {
margin: 0;
color: var(--guide-route-copy);
font-size: var(--step-12);
line-height: 1.5;
}
.skill-explorer {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
min-height: 290px;
background: var(--blue);
}
.skill-package button {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
padding: 17px 20px;
border: 0;
border-bottom: 1px solid var(--white-25);
color: var(--paper);
background: transparent;
text-align: left;
cursor: pointer;
}
.skill-package button:hover,
.skill-package button.active {
background: var(--guide-skill-hover);
}
.skill-package button.active {
box-shadow: inset 4px 0 0 var(--gold);
}
.skill-package button code {
font: var(--step-12) var(--font-mono);
}
.skill-package button small {
opacity: 0.7;
}
.skill-detail {
display: grid;
grid-template-columns: auto 1fr;
gap: 18px;
align-content: center;
padding: 28px;
color: var(--paper);
background: var(--guide-panel-blue);
}
.skill-detail > span {
color: var(--gold);
font:
var(--step-42) Georgia,
serif;
}
.skill-detail > div {
display: grid;
gap: 13px;
}
.skill-detail strong {
font: 600 var(--step-1) var(--font-mono);
}
.skill-detail p {
margin: 0;
color: var(--guide-skill-copy);
font-size: var(--step-12);
line-height: 1.65;
}
.skill-detail small {
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.worker-card:focus-visible,
.tree-node:focus-visible,
.route-table button:focus-visible,
.skill-package button:focus-visible {
outline: 3px solid var(--gold);
outline-offset: -3px;
}
/* Model and effort gearbox */
.model-gearbox {
margin-bottom: 150px;
padding-top: 80px;
border-top: 1px solid var(--line);
}
.gearbox-intro {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: 70px;
align-items: end;
margin: 45px 0;
}
.gearbox-intro h2 {
margin-bottom: 0;
}
.gearbox-intro > p {
max-width: 650px;
margin: 0;
color: var(--muted);
font-size: var(--step-14);
line-height: 1.75;
}
.gearbox {
display: grid;
grid-template-columns: 150px minmax(0, 1.35fr) minmax(230px, 0.65fr);
grid-template-rows: minmax(410px, auto) auto;
border: 1px solid var(--line);
background: var(--line);
gap: 1px;
}
.provider-tabs {
display: grid;
grid-template-rows: repeat(3, 1fr);
gap: 1px;
background: var(--line);
}
.provider-tabs button {
border: 0;
padding: 18px;
color: var(--ink);
background: var(--paper);
font: 700 var(--step-00) var(--font-mono);
letter-spacing: 0.08em;
cursor: pointer;
writing-mode: vertical-rl;
transform: rotate(180deg);
}
.provider-tabs button:hover {
background: var(--guide-skill-index-hover);
}
.provider-tabs button.active {
color: var(--paper);
background: var(--blue);
box-shadow: inset -5px 0 0 var(--gold);
}
.provider-detail {
display: grid;
align-content: start;
padding: 42px clamp(28px, 4vw, 58px);
color: var(--paper);
background: var(--deep);
}
.provider-detail header {
display: flex;
justify-content: space-between;
gap: 20px;
align-items: center;
}
.provider-detail header span {
color: var(--gold);
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
}
.provider-detail header a {
color: var(--guide-provider-copy);
font: 500 var(--step-09) var(--font-mono);
}
.provider-detail h3 {
margin: 34px 0 12px;
font-size: clamp(34px, 4vw, 62px);
letter-spacing: -0.06em;
}
.provider-detail > p {
max-width: 730px;
margin: 0;
color: var(--guide-provider-detail-copy);
font-size: var(--step-13);
line-height: 1.7;
}
.model-ladder {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px;
margin-top: 34px;
background: var(--guide-provider-rule);
}
.model-ladder div {
padding: 18px;
background: var(--guide-effort-surface);
}
.model-ladder span {
display: block;
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.model-ladder strong {
display: block;
margin-top: 10px;
font-size: var(--step-13);
}
.model-ladder small {
display: block;
margin-top: 7px;
color: var(--guide-effort-copy);
font-size: var(--step-00);
line-height: 1.4;
}
.effort-rail {
display: grid;
grid-template-rows: auto repeat(3, 1fr);
background: var(--guide-effort-active);
}
.effort-rail > span {
padding: 17px;
color: var(--accent);
font: 700 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.effort-rail button {
display: grid;
align-content: center;
gap: 8px;
padding: 22px;
border: 0;
border-top: 1px solid var(--line);
color: var(--ink);
background: var(--paper);
text-align: left;
cursor: pointer;
}
.effort-rail button b {
font: 700 var(--step-18) var(--font-mono);
}
.effort-rail button small {
color: var(--muted);
font-size: var(--step-00);
}
.effort-rail button:hover {
background: var(--guide-skill-index-hover);
}
.effort-rail button.active {
color: var(--paper);
background: var(--accent);
box-shadow: inset 5px 0 0 var(--gold);
}
.effort-rail button.active small {
color: var(--guide-effort-active-copy);
}
.effort-detail {
grid-column: 1/-1;
display: grid;
grid-template-columns: 150px 1fr auto;
gap: 25px;
align-items: center;
padding: 22px 28px;
color: var(--paper);
background: var(--guide-builder-surface);
}
.effort-detail > span {
color: var(--gold);
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.08em;
}
.effort-detail p {
margin: 0;
font-size: var(--step-12);
line-height: 1.55;
}
.effort-detail code {
padding: 10px 12px;
color: var(--gold);
background: var(--guide-tree-shadow);
font: var(--step-00) var(--font-mono);
}
.gearbox-rule {
display: grid;
grid-template-columns: 150px 1fr;
gap: 25px;
padding: 24px 28px;
color: var(--ink);
background: var(--gold);
}
.gearbox-rule span {
color: var(--accent);
font: 700 var(--step-09) var(--font-mono);
letter-spacing: 0.08em;
}
.gearbox-rule strong {
font-size: var(--step-13);
line-height: 1.5;
}
.provider-tabs button:focus-visible,
.effort-rail button:focus-visible,
.provider-detail a:focus-visible {
outline: 3px solid var(--gold);
outline-offset: -3px;
}
/* Skill shelf */
.skill-builder {
margin-bottom: 150px;
padding-top: 80px;
border-top: 1px solid var(--line);
}
.builder-intro {
display: grid;
grid-template-columns: 0.95fr 1.05fr;
gap: 70px;
align-items: end;
margin: 45px 0;
}
.builder-intro h2 {
margin-bottom: 0;
}
.builder-intro > p {
max-width: 620px;
margin: 0;
color: var(--muted);
font-size: var(--step-14);
line-height: 1.75;
}
.builder-workbench {
display: grid;
grid-template-columns: minmax(220px, 0.65fr) minmax(380px, 1.35fr) minmax(270px, 0.85fr);
min-height: 570px;
border: 1px solid var(--line);
background: var(--line);
}
.builder-steps {
display: grid;
grid-template-rows: repeat(5, 1fr);
gap: 1px;
background: var(--line);
}
.builder-steps button {
display: grid;
grid-template-columns: 42px 1fr;
grid-template-rows: auto auto;
align-content: center;
column-gap: 13px;
padding: 18px;
border: 0;
color: var(--ink);
background: var(--paper);
text-align: left;
cursor: pointer;
}
.builder-steps button b {
grid-row: 1/-1;
align-self: center;
color: var(--accent);
font: 500 var(--step-0) var(--font-mono);
}
.builder-steps button span {
font: 700 var(--step-12) var(--font-mono);
}
.builder-steps button small {
margin-top: 5px;
color: var(--muted);
font-size: var(--step-00);
}
.builder-steps button:hover {
background: var(--guide-skill-index-hover);
}
.builder-steps button.active {
color: var(--paper);
background: var(--blue);
box-shadow: inset 5px 0 0 var(--gold);
}
.builder-steps button.active b,
.builder-steps button.active small {
color: var(--gold);
}
.builder-detail {
display: grid;
grid-template-rows: auto auto auto 1fr auto;
align-content: start;
padding: 38px clamp(28px, 4vw, 58px);
color: var(--paper);
background: var(--deep);
}
.builder-detail header {
display: flex;
justify-content: space-between;
align-items: center;
}
.builder-detail header span {
color: var(--guide-builder-rule);
font: 500 54px var(--font-mono);
}
.builder-detail header small,
.builder-action span,
.builder-detail footer span {
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.1em;
}
.builder-detail h3 {
margin: 27px 0 14px;
font-size: clamp(26px, 3vw, 44px);
line-height: 1.05;
letter-spacing: -0.05em;
}
.builder-detail blockquote {
margin: 0;
padding: 0;
color: var(--guide-builder-copy);
font:
italic var(--step-20)/1.35 Georgia,
serif;
}
.builder-action {
align-self: center;
margin: 34px 0;
}
.builder-action p {
margin: 11px 0 0;
color: var(--guide-builder-action-copy);
font-size: var(--step-13);
line-height: 1.7;
}
.builder-detail footer {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1px;
background: var(--guide-provider-rule);
}
.builder-detail footer > div {
display: grid;
gap: 10px;
padding: 17px;
background: var(--guide-effort-surface);
}
.builder-detail footer strong {
font-size: var(--step-0);
line-height: 1.5;
}
.builder-artifact {
display: grid;
grid-template-rows: auto 1fr auto;
color: var(--paper);
background: var(--guide-code-surface);
}
.artifact-head {
display: flex;
justify-content: space-between;
padding: 17px;
border-bottom: 1px solid var(--guide-builder-border);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.09em;
}
.artifact-head i {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--guide-live);
box-shadow: 0 0 0 4px var(--guide-builder-live-glow);
}
.builder-artifact pre {
display: grid;
align-items: center;
margin: 0;
padding: 28px;
overflow: auto;
color: var(--guide-builder-code);
background-image:
linear-gradient(var(--guide-builder-grid) 1px, transparent 1px),
linear-gradient(90deg, var(--guide-builder-grid) 1px, transparent 1px);
background-size: 22px 22px;
}
.builder-artifact pre code {
font: var(--step-12)/1.9 var(--font-mono);
}
.artifact-command {
display: grid;
gap: 9px;
padding: 18px;
border-top: 1px solid var(--guide-builder-border);
}
.artifact-command span {
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.09em;
}
.artifact-command code {
font: var(--step-00) var(--font-mono);
}
.builder-loop {
display: grid;
grid-template-columns: 200px 1fr;
gap: 25px;
padding: 23px 28px;
color: var(--ink);
background: var(--gold);
}
.builder-loop > span {
font: 700 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
}
.builder-loop > div {
font: 600 var(--step-0) var(--font-mono);
}
.builder-loop i {
margin: 0 12px;
color: var(--accent);
font-style: normal;
}
.builder-steps button:focus-visible {
position: relative;
z-index: 2;
outline: 3px solid var(--gold);
outline-offset: -3px;
}
.skill-catalog {
margin-bottom: 130px;
padding-top: 80px;
border-top: 1px solid var(--line);
}
.verification {
padding-top: 80px;
border-top: 1px solid var(--line);
margin-bottom: 130px;
}
.verify-intro {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: 70px;
align-items: end;
margin: 45px 0;
}
.verify-intro h2 {
margin-bottom: 0;
}
.verify-intro > p {
max-width: 650px;
margin: 0;
color: var(--muted);
font-size: var(--step-14);
line-height: 1.75;
}
.verify-layers {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px;
margin-top: 1px;
background: var(--line);
border: 1px solid var(--line);
}
.verify-layers article {
background: var(--paper);
padding: 24px 22px;
display: grid;
gap: 12px;
grid-template-rows: auto auto 1fr auto;
}
.verify-layers article > span {
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
color: var(--accent);
}
.verify-layers article h3 {
margin: 0;
font-size: var(--step-18);
letter-spacing: -0.02em;
}
.verify-layers article p {
margin: 0;
color: var(--muted);
font-size: var(--step-13);
line-height: 1.55;
}
.verify-layers article code {
font: 10.5px var(--font-mono);
color: var(--ink);
background: var(--paper);
border: 1px solid var(--line);
padding: 10px 12px;
white-space: pre-wrap;
word-break: break-word;
line-height: 1.55;
}
.verify-antipatterns {
margin-top: 55px;
}
.verify-antipatterns > span {
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
color: var(--muted);
}
.ap-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1px;
margin-top: 14px;
background: var(--line);
border: 1px solid var(--line);
}
.ap-grid article {
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 18px;
align-items: start;
background: var(--paper);
padding: 18px 20px;
}
.ap-grid article b {
font: 500 var(--step-22) var(--font-mono);
color: var(--accent);
line-height: 1;
align-self: center;
}
.ap-grid article strong {
font-size: var(--step-1);
letter-spacing: -0.01em;
}
.ap-grid article p {
margin: 6px 0 0;
color: var(--muted);
font-size: var(--step-13);
line-height: 1.5;
}
.ap-grid article code {
font: var(--step-0) var(--font-mono);
color: var(--ink);
background: var(--paper);
padding: 1px 4px;
border: 1px solid var(--line);
}
.verify-cta {
margin-top: 55px;
padding: 26px 28px;
color: var(--paper);
background: var(--ink);
}
.verify-cta > span {
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
color: var(--gold);
}
.verify-cta-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1px;
margin-top: 18px;
background: var(--guide-verify-rule);
}
.verify-card {
display: grid;
gap: 6px;
background: var(--ink);
padding: 20px 22px;
color: var(--paper);
text-decoration: none;
border-bottom: 2px solid var(--gold);
}
.verify-card strong {
font-size: var(--step-17);
letter-spacing: -0.01em;
}
.verify-card p {
margin: 0;
color: var(--guide-verify-copy);
font-size: var(--step-13);
line-height: 1.55;
}
.verify-card p code {
font: var(--step-0) var(--font-mono);
color: var(--gold);
background: var(--guide-verify-code);
padding: 1px 5px;
border: 1px solid var(--guide-verify-code-border);
}
.verify-card small {
font: 500 var(--step-00) var(--font-mono);
color: var(--gold);
letter-spacing: 0.09em;
} /* token-gap: preserve the legacy verification layout threshold; this behavior is required by task 15e */
@media (max-width: 880px) {
.verify-layers,
.verify-cta-grid {
grid-template-columns: 1fr;
}
.verify-intro {
grid-template-columns: 1fr;
}
}
@media (max-width: 560px) {
.verify-intro {
display: block;
}
.verify-intro > p {
margin-top: 18px;
}
.ap-grid {
grid-template-columns: 1fr;
}
.verify-cta {
padding: 22px 20px;
}
}
.catalog-intro {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: 70px;
align-items: end;
margin: 45px 0;
}
.catalog-intro h2 {
margin-bottom: 0;
}
.catalog-intro > p {
max-width: 620px;
margin: 0;
color: var(--muted);
font-size: var(--step-14);
line-height: 1.75;
}
.skill-deck {
display: grid;
grid-template-columns: minmax(270px, 0.8fr) minmax(0, 1.7fr);
min-height: 620px;
border: 1px solid var(--line);
background: var(--line);
}
.skill-index {
display: grid;
grid-template-rows: repeat(7, 1fr);
gap: 1px;
background: var(--line);
}
.skill-index button {
display: grid;
grid-template-columns: 95px 1fr;
grid-template-rows: auto auto;
align-content: center;
column-gap: 18px;
padding: 16px 20px;
border: 0;
color: var(--ink);
background: var(--paper);
text-align: left;
cursor: pointer;
transition:
background 0.2s ease,
color 0.2s ease;
}
.skill-index button span {
grid-row: 1/-1;
align-self: center;
color: var(--accent);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.skill-index button strong {
font: 600 var(--step-13) var(--font-mono);
}
.skill-index button small {
margin-top: 5px;
color: var(--muted);
font-size: var(--step-00);
}
.skill-index button:hover {
background: var(--guide-skill-index-hover);
}
.skill-index button.active {
color: var(--paper);
background: var(--deep);
box-shadow: inset 5px 0 0 var(--gold);
}
.skill-index button.active span,
.skill-index button.active small {
color: var(--gold);
}
.common-skill-detail {
display: grid;
grid-template-rows: auto auto auto 1fr;
align-content: start;
padding: 44px clamp(30px, 5vw, 78px);
color: var(--paper);
background: var(--accent);
overflow: hidden;
}
.common-skill-detail header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 18px;
border-bottom: 1px solid var(--guide-accent-rule);
}
.common-skill-detail header span {
font: 500 var(--step-48) var(--font-mono);
opacity: 0.34;
}
.common-skill-detail header small {
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.1em;
}
.common-skill-detail h3 {
margin: 38px 0 18px;
font-size: var(--step-skill-title);
letter-spacing: -0.06em;
}
.common-skill-detail blockquote {
max-width: 720px;
margin: 0 0 38px;
padding: 0;
border: 0;
color: var(--gold);
font:
400 clamp(var(--step-20), 2.5vw, 34px)/1.15 Georgia,
serif;
font-style: italic;
}
.common-skill-notes {
display: grid;
grid-template-columns: 1.45fr 0.9fr 0.9fr;
gap: 1px;
align-self: end;
background: var(--guide-accent-rule);
}
.common-skill-notes > div {
padding: 20px;
background: var(--guide-accent-note);
}
.common-skill-notes span {
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.common-skill-notes p {
margin: 12px 0 0;
color: var(--guide-accent-copy);
font-size: var(--step-12);
line-height: 1.55;
}
.common-skill-notes div:nth-child(2) p {
font-family: var(--font-mono);
font-size: var(--step-00);
}
.skill-loadout {
display: grid;
grid-template-columns: 210px 1fr;
gap: 25px;
padding: 24px 28px;
color: var(--paper);
background: var(--ink);
}
.skill-loadout > span {
color: var(--gold);
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
}
.skill-loadout > div {
font: 500 var(--step-0) var(--font-mono);
}
.skill-loadout b {
color: var(--accent);
font-size: var(--step-09);
}
.skill-loadout i {
margin: 0 10px;
color: var(--gold);
font-style: normal;
}
.skill-index button:focus-visible {
position: relative;
z-index: 2;
outline: 3px solid var(--gold);
outline-offset: -3px;
}
.skill-source {
display: inline-block;
margin-top: 22px;
color: var(--gold);
font: 700 var(--step-09) var(--font-mono);
letter-spacing: 0.07em;
text-decoration: none;
border-bottom: 1px solid currentColor;
}
.skill-source:focus-visible {
outline: 3px solid var(--gold);
outline-offset: 4px;
}
.install-skills {
display: grid;
grid-template-rows: auto 1fr auto;
margin-top: 24px;
color: var(--paper);
background: var(--deep);
border-left: 7px solid var(--gold);
}
.install-skills header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24px;
padding: 20px 24px;
border-bottom: 1px solid var(--guide-install-rule);
}
.install-skills header > div {
display: grid;
gap: 7px;
}
.install-skills header span,
.install-skills footer {
color: var(--gold);
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.08em;
}
.install-skills header strong {
font-size: var(--step-1);
}
.install-skills button {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border: 1px solid var(--guide-control-border);
color: var(--paper);
background: transparent;
cursor: pointer;
}
.install-skills button:hover,
.install-skills button.copied {
color: var(--ink);
border-color: var(--gold);
background: var(--gold);
}
.install-skills button i {
font-style: normal;
}
.install-skills pre {
max-height: 360px;
margin: 0;
padding: 24px;
overflow: auto;
white-space: pre-wrap;
background: var(--guide-code-surface);
}
.install-skills pre code {
font: var(--step-00)/1.7 var(--font-mono);
}
.install-skills footer {
padding: 16px 24px;
color: var(--guide-install-copy);
border-top: 1px solid var(--guide-install-rule);
}
.install-skills button:focus-visible {
outline: 3px solid var(--gold);
outline-offset: 3px;
}
/* Copy-ready hands-on lab */
.hands-on {
margin-bottom: 130px;
padding-top: 80px;
border-top: 1px solid var(--line);
}
.hands-intro {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: 70px;
align-items: end;
margin: 45px 0;
}
.hands-intro h2 {
margin-bottom: 0;
}
.hands-intro > div:last-child > p {
max-width: 650px;
margin: 0;
color: var(--muted);
font-size: var(--step-14);
line-height: 1.75;
}
.starter-link {
display: inline-block;
margin-top: 18px;
color: var(--blue);
font: 700 var(--step-0) var(--font-mono);
text-decoration: none;
border-bottom: 2px solid var(--gold);
}
.starter-links {
display: flex;
flex-wrap: wrap;
gap: 14px 28px;
margin-top: 18px;
}
.starter-links .starter-link {
margin-top: 0;
}
.starter-link-group {
display: flex;
flex-wrap: wrap;
gap: 6px 18px;
align-items: baseline;
}
.starter-link-source {
font-weight: 500 !important;
color: var(--muted) !important;
border-bottom-color: transparent !important;
}
.verify-card-source {
display: block;
margin-top: 8px;
color: var(--guide-verify-copy);
font-size: var(--step-00) !important;
letter-spacing: 0.05em;
text-transform: none;
font-weight: 500;
}
.verify-card-source span {
font-family: var(--font-mono);
color: var(--gold);
}
.exercise-brief {
display: grid;
grid-template-columns: 190px 1fr;
gap: 22px;
padding: 26px 30px;
color: var(--paper);
background: var(--deep);
}
.exercise-brief > span {
color: var(--gold);
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.09em;
}
.exercise-brief > strong {
font-size: var(--step-exercise-title);
line-height: 1.12;
}
.exercise-brief > div {
grid-column: 2;
color: var(--guide-exercise-copy);
font: 500 var(--step-09) var(--font-mono);
letter-spacing: 0.05em;
}
.exercise-brief b {
margin-left: 18px;
color: var(--accent);
}
.exercise-brief b:first-child {
margin-left: 0;
}
.prompt-compare {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1px;
margin-top: 1px;
background: var(--line);
}
.prompt-card {
display: grid;
grid-template-rows: auto 1fr auto;
min-width: 0;
min-height: 600px;
color: var(--paper);
background: var(--guide-prompt-surface);
}
.prompt-card.enhanced {
background: var(--guide-prompt-enhanced);
}
.prompt-card header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 22px;
border-bottom: 1px solid var(--guide-prompt-rule);
}
.prompt-card header > div {
display: grid;
gap: 6px;
}
.prompt-card header span,
.prompt-card footer {
font: 500 var(--step-08) var(--font-mono);
letter-spacing: 0.09em;
}
.prompt-card header > div span {
color: var(--gold);
}
.prompt-card header strong {
font-size: var(--step-17);
}
.prompt-card button {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border: 1px solid var(--guide-control-border);
color: var(--paper);
background: transparent;
cursor: pointer;
}
.prompt-card button:hover,
.prompt-card button.copied {
color: var(--ink);
border-color: var(--gold);
background: var(--gold);
}
.prompt-card button i {
font-style: normal;
}
.prompt-card pre {
margin: 0;
padding: 25px;
overflow: auto;
white-space: pre-wrap;
}
.prompt-card pre code {
font: var(--step-0)/1.72 var(--font-mono);
}
.prompt-card footer {
padding: 17px 22px;
color: var(--guide-verify-copy);
border-top: 1px solid var(--guide-prompt-rule);
}
.prompt-card.enhanced footer {
color: var(--guide-prompt-enhanced-copy);
}
.prompt-card button:focus-visible,
.starter-link:focus-visible {
outline: 3px solid var(--gold);
outline-offset: 3px;
}
.comparison-strip {
display: grid;
grid-template-columns: 190px repeat(4, 1fr);
gap: 1px;
background: var(--line);
}
.comparison-strip > * {
padding: 18px;
background: var(--paper);
}
.comparison-strip > span {
color: var(--accent);
font: 700 var(--step-09) var(--font-mono);
letter-spacing: 0.08em;
}
.comparison-strip > div {
color: var(--muted);
font: 500 var(--step-00) var(--font-mono);
}
.comparison-strip b {
margin-right: 8px;
color: var(--blue);
}
.copy-status {
min-height: 20px;
margin: 15px 0 0;
color: var(--blue);
font: 600 var(--step-00) var(--font-mono);
text-align: right;
}
@media (min-width: 1600px) {
.tree-detail {
grid-template-columns: 0.6fr 0.8fr 1.8fr;
}
}
@media (min-width: 2200px) {
main {
max-width: 2880px;
padding-inline: clamp(140px, 7vw, 280px);
}
.hero {
max-width: 1420px;
}
.hero h1 {
font-size: var(--step-display-wide);
}
.tree-detail > * {
font-size: var(--step-14) !important;
}
.fleet,
.failure-map {
margin-bottom: 170px;
}
.workflow,
.routing,
.skills {
margin-bottom: 180px;
}
}
@media (max-width: 1100px) {
.chapter-links {
display: none;
}
.builder-workbench {
grid-template-columns: minmax(210px, 0.65fr) minmax(0, 1.35fr);
}
.builder-artifact {
grid-column: 1/-1;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
}
.builder-artifact .artifact-head {
grid-column: 1/-1;
}
.artifact-command {
align-content: center;
border-top: 0;
border-left: 1px solid var(--guide-builder-border);
}
}
/* token-gap: preserve the legacy worktree and skill layout threshold; this behavior is required by task 15e */
@media (max-width: 1050px) {
.tree-detail {
grid-template-columns: 1fr 1fr;
}
.tree-detail p {
grid-column: 1/-1;
}
.skill-explorer {
grid-template-columns: 1fr;
}
}
@media (max-width: 800px) {
.worker-detail {
grid-template-columns: 1fr;
}
.worktrees {
display: block;
}
.worktree-intro {
margin-bottom: 40px;
}
.tree-lab {
box-shadow: 9px 9px 0 var(--guide-tree-shadow);
}
.route-table button {
min-width: 620px;
}
.gearbox-intro,
.builder-intro,
.catalog-intro,
.hands-intro {
grid-template-columns: 1fr;
gap: 20px;
}
.gearbox {
grid-template-columns: 1fr 210px;
grid-template-rows: auto auto;
}
.provider-tabs {
grid-column: 1/-1;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: none;
}
.provider-tabs button {
writing-mode: horizontal-tb;
transform: none;
}
.provider-tabs button.active {
box-shadow: inset 0 -5px 0 var(--gold);
}
.effort-detail {
grid-template-columns: 110px 1fr;
}
.effort-detail code {
grid-column: 2;
}
.skill-explorer {
grid-template-columns: 1fr 1fr;
}
.builder-workbench {
grid-template-columns: 1fr;
}
.builder-steps {
grid-template-columns: 1fr 1fr;
grid-template-rows: none;
}
.builder-artifact {
grid-column: auto;
}
.skill-deck {
grid-template-columns: 1fr;
}
.skill-index {
grid-template-columns: 1fr 1fr;
grid-template-rows: none;
}
.common-skill-detail {
min-height: 600px;
}
.common-skill-notes {
grid-template-columns: 1fr 1fr;
}
.common-skill-notes > div:first-child {
grid-column: 1/-1;
}
.prompt-compare {
grid-template-columns: 1fr;
}
.comparison-strip {
grid-template-columns: 1fr 1fr;
}
.comparison-strip > span {
grid-column: 1/-1;
}
.exercise-brief {
grid-template-columns: 1fr;
}
.exercise-brief > div {
grid-column: auto;
}
}
/* token-gap: preserve the legacy full-guide layout threshold; responsive.css is gone, so this rule is now the only definition of it */
@media (max-width: 600px) {
.tree-detail {
grid-template-columns: 1fr;
}
.tree-detail p,
.tree-detail code {
grid-column: auto;
}
.gearbox {
grid-template-columns: 1fr;
}
.provider-detail,
.effort-rail {
grid-column: 1;
}
.model-ladder {
grid-template-columns: 1fr;
}
.effort-rail {
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto auto;
}
.effort-rail > span {
grid-column: 1/-1;
}
.effort-rail button {
text-align: center;
border-top: 1px solid var(--line);
border-left: 1px solid var(--line);
}
.effort-rail button.active {
box-shadow: inset 0 -5px 0 var(--gold);
}
.effort-detail {
grid-template-columns: 1fr;
}
.effort-detail code {
grid-column: auto;
overflow: auto;
}
.gearbox-rule {
grid-template-columns: 1fr;
}
.skill-explorer {
grid-template-columns: 1fr;
}
.route-detail {
grid-template-columns: 70px 1fr;
}
.route-meter {
width: 56px;
height: 70px;
}
.builder-steps {
grid-template-columns: 1fr;
}
.builder-steps button {
min-height: 78px;
}
.builder-detail {
padding: 28px 24px;
}
.builder-detail footer {
grid-template-columns: 1fr;
}
.builder-artifact {
grid-template-columns: 1fr;
}
.builder-artifact .artifact-head {
grid-column: auto;
}
.artifact-command {
border-left: 0;
border-top: 1px solid var(--guide-builder-border);
}
.builder-loop {
grid-template-columns: 1fr;
}
.builder-loop > div {
line-height: 2;
}
.builder-loop i {
margin-inline: 4px;
}
.skill-index {
grid-template-columns: 1fr;
}
.skill-index button {
min-height: 78px;
}
.common-skill-detail {
min-height: 0;
padding: 30px 24px;
}
.common-skill-notes {
grid-template-columns: 1fr;
}
.common-skill-notes > div:first-child {
grid-column: auto;
}
.skill-loadout {
grid-template-columns: 1fr;
}
.skill-loadout > div {
line-height: 2;
}
.skill-loadout i {
margin-inline: 4px;
}
.install-skills header {
align-items: flex-start;
}
.install-skills header strong {
font-size: var(--step-12);
}
.install-skills pre {
max-height: 500px;
}
.exercise-brief {
padding: 22px;
}
.exercise-brief > div {
line-height: 2;
}
.exercise-brief b {
margin-left: 7px;
}
.prompt-card {
min-height: 0;
}
.prompt-card pre {
max-height: 560px;
}
.comparison-strip {
grid-template-columns: 1fr;
}
.comparison-strip > span {
grid-column: auto;
}
.copy-status {
text-align: left;
}
}
@media (prefers-reduced-motion: reduce) {
.worker-card,
.tree-node,
.route-meter span {
transition: none;
}
.reading-progress span {
transition: none;
}
}
</style>