feat(15d): complete localization of full-guide page to PT

This commit is contained in:
Marcos Paulo
2026-09-05 22:30:50 +00:00
parent c022a93302
commit 054393f7af
38 changed files with 1322 additions and 325 deletions
@@ -24,7 +24,7 @@ const { label, columns = 3 } = Astro.props;
.grid {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
gap: 1px; /* hairline separators, drawn by the parent background */
gap: 1px; /* hairline separators, drawn by the parent background */
background: var(--line);
}
@@ -34,6 +34,8 @@ const { label, columns = 3 } = Astro.props;
}
@media (max-width: 800px) {
.grid { grid-template-columns: 1fr; }
.grid {
grid-template-columns: 1fr;
}
}
</style>
+34 -21
View File
@@ -20,25 +20,33 @@ const { items, initialId = items[0]?.id } = Astro.props;
<div class="island" data-initial={initialId}>
<div class="tabs" role="tablist" aria-label="Sections">
{items.map((item) => (
<button
role="tab"
id={`tab-${item.id}`}
aria-controls={`panel-${item.id}`}
aria-selected={item.id === initialId}
data-tab={item.id}
>{item.label}</button>
))}
{
items.map((item) => (
<button
role="tab"
id={`tab-${item.id}`}
aria-controls={`panel-${item.id}`}
aria-selected={item.id === initialId}
data-tab={item.id}
>
{item.label}
</button>
))
}
</div>
{items.map((item) => (
<div
role="tabpanel"
id={`panel-${item.id}`}
aria-labelledby={`tab-${item.id}`}
data-panel={item.id}
hidden={item.id !== initialId}
>{item.body}</div>
))}
{
items.map((item) => (
<div
role="tabpanel"
id={`panel-${item.id}`}
aria-labelledby={`tab-${item.id}`}
data-panel={item.id}
hidden={item.id !== initialId}
>
{item.body}
</div>
))
}
</div>
<script>
@@ -68,7 +76,10 @@ const { items, initialId = items[0]?.id } = Astro.props;
</script>
<style>
.tabs { display: grid; gap: 8px; }
.tabs {
display: grid;
gap: 8px;
}
button {
padding: 12px;
@@ -78,7 +89,7 @@ const { items, initialId = items[0]?.id } = Astro.props;
text-align: left;
cursor: pointer;
/* transform/opacity only — never animate layout properties */
transition: background 180ms cubic-bezier(.2, 0, 0, 1);
transition: background 180ms cubic-bezier(0.2, 0, 0, 1);
}
button[aria-selected='true'] {
@@ -92,6 +103,8 @@ const { items, initialId = items[0]?.id } = Astro.props;
}
@media (prefers-reduced-motion: reduce) {
button { transition-duration: .01ms; }
button {
transition-duration: 0.01ms;
}
}
</style>
@@ -40,7 +40,7 @@ const { eyebrow, title, body, href } = Astro.props;
.eyebrow {
color: var(--accent);
font: var(--font-eyebrow);
letter-spacing: .1em;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@@ -48,7 +48,7 @@ const { eyebrow, title, body, href } = Astro.props;
margin: 0;
font-size: var(--step-5);
line-height: 1.05;
letter-spacing: -.06em; /* tight display tracking is a signature of this design */
letter-spacing: -0.06em; /* tight display tracking is a signature of this design */
}
p {
@@ -69,6 +69,8 @@ const { eyebrow, title, body, href } = Astro.props;
}
@media (max-width: 800px) {
.block { padding: 18px; }
.block {
padding: 18px;
}
}
</style>
+1 -5
View File
@@ -1,10 +1,6 @@
{
"extends": ["stylelint-config-standard"],
"ignoreFiles": [
"dist/**",
"public/hands-on/**",
"submitted-skills/**"
],
"ignoreFiles": ["dist/**", "public/hands-on/**", "submitted-skills/**"],
"rules": {
"custom-property-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"declaration-property-value-disallowed-list": {
+5 -5
View File
@@ -8,11 +8,11 @@ export default [
{
ignores: [
'dist/**',
'public/hands-on/**', // lab fixtures ship verbatim — linting them would
// invite "fixes" that break the exercise
'submitted-skills/**', // other people's work, reproduced as submitted
'skill-reviews/**', // generated from skills-review/catalog.js
'vote-service/**', // Go service, separate lifecycle
'public/hands-on/**', // lab fixtures ship verbatim — linting them would
// invite "fixes" that break the exercise
'submitted-skills/**', // other people's work, reproduced as submitted
'skill-reviews/**', // generated from skills-review/catalog.js
'vote-service/**', // Go service, separate lifecycle
],
},
{
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # gate.sh compares assertion counts against origin/main
fetch-depth: 0 # gate.sh compares assertion counts against origin/main
- uses: actions/setup-node@v4
with:
+20 -11
View File
@@ -28,25 +28,30 @@ const lang = 'en'; // TODO: wire to the language toggle decision (task 03)
</section>
<GridGroup label="Chapter sections" columns={3}>
{chapter.data.sections.map((section) => (
<StaticBlock
eyebrow={section.eyebrow[lang]}
title={section.title[lang]}
body={section.body[lang]}
/>
))}
{
chapter.data.sections.map((section) => (
<StaticBlock
eyebrow={section.eyebrow[lang]}
title={section.title[lang]}
body={section.body[lang]}
/>
))
}
</GridGroup>
</ChapterLayout>
<style>
/* Page-level layout only. Anything reusable belongs in a component. */
.hero { max-width: 780px; padding: clamp(75px, 12vh, 145px) 0 85px; }
.hero {
max-width: 780px;
padding: clamp(75px, 12vh, 145px) 0 85px;
}
h1 {
margin: 16px 0 24px;
font-size: var(--step-display);
line-height: .86;
letter-spacing: -.08em;
line-height: 0.86;
letter-spacing: -0.08em;
}
/* Georgia is a real system font and DOES render — unlike Manrope/DM Mono.
@@ -57,5 +62,9 @@ const lang = 'en'; // TODO: wire to the language toggle decision (task 03)
font-weight: 400;
}
.lede { max-width: 570px; color: var(--muted); line-height: 1.65; }
.lede {
max-width: 570px;
color: var(--muted);
line-height: 1.65;
}
</style>
+14 -3
View File
@@ -39,7 +39,18 @@ const items = entries.map((entry) => ({
</BaseLayout>
<style>
.hero { max-width: 780px; padding: clamp(75px, 12vh, 145px) 0 85px; }
h1 { font-size: var(--step-display); line-height: .86; letter-spacing: -.08em; }
h1 em { color: var(--blue); font-family: Georgia, serif; font-weight: 400; }
.hero {
max-width: 780px;
padding: clamp(75px, 12vh, 145px) 0 85px;
}
h1 {
font-size: var(--step-display);
line-height: 0.86;
letter-spacing: -0.08em;
}
h1 em {
color: var(--blue);
font-family: Georgia, serif;
font-weight: 400;
}
</style>