91e8d380d0
Move the Astro-facing responsive layer out of responsive.css, retaining the exact legacy stylesheet for full-guide/index.html until task 20. Scope worktree and fleet overrides to their components so they can win against component base styles. Do not delete responsive.css: the legacy page still loads it. Generated screenshot artifacts are deliberately untracked.
3241 lines
99 KiB
TypeScript
3241 lines
99 KiB
TypeScript
---
|
||
// /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 '../../styles.css';
|
||
import '../../full-guide/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 lê 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 context—not 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 nó 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 dá 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; task 20 can retire it with the legacy stylesheet */
|
||
@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 1var (--step-08) 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 4var (--step-08) 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; task 20 can retire it with the legacy stylesheet */
|
||
@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>
|