Skip to content

Redesign: information architecture, content, and design (merge 1 of 2) - #22

Merged
haksungjang merged 26 commits into
mainfrom
redesign-2026-09
Sep 3, 2026
Merged

haksungjang merged 26 commits into
mainfrom
redesign-2026-09

Conversation

@haksungjang

Copy link
Copy Markdown
Contributor

Summary

First of two merges in the site-wide redesign (K0 through K15-a). Covers information
architecture, content restructuring, and visual design. Example-code fixes, CI automation,
and the TRUSCA link check remain on the branch for a second merge.

  • Redirect infrastructure (@docusaurus/plugin-client-redirects) replaces the dead
    Netlify-era _redirects file; the blog instance and its React Native image assets
    (81MB) are removed.
  • Sidebar reorder, agents.md moved to the reference instance, checklist-mapping.md
    split into a summary and a canonical requirements-matrix.md, chapter 08's four method
    pages merged into a single index.
  • Design: customTheme.scss split into six partials, dead fork-era stylesheet removed,
    type scale and primary colour replaced per the approved mockup, landing/doc pages/404
    rebuilt, Lighthouse gate reset to the new assertions.
  • English locale kept in sync throughout; a GitHub Pages limitation (English 404s falling
    back to the Korean 404 page) is worked around client-side.
  • An independent verification pass (not by the sessions that made the changes) confirmed
    the pre-merge checklist against live script output before this PR was opened.

Test plan

  • bash .claude/scripts/verify.sh 13/13
  • cd website && npm run build (ko + en)
  • python3 .claude/scripts/check-redirects.py docs/_plan/routes-baseline.txt website/build — all 28 dropped URLs redirect to a real destination
  • Lighthouse: 6 URLs × 3 runs, accessibility ≥ 0.95, zero color-contrast violations
  • ko-style-lint: zero new findings introduced by this branch
  • All 24 commits carry Signed-off-by
  • Manual review of the diff and screenshots before merge

Six defects found by a four-axis site diagnosis. All were reproduced before
being fixed; none are redesign work.

- ai-security-review: the workflow did not parse as YAML because the Python
  f-string inside `run: |` dropped to column 0 and ended the block scalar.
  Re-indented; verified with PyYAML and actionlint.
- trivy-action: `@0.36.0` is not a real tag (the tag is `v0.36.0`). Fixed in
  12 places, not the 7 first counted. All 17 `uses:` refs in published content
  were resolved with git ls-remote.
- iac-security: `CKV_AWS_52` does not exist in Checkov 3.3.16, so the skip did
  nothing. Replaced with `CKV_AWS_144`, which actually fails on that resource;
  confirmed by running Checkov before and after.
- customTheme.scss: a dark-mode selector used `[class*="Button"]`, a React
  Native naming leftover that misses Docusaurus's lowercase `button--primary`.
  It repainted every landing link, leaving the FinalCTA button at 1.00:1. The
  rule gave nothing Infima does not already give, so it is removed. Measured
  after the fix: 16.27:1, 7.72:1, 13.40:1, link colour unchanged at 8.16:1.
- license grades: method1 and method4 contradicted the canonical classification
  on LGPL, CC-BY-SA, SSPL and Commons Clause. Aligned to canon, and CC-BY-SA now
  has a canonical entry of its own instead of being inferred. The CI grep also
  needed word boundaries: `GPL-2\.0` was matching inside `LGPL-2.0`.
- trivy supply chain: an earlier correction went too far. Only the advisory ID
  was wrong; the March 2026 tag re-pointing did happen (GHSA-69fq-xp46-6x23,
  76 of 77 trivy-action tags). The two Trivy incidents are separate and are now
  described separately.

Signed-off-by: Haksung Jang <haksung@sk.com>
The site deploys to GitHub Pages, which does not read Netlify _redirects,
so the repository had no working redirect mechanism for the upcoming URL
moves. website/static/_redirects held React Native template rules and was
shipped to production on every build.

Add @docusaurus/plugin-client-redirects 3.9.2, pinned to match
@docusaurus/core. Measured its behaviour with a probe rule before wiring
the real ones: it duplicates rules per locale, prefixes `to` with the
locale baseUrl (/ for ko, /en/ for en), and emits <path>/index.html under
trailingSlash: false. One rule set therefore covers both locales.

Disable the blog. It generated /blog and its feeds but the navbar and
footer links were commented out, so nothing on the site reached it and
the only post was the template placeholder. The eight blog URLs per
locale now redirect to the site root.

Remove the React Native leftovers this touched: static/_redirects,
scripts/src/update-redirects.ts and its package script, and netlify.toml.
With netlify.toml gone, process.env.NETLIFY can never be set, so drop the
isProductionDeployment branch and pin concatenateModules to false, which
is what GitHub Pages builds already did.

Add .claude/scripts/check-redirects.py as the gate. The plugin validates
`to` but not `from`, so a missing redirect is silent. The script diffs the
baseline routes against the current sitemaps and requires every vanished
URL to have a redirect whose target actually exists. It confirms exactly
16 removed URLs, all covered.

verify.sh 13/13, build passes for ko and en, yarn install --immutable
passes.

Signed-off-by: Haksung Jang <haksung@sk.com>
website/static/blog held 119 React Native blog images totalling 81MB.
They came in with the Docusaurus template fork, nothing in this site
references them, and there is no plan to reuse them.

Because they sat in static/, every build copied them to /blog/assets/
for both locales. The previous commit removed the blog instance, so the
site was serving blog images for a blog that no longer exists.

A plain string grep never surfaced these: the only signal is the
directory name and the files themselves are binaries. That is why the
diagnosis and the plan both missed them.

Kept as a separate commit from the blog removal so an 81MB deletion is
distinguishable in history.

Sitemaps are unchanged, the redirect gate still reports the same 16
removed URLs all covered, build passes for ko and en, verify.sh 13/13.

Signed-off-by: Haksung Jang <haksung@sk.com>
Acts on the information-architecture findings. Four changes to how pages
are placed, plus the guard rails that keep the moves honest.

Entry point. /docs served the overview page while the sidebar listed it
third, so the page a reader landed on was not the page the sidebar
started with. The overview is now first, followed by quick start and the
standards mapping.

start-path had no inbound link from any page. It was built as a routing
page for readers choosing a path, but the landing CTA went to quick start
instead, so only sidebar browsers ever found it. Its three routes now
live in the overview's next-steps section, where a reader choosing a path
actually is, and the page is gone.

The agent guide moves from docs to reference. reference/intro already
claimed an "agent selection guide" section that held nothing but a link
out to docs, so the reference instance advertised a page it did not own.
The table also listed only the nine program-building agents; the seven
automation agents shipped with no entry anywhere. All sixteen are now
covered, split into program-building and automation groups.

pipeline-security is registered in the DevSecOps sidebar. Eight pages
link to it and it was in none of them, so it had no sidebar highlight and
no prev/next.

Supporting changes. The three standard-mapping pages get parallel labels
so the sidebar shows they are one family. sidebar_position values are
aligned with the manual sidebar arrays across all four instances, which
removes two duplicates and one out-of-order entry. The 08 chapter drops
its redundant `id:`, which only made the sidebar reference a numbered
doc id; the URL is unaffected and needs no redirect.

verify.sh checks 3, 6 and 7 now search website/reference as well as docs.
Without this the agent guide would leave the admonition check simply by
moving, and the gate would keep passing while covering less. The expanded
roots surface no new failures on current content.

check-redirects.py reports 20 removed URLs, 10 per locale, all covered.
verify.sh 13/13, build passes for ko and en, ko-style lint 0 findings.

Signed-off-by: Haksung Jang <haksung@sk.com>
The overview chapter sent newcomers through four competing entry pages and
told them to read a 613-line requirements matrix as step 2 of self-study.

- Point self-study step 2 at what the two standards require rather than at
  the 31-item structure, and make every step a real link
- Keep the git clone instructions in 01-setup only; the overview and the
  5-minute quick start now link there
- Keep the no-install SBOM demo in the quick start only; the tools index
  links to it
- Keep the chapter and deliverable tables in the overview only; the
  reference index links to them
- Finish the three-way branch in the overview's next-steps section
- Promote the h4 headings under sections 3 and 4 of supply-chain to h3 so
  heading order no longer skips a level

Signed-off-by: Haksung Jang <haksung@sk.com>
Sections 3 and 4 jumped from h2 straight to h4, which Lighthouse reports as
a heading-order violation. The Korean page was fixed in the previous commit;
this brings the English page back in line with it.

Heading text and body are untouched, and heading ids derive from the text
rather than the level, so no anchor changes. The eight promoted headings now
appear in the page table of contents, which stops at h3.

Signed-off-by: Haksung Jang <haksung@sk.com>
…atrix

The checklist mapping was 613 lines and self-study step 2 sent first-time
readers straight into it, even though the document says it exists for the
harness rather than for readers. It now splits by audience.

- docs/00-overview/checklist-mapping.md keeps its URL and becomes a 69-line
  summary: the two-standard comparison, the four requirement groups with the
  chapter that fills each, and why doing both together saves about 39%
- website/reference/requirements-matrix.md is new and holds the 31 per-item
  blocks verbatim, for the self-certification stage
- test-coverage.py reads the new path; the G-block structure it parses is
  unchanged, so [8/13] still finds 31 items
- iso-verifier, kwg-drift-checker, check-kwg-drift, harness-guide, the
  iso-18974 reference and the four conformance templates point at the matrix

Signed-off-by: Haksung Jang <haksung@sk.com>
The OpenChain self-certification questions only existed inside eight chapter
admonitions, so the document that calls itself canonical never carried them.
They now live once, next to the item each one belongs to.

- Every one of the 31 matrix blocks gains a certification question bullet
- The eight chapter admonitions keep the ISO section numbers and link to the
  matrix instead of restating the question text
- devsecops/iso-mapping drops the standard introduction and the registration
  procedure, both of which restate the conformance chapter, and is retitled
  so it no longer collides with ai-coding/iso-mapping in search
- 07-conformance section 6 keeps the recommended order and links out for the
  counts; the gap analysis section points at the matrix
- 03-policy links to 01-setup for the clone command instead of repeating it
- Stale ko-style baseline entries for the shrunk mapping file are dropped

Signed-off-by: Haksung Jang <haksung@sk.com>
The overview repeated the G1-G4 table and the 39% figure that the summary
page now carries, so a change to either had two places to land.

- The overview keeps a two-sentence orientation and links to the summary for
  the per-group chapter table and to the matrix for per-item detail
- The chapter CLAUDE.md reading order matches the split, and names the file
  that test-coverage.py parses

Signed-off-by: Haksung Jang <haksung@sk.com>
Seven places restated something another page already owned, and in one case
the same word carried two different scales on a single page.

- sbom-generation drops its own SBOM definition and links to sbom-101, which
  it already claims as the prerequisite
- The six AI coding tool pages replace the license list with a placeholder
  comment and a link, so a policy change lands in the rules template only
- sca keeps both complete workflows and gains a table of the three things
  that differ from the Quick CI/CD one, instead of restating the setup prose
- devsecops strategy renames its maturity ladder to levels 1-4, so "stage"
  now refers only to the AI coding 5-stage strategy on that page
- The training resource table gains a role column that ties it to section 3
- The data walkthrough in ai-security-review folds into a details block,
  leaving 329 lines of body
- pipeline-design points at the SCA page for the grype policy file

Signed-off-by: Haksung Jang <haksung@sk.com>
Chapter 08 split one task across five pages. The index already summarized
all four methods with short examples, so a reader who wanted to actually
apply anything had to open a second page, and the effect and limitation
of each method were stated twice.

The four method pages are folded into the index. Each method section now
carries the full content that used to live on its own page. The two long
artifacts, the complete SKILL.md and the complete workflow YAML, go into
<details> so they stay available without pushing the reading flow past
them.

Section 5 is gone. It promised detailed guidance in a claude-oss-policy-guard
project that does not exist, marked "in preparation", and the same promise
appeared again under next steps. Neither is a thing a reader can act on.

The license list in method 1 stays complete rather than becoming a
placeholder. It differs from the six tool pages cleaned up earlier: those
show where a config file goes, while this fence is the artifact a reader
pastes into their own CLAUDE.md, so removing the list would remove the
point of the section. Both the prose and the note keep the link to the
canonical classification page, and a comment at the top of the file records
that a category change now has to be applied in three places.

The four method headings get explicit anchor ids so the redirects and the
inbound link from agent-governance land on the right section rather than
the top of the page. The redirect plugin accepts an anchor in `to`, verified
by build.

check-redirects.py gained anchor handling. It compared the whole `to` value
against the sitemap, so any anchored redirect looked like a dangling one.
It now splits the fragment, checks the page against the sitemap, and then
checks that the anchor id actually exists in the built page, which
onBrokenAnchors does not cover for redirects.

check-redirects.py reports 28 removed URLs, 14 per locale, all covered.
Body outside <details> is 241 lines ko and 245 en, file total 396 and 404,
within the limits. verify.sh 13/13, build passes for ko and en.

Signed-off-by: Haksung Jang <haksung@sk.com>
Each sample page stitches two to seven deliverables into one document, and
the reader needs one of them at a time to compare against their own output.
Five of the seven pages had no table of contents, and the two that did
listed plain text rather than links.

- All seven pages, in both locales, list their deliverables as anchor links
- Every section heading carries an explicit id taken from its output-sample
  filename, so the anchor survives a title change and is the same in ko and en
- The gap analysis table in conformance now uses those ids instead of slugs
  generated from headings, which would have broken silently on a retitle
- The dependabot block in sbom-management-plan is yaml, not bash, fixed in
  output-sample so a regeneration keeps it
- The skill documents the table of contents rule, warns that
  sync-output-samples.sh runs output/ to output-sample/ and would overwrite
  the golden fixtures, and records that the English pages are hand-maintained

Signed-off-by: Haksung Jang <haksung@sk.com>
The chapter CLAUDE.md still pointed at a claude-oss-policy-guard project
for detailed implementation and called it "to be released". No such
repository exists. This is the same promise removed from the reader-facing
page, and it matters more here: a session working in this folder reads
this file as context, so it would go looking for a project that is not
there, or write documentation assuming it exists.

Detailed implementation now lives in index.md itself, so the next-steps
section says what actually follows the chapter: renewal, quarterly
allowlist review, rescanning on new CVEs, and the DevSecOps and AI coding
tracks for wider automation.

Adds a file-layout section recording that the four method pages were
merged into index.md, that the two long artifacts sit in <details>, and
that the old URLs redirect to the per-method anchors. The self-study path
now names those anchors so a reader of this file can jump straight to the
right section.

verify.sh 13/13.

Signed-off-by: Haksung Jang <haksung@sk.com>
customTheme.scss had grown to 2784 lines mixing tokens, layout and
components, which made any design change hard to scope. It is now an
entry file that @use-s eight partials, and the React Native fork
leftovers are gone.

The split is a pure move. Each partial holds a contiguous slice of the
original in its original order, so the cascade is unchanged. The built
CSS was normalised and compared before and after: 783 rules, identical
order, identical declarations, identical selector sets. The only textual
difference was the order of selectors inside four comma-separated groups,
which is semantically inert.

Deleted after confirming zero references, both in the sources and in the
built HTML:

- 44 unused custom properties (--toss-deep-*, --hero-bg, --home-hero-*,
  --home-feature-*, --logo, --tintColor and the rest)
- the blog rules left behind when K1 removed the blog instance
- RN-only blocks: the Native Code Required banner, Snack Player, the
  colour preview box, the component grid, the two-column code block,
  pill tabs and the code diff lines
- PlatformSupport and the six platform icons it alone imported
- seven unreferenced files under core/, the three get*Version helpers,
  the version banner and dropdown swizzles, versionsArchived.json
- snackPlayerInitializer.ts and its type declaration, neither of which
  was registered as a client module

Two things were deliberately left alone. The light-mode
`a:not([class*="Button"])` guard in _surfaces.scss still has the capital
B from React Native's naming, so it matches every homepage link and gives
the CTA buttons `display: block` instead of `inline-flex`. That is live
styling, not dead code, and changing it would move pixels, so it belongs
with the landing rework rather than here. `--home-button-primary` reads
like residue but has nine live references.

Meta copyright notices were judged per file rather than stripped. The
partials carry derived code and keep the MIT notice. The entry file was
written from scratch during the split and has none, so it carries a
project header instead.

Verified against the 40 baseline screenshots taken at the parent commit:
32 identical, 8 differing by under 0.1% in the Algolia spinner and a few
antialiasing pixels, none over tolerance. verify.sh 13/13, build clean.

Also drops the netlify.toml entry from .claudeignore, left dangling when
K1 deleted that file.

Signed-off-by: Haksung Jang <haksung@sk.com>
Design option A was approved at gate 3, with the current font kept
(Roboto for Latin, Pretendard for Korean). This lands its tokens plus the
five corrections the diagnosis called for.

Headings now carry weight, not just size. Every heading was 400, the same
as body text, so an h3 at 20px sat four pixels away from a paragraph and
read as one. h1 is 700, h2 through h4 are 600. Of the four reference
sites measured, all separate headings by weight or by size; this site did
neither.

The size tokens are rem instead of px, so a reader who enlarges their
browser font now gets larger text. Code blocks move from a line height of
1.4, the tightest of the four references, to 1.6. Corner radii become a
two-step scale.

The primary colour is split in two. #1a73e8 clears AA on white by 0.01,
so any tinted surface pushed it under: the landing card link measured
4.22:1 and the final CTA note 4.17:1. Text now uses #1967d2 (5.37:1 on
white, 4.86:1 on the tint) while #1a73e8 stays for large fills. The same
split fixes the sidebar active item, which sat at 4.10:1 on its own
highlight.

Three further contrast failures surfaced while measuring and are fixed:
the search shortcut keys (2.36:1), table headers (4.07:1), and the Hero
attribution line (4.39:1).

Hardcoded colours in the Hero, FinalCTA and WhyKwg modules now reference
tokens. The Hero secondary CTA gets an opaque background token: it was
translucent white over a gradient, which is why the diagnosis could not
put a number on it.

Measured after the change with text hidden so sampled pixels are true
background, not glyphs: 1202 text elements across nine screens, two
widths and both themes, none below AA. Lighthouse accessibility on the
landing goes 96 to 100 and colour-contrast passes on all four sampled
pages. Heading and code values match the option A spec exactly. No px
remains in the font size tokens. verify.sh 13/13, build clean.

Signed-off-by: Haksung Jang <haksung@sk.com>
index.scss was 788 lines of styling for the React Native homepage:
.HeaderHero, .GetStarted, .CrossPlatform, .FastRefresh, .NativeApps,
.VideoContent and the rest. None of those elements exist here. Every one
of its 37 top-level selectors was run through querySelectorAll on eight
real pages and matched nothing.

One rule in it was load-bearing and nearly went out with the rest:

    .homepage { width: 100%; max-width: 100%; }

.homepage is the landing page's wrapperClassName, and this overrides the
Infima container width so the Hero band reaches both edges. Deleting the
file first cost the landing its full bleed: the Hero measured left 20,
width 1400 in a 1440 viewport, leaving a 20px white gutter down each
side. That is exactly 40 pixels per row, which is what the pixel diff
reported before the cause was found. The rule now lives in
_surfaces.scss next to the other landing styles.

The normalised CSS diff is 102 rules out, 1 in, and the one added is byte
identical to one of the removed: the relocation, not a change. The other
101 are the dead marketing rules.

Checked against the 20 screenshots taken at the end of the previous
chunk: 18 identical, one differing in a 3x3 pixel patch, and the mobile
dark landing alternating between two renders on every load independently
of this change, confirmed by comparing the same build against itself and
by a 0 diff against a capture in the same state. Hero geometry back to
left 0, width 1440. verify.sh 13/13, build clean.

Signed-off-by: Haksung Jang <haksung@sk.com>
The Hero was a fixed dark navy band in both themes, so a reader in light
mode met a hard reversal between the first screen and the docs below it.
Its colours are now tokens that swap: a pale gradient with dark type in
light, the existing navy in dark. The terminal mock stays dark in both,
which is what a terminal looks like, and its surfaces are opaque now so
contrast can be measured rather than guessed at.

Two long-standing rules come out together, as they were one problem. The
light-mode `a:not([class*="Button"])` guard on .homepage carried React
Native's capital B, so it never excluded Docusaurus's lowercase
button--primary and applied `display: initial` from %link-style to every
landing anchor. That is why the Hero CTAs rendered as blocks instead of
flex. The guard is gone and `display: initial` is out of %link-style,
where its only remaining user was an inline `.markdown a` and it did
nothing. Landing links keep their hover underline from Infima.

While wiring the Hero tokens the same cascade trap appeared again: the
CTA colours were losing to a global dark-theme button rule, so the
tokens read correctly only because the values happened to agree. The CTA
selectors now outrank it, and the tokens actually decide.

Also here: a fourth track card for Reference, matching the four docs
instances in the navbar, with the grid at four columns and two on
narrow screens; width and height on the navbar logo; English
placeholders for the new card's strings.

Landing measured with the method from the previous chunk, text hidden so
sampled pixels are background: 112 elements across both widths and
themes, none below AA. The three the script flagged are .titleAccent,
whose gradient is painted through background-clip, so hiding the text
leaves the gradient in the glyphs and the sampler reads it as its own
background; every gradient stop clears 4.68:1 against the Hero.
Lighthouse accessibility 100, colour-contrast and unsized-images pass,
CLS 0. No horizontal overflow at 390px. verify.sh 13/13.

Signed-off-by: Haksung Jang <haksung@sk.com>
…body

The 404 was the stock Docusaurus page: no search, no links anywhere
except the footer, a title and a first paragraph saying the same thing
twice, and a heading copy button that belongs to documents. It now
carries a search box, the four instance links with a line each, and one
sentence. Its heading is a plain h1, not the Heading swizzle, so no copy
button appears.

The copy button also showed on the search results page, which is a theme
page rather than a document. The h1 branch of the Heading swizzle now
skips it there. Document pages keep theirs, eight on the SBOM chapter.

BoxLink and Badge join Term, Prerequisite and JourneyProgress in the
global MDX registration, so writers can use all five without an import.
Badge had fallen to zero references when PlatformSupport was deleted two
chunks ago; it resolves again.

Document bodies narrow to 740px, the width chosen with option A. The
column was 807px. Of the four sites measured during the diagnosis,
Stripe sits at 492, Astro 720, MDN 768 and web.dev 854, so this lands
between the two developer-documentation references. The cap is on the
article, so body, footer and pagination share one edge, and tables still
scroll inside it.

One thing had to move out of the theme namespace. The 404 title kept
rendering the old Korean string because Docusaurus ships its own
translations for `theme.*` ids, which override an inline default. These
strings are `notFound.*` now, and the English file follows.

Nine screens across two widths and both themes: no horizontal overflow
at 390px, and 36 captures taken for review. Lighthouse accessibility is
100 on all six configured URLs with colour-contrast passing. verify.sh
13/13, build clean.

Signed-off-by: Haksung Jang <haksung@sk.com>
The gate has been advisory since it was added: every assertion was a
warn, and the performance threshold of 0.9 was unreachable because the
CI serves the build directory without compression or cache headers, so
nobody could act on it. Accessibility, best practices and SEO become
error assertions, joined by unsized-images and font-display. The
performance category assertion is dropped in favour of two audits that
say something actionable: total blocking time and unused JavaScript,
both as warnings.

font-display was failing on the two Source Code Pro faces, the only ones
declared in CSS rather than through modules/fonts.ts, where Roboto and
Pretendard already set swap. Both now do too, and the audit passes.

The focus-visible polyfill is gone. Every rule in the codebase uses the
native :focus-visible selector, none the polyfill's class form, so it
was a CDN request for nothing. react-github-btn goes with it: a
dependency no file imports. Removing it keeps yarn install --immutable
green, which is what CI runs.

numberOfRuns rises to three. The reason was that the landing sat one
point above the accessibility threshold; it now scores 100, but run to
run variance is worth absorbing regardless.

Measured across all six configured URLs after the change: accessibility,
best practices and SEO all 100, unsized-images and font-display passing.
Blocking time stays under the 600ms warning on every page, the highest
being 265ms. Unused JavaScript is over the 100KiB warning everywhere,
between 130 and 477KiB, which is why it is a warning and not a gate.

The dark contrast step is deferred. It needs the page rendered with
prefers-color-scheme dark, and Lighthouse resets emulated media, so
--force-prefers-color-scheme=dark has no effect: its screenshot comes
back light. Doing it in CI would mean adding a browser automation
dependency, which is a supply chain decision rather than a gate tweak.
Dark is covered by the manual procedure instead, and the harness guide
now describes it correctly.

That guide had a warning worth acting on: switching data-theme by
attribute leaves code blocks at their light colours, because Prism needs
a React re-render. Confirmed: the pre background stays rgb(246,248,250).
Earlier chunks measured dark that way, so dark code blocks had never
actually been checked. Re-measured with the theme genuinely switched:
452 elements over nine screens, none below AA. The guide now gives
prefers-color-scheme emulation as the simpler route, and records the
contrast method and its background-clip exception.

Signed-off-by: Haksung Jang <haksung@sk.com>
The docs and reference instances still described the entry path the way it
worked before the overview was rebuilt.

- The overview and the quick start point at 01-setup for the clone command
  instead of repeating it, matching the Korean
- The tools index links to the quick start for the no-install demo
- The reference index links to the overview for the deliverable file list
- sbom-management step 6 gains the ls command and the note that myapp is only
  an example, which Korean already had
- The chapter 08 sidebar key becomes a doc key, since chunk K6 turned that
  category into a single document

Code blocks are identical to the Korean; only comments are translated. Fence
counts now match across every file in both instances.

Signed-off-by: Haksung Jang <haksung@sk.com>
English pages linked to /docs, /reference, /devsecops and /ai-coding without
a locale prefix. Docusaurus does not add one to a hardcoded absolute path, so
every one of those links dropped an English reader onto the Korean site.

All 275 are now /en/... across the four instances. External URLs, bare
anchors and image paths were out of scope and none were touched; no link
inside a code block was affected.

The English sample pages are edited directly because they are hand-maintained
translations, not output of the reference-samples skill, so a regeneration
cannot undo this.

Signed-off-by: Haksung Jang <haksung@sk.com>
The sidebar showed "개발자 가이드 (선택)" where every other chapter showed
its number, because front matter sidebar_label overrides the label set on
the sidebars.ts item. Chapter 07 renders "7. 자체 인증" from sidebars.ts;
chapter 08 was the only index carrying its own sidebar_label, so it lost
the "8." the sidebar config supplies.

The line predates this redesign, and chapters 01 through 07 have no
sidebar_label at all, so removing it matches the existing convention and
drops the duplicate label that had to be kept in sync by hand.

The English translation key already carried the number
("8. Developer Guide (Optional)"), so both locales pick it up once the
front matter stops winning. Verified by build: ko now renders
"8. 개발자 가이드 (선택)" and en "8. Developer Guide (Optional)".

The English counterpart of this change, removing the same front matter
line, landed in b7df0bb: that commit rewrote absolute links across the
English tree and touched this same file, so the one-line removal could not
be separated from it.

verify.sh 13/13.

Signed-off-by: Haksung Jang <haksung@sk.com>
The repository style forbids the em dash, and the English landing, glossary
tooltips and about page still used it as a clause separator.

- code.json: 14 strings reworded, covering the hero and track subtitles, the
  three showcase captions and the seven glossary tooltips
- about.md: the two contact bullets

The Korean source strings in website/src still carry em dashes, so the two
locales now differ in punctuation on these strings. Reported separately: the
body content of both locales uses the em dash heavily, and test-coverage.py
requires it in the requirements matrix headings, so a blanket sweep is not
safe and is out of scope here.

Signed-off-by: Haksung Jang <haksung@sk.com>
GitHub Pages serves one fallback file for anything missing: the root
404.html. build/en/404.html is generated correctly and is fine when
opened directly, but nothing ever routes a broken /en/ link to it. An
English reader following a dead link landed on a Korean page. Static
hosting gives no way to pick a fallback by path prefix, so the choice
has to happen in the browser.

It renders English in place rather than redirecting. The address stays
as the reader typed it, so they can see which link is broken, and there
is no redirect flash. The page also names the path it could not find.
The four cards point at /en/, so any of them leads into the English
site.

The English strings are inlined rather than translated. translate()
resolves at build time, and this decision has to happen at run time
inside the Korean bundle. The locale swap runs after mount so the first
client render still matches the server HTML.

lang and title needed Docusaurus's Head. Setting them on the DOM
directly appeared to work but did not survive: measured, the body turned
English while lang stayed ko and the title stayed Korean, because Helmet
reapplies both.

Verified against a running server, not just the build output, since the
files alone look fine either way. Four missing paths under /en/
(/en/no-such-page, /en/docs/does-not-exist,
/en/devsecops/broken-link-abc, /en/reference/samples/gone) all render
English with lang=en, an English title and the path shown. Missing paths
under / are unchanged, and /en/404 opened directly is untouched.

One limit worth stating: only the 404 content swaps. The navbar and
footer come from the Korean bundle and stay Korean on that page. Making
those English would mean rendering the whole app in another locale,
which the client cannot do. The English cards are the way out.

Signed-off-by: Haksung Jang <haksung@sk.com>
Merge-1 verification found the new script missing from CONTRIBUTING's
quick reference and harness-guide's script inventory, and the reference/
instance missing from CLAUDE.md's directory table after this redesign
moved agents.md there and added requirements-matrix.md.

Signed-off-by: Haksung Jang <haksung@sk.com>
eslint flags _config and isServer as unused, which fails ci:lint and
blocks the pull request. Neither is referenced in the function body.

The rule has been failing since before this redesign, but pre-merge.yml
only runs on pull requests and recent work landed directly on main, so
no run had exercised it.

Signed-off-by: Haksung Jang <haksung@sk.com>
@haksungjang
haksungjang merged commit 3b25695 into main Sep 3, 2026
6 checks passed
@haksungjang
haksungjang deleted the redesign-2026-09 branch September 3, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant