feat(website): follow the system dark mode and fix small-screen text (#1894)
* fix(website): keep text inside small screens and tidy small type and spacing From a layout audit of the built pages: - Long terminal prompts and code-header buttons wrap instead of being cut off at 320px (WCAG 1.4.10). - Headings and table cells break long words, so the 1.4.12 text-spacing test no longer widens pages past 320px. - Header and footer links get a 24px minimum height (2.5.8). - Labels that rendered under 12px now render at 12px or more, and inline code never drops under 0.75rem. - The home page's hero and definition rows share one column gap and align on the first baseline, and stacked boxes share one corner size. - Highlight chips get room around the text, and the active run in a step listing is one band instead of a box per line. Colors are unchanged. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * feat(website): follow the system dark mode The site was light only, so a reader with a dark system still got a white page. Add one prefers-color-scheme: dark block to the stylesheet that swaps the six color variables to Catppuccin Mocha (MIT) and overrides the fixed colors that would break on a dark page: selection, buttons, tinted highlights, flow nodes and arrows, and a visible border on the agent terminal. Add a dark theme-color tag beside the light one in the page template and the 17 pages, and a Dark column to the style guide's color table. Light colors are unchanged. The SVG figures follow in the next commit; the blog page's inline strokes, the dinosaur game and the social card are left as they are. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * feat(website): give the five SVG figures a dark scheme Pages load the figures with <img>, so page CSS cannot reach inside them. Each figure now carries its own @media (prefers-color-scheme: dark) block of attribute-selector overrides that map every light color to a Catppuccin Mocha color, with one shared map across all five. No markup, labels, shapes or positions change, and nothing uses !important. Four figures also paint a mantle canvas so "Open figure" works on its own; analyst-thinking.svg stays transparent, since it sits on the page rather than in a figure box. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * chore(website): refresh translation source references The theme-color tags move the page lines that the catalogs cite, so python3 scripts/website.py translations extract rewrites the source references in messages.pot and the 18 PO files. No message text changes. The same run moves the "Main navigation" entry to its new position in each catalog. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * fix(website): keep inline step highlights inline The full-width band for the active step now applies only to code-step blocks. The inline parameter highlights in the dx-ball and th04 signatures stay inline again. 🤖 Generated with Claude Code (Opus 5.5) 🦊 * test(website): check every page offers light and dark theme colors Each authored reading page, and its built copy in every language, must carry one theme-color tag for light and one for dark. The stylesheet must keep its dark color scheme block. On the commit before dark mode, this test fails on every page. 🤖 Generated with Claude Code (Opus 5.5) 🦊 * fix(website): draw the dinosaur game in the page colors In dark mode the game box turned dark, but the game still drew with its light colors, so the dinosaur, cacti and text fell to about 2:1 contrast. The canvas now reads five colors from CSS variables on .dino-stage. Light values are the old ones, so light mode draws the same pixels. Dark values are Catppuccin Mocha: 8.3:1 for the dinosaur, 7.9:1 for cacti and text, 7.6:1 for the crash color. The moved lines in dino-demo.js shift the translation catalog references, so the catalogs are refreshed too (reference comments only). 🤖 Generated with Claude Code (Opus 5.5) 🦊 * fix(website): recolor the Touhou flywheel arrows in dark mode The inline flywheel SVG on the Touhou article hard-codes its stroke colors, so on the dark page its connectors fell to about 2:1. Two dark-only rules map those strokes to the page accent and muted colors (7.8:1 and 7.4:1). Light mode is unchanged. 🤖 Generated with Claude Code (Opus 5.5) 🦊 * fix(website): redraw the dinosaur game when the system theme changes The canvas reads its colors only when it draws, so an idle, paused or crashed game kept the old palette after a theme switch. Each demo now redraws on a prefers-color-scheme change. The added lines shift the translation catalog references, so the catalogs are refreshed too (reference comments only). 🤖 Generated with Claude Code (Opus 5.5) 🦊 --------- Co-authored-by: Claude Sonnet 5.5 <sonnet@cassie-pc> Co-authored-by: Claude Opus 5.5 <opus@cassie-pc>
@@ -401,6 +401,22 @@ class WebsiteTranslationChecks(unittest.TestCase):
|
||||
server.shutdown()
|
||||
worker.join()
|
||||
|
||||
def test_every_reading_page_offers_light_and_dark_theme_colors(self):
|
||||
site = ROOT / "website/_site"
|
||||
english_pages = reading_pages(ROOT / "website/public")
|
||||
self.assertTrue(english_pages)
|
||||
for language in languages(ROOT):
|
||||
code = language["code"]
|
||||
for original in english_pages:
|
||||
relative = original.relative_to(ROOT / "website/public")
|
||||
for path in {original, site / relative if code == "en" else site / code / relative}:
|
||||
with self.subTest(language=code, page=str(path.relative_to(ROOT))):
|
||||
doc = Document(path.read_text())
|
||||
media = sorted(node.attrs.get("media") for node in doc.nodes if node.tag == "meta" and node.attrs.get("name") == "theme-color")
|
||||
self.assertEqual(media, ["(prefers-color-scheme: dark)", "(prefers-color-scheme: light)"])
|
||||
styles = (ROOT / "website/public/assets/styles.css").read_text()
|
||||
self.assertTrue("@media (prefers-color-scheme: dark)" in styles, "styles.css has no dark color scheme block")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -33,9 +33,13 @@ function initializeDinoDemo(demo) {
|
||||
slider.value = speed.toFixed(1);
|
||||
};
|
||||
|
||||
const color = (name, fallback) =>
|
||||
getComputedStyle(canvas).getPropertyValue(name).trim() || fallback;
|
||||
|
||||
const draw = () => {
|
||||
const ink = color("--dino-ink", "#5b6570");
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
context.strokeStyle = "#b7c0c9";
|
||||
context.strokeStyle = color("--dino-ground", "#b7c0c9");
|
||||
context.beginPath();
|
||||
context.moveTo(0, ground);
|
||||
context.lineTo(canvas.width, ground);
|
||||
@@ -44,7 +48,7 @@ function initializeDinoDemo(demo) {
|
||||
context.lineTo(x + 12, ground + 7);
|
||||
}
|
||||
context.stroke();
|
||||
context.fillStyle = "#5b6570";
|
||||
context.fillStyle = ink;
|
||||
for (const obstacle of obstacles) {
|
||||
context.fillRect(
|
||||
obstacle.x + 6,
|
||||
@@ -59,12 +63,14 @@ function initializeDinoDemo(demo) {
|
||||
}
|
||||
context.save();
|
||||
context.translate(dinosaurX, ground - 59 - height);
|
||||
context.fillStyle = crashed ? "#8c4b40" : "#294f82";
|
||||
context.fillStyle = crashed
|
||||
? color("--dino-crash", "#8c4b40")
|
||||
: color("--dino-player", "#294f82");
|
||||
context.fill(dinosaur);
|
||||
context.fillStyle = "#ffffff";
|
||||
context.fillStyle = color("--dino-eye", "#ffffff");
|
||||
context.fillRect(39, 7, 4, 4);
|
||||
context.restore();
|
||||
context.fillStyle = "#5b6570";
|
||||
context.fillStyle = ink;
|
||||
context.font = "13px monospace";
|
||||
context.textAlign = "right";
|
||||
context.fillText(
|
||||
@@ -218,6 +224,9 @@ function initializeDinoDemo(demo) {
|
||||
stop(t("Paused. Press Play to continue."));
|
||||
}).observe(demo);
|
||||
}
|
||||
window
|
||||
.matchMedia("(prefers-color-scheme: dark)")
|
||||
.addEventListener("change", draw);
|
||||
demo.querySelector(".dino-fallback").setAttribute("hidden", "");
|
||||
demo.querySelector(".dino-controls").hidden = false;
|
||||
canvas.hidden = false;
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 120" fill="none">
|
||||
<title>An analyst thinking at a computer</title>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark){
|
||||
[stroke="#294f82"]{stroke:#89b4fa}
|
||||
[fill="#5b6570"]{fill:#a6adc8}
|
||||
[stroke="#5b6570"]{stroke:#a6adc8}
|
||||
[stroke="#e0e5e9"]{stroke:#45475a}
|
||||
[fill="#edf2f8"]{fill:#313244}
|
||||
[fill="#f4f6f8"]{fill:#1e1e2e}
|
||||
[fill="#fff"]{fill:#181825}
|
||||
}
|
||||
</style>
|
||||
<g stroke="#5b6570" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 101h136" stroke="#e0e5e9" />
|
||||
<path d="M24 54h38l-6 35H18z" fill="#f4f6f8" />
|
||||
|
||||
|
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 1.1 KiB |
@@ -2,6 +2,23 @@
|
||||
<title id="title">One check reveals one character</title>
|
||||
<desc id="desc">The seventh mask selects only position 21 in the six by six input grid. Its character code must equal 55, so the character is 7. The other masks select different positions and give further equations.</desc>
|
||||
<defs><marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#8191a2"/></marker></defs>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark){
|
||||
svg{background-color:#181825}
|
||||
[fill="#20252b"]{fill:#cdd6f4}
|
||||
[fill="#294f82"]{fill:#89b4fa}
|
||||
[stroke="#294f82"]{stroke:#89b4fa}
|
||||
[fill="#5b6570"]{fill:#a6adc8}
|
||||
[fill="#7a8490"]{fill:#9399b2}
|
||||
[fill="#8191a2"]{fill:#7f849c}
|
||||
[stroke="#8191a2"]{stroke:#7f849c}
|
||||
[stroke="#e0e5e9"]{stroke:#45475a}
|
||||
[fill="#edf2f8"]{fill:#313244}
|
||||
[fill="#f4f6f8"]{fill:#1e1e2e}
|
||||
[fill="#fafbfc"]{fill:#11111b}
|
||||
[fill="#ffffff"]{fill:#181825}
|
||||
}
|
||||
</style>
|
||||
<rect width="760" height="475" fill="#ffffff"/>
|
||||
<g font-family="system-ui, -apple-system, sans-serif" font-size="14" fill="#20252b">
|
||||
<text x="32" y="36" font-size="19" font-weight="600">One check reveals one character</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -4,6 +4,17 @@
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="14" markerHeight="14" refX="11" refY="7" orient="auto" markerUnits="userSpaceOnUse"><path d="M1 1 L11 7 L1 13 Z" fill="#5b6570"/></marker>
|
||||
</defs>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark){
|
||||
svg{background-color:#181825}
|
||||
[fill="#20252b"]{fill:#cdd6f4}
|
||||
[fill="#294f82"]{fill:#89b4fa}
|
||||
[fill="#5b6570"]{fill:#a6adc8}
|
||||
[stroke="#5b6570"]{stroke:#a6adc8}
|
||||
[stroke="#6c7e8b"]{stroke:#7f849c}
|
||||
[fill="#ffffff"]{fill:#181825}
|
||||
}
|
||||
</style>
|
||||
<rect width="1774" height="887" fill="#ffffff"/>
|
||||
<g font-family="Arial, Helvetica, sans-serif" fill="#20252b">
|
||||
<text x="40" y="166" font-size="63" font-weight="700">DX-Ball sound-pan investigation</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -5,6 +5,18 @@
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto-start-reverse" markerUnits="userSpaceOnUse"><path d="M1 1 L8 5 L1 9" fill="none" stroke="#5b6570" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></marker>
|
||||
<marker id="blue-arrow" markerWidth="12" markerHeight="12" refX="9" refY="6" orient="auto" markerUnits="userSpaceOnUse"><path d="M1 1 L9 6 L1 11" fill="none" stroke="#294f82" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></marker>
|
||||
</defs>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark){
|
||||
svg{background-color:#181825}
|
||||
[fill="#20252b"]{fill:#cdd6f4}
|
||||
[fill="#294f82"]{fill:#89b4fa}
|
||||
[stroke="#294f82"]{stroke:#89b4fa}
|
||||
[fill="#5b6570"]{fill:#a6adc8}
|
||||
[stroke="#5b6570"]{stroke:#a6adc8}
|
||||
[stroke="#87929e"]{stroke:#7f849c}
|
||||
[fill="#ffffff"]{fill:#181825}
|
||||
}
|
||||
</style>
|
||||
<rect width="1774" height="887" fill="#ffffff"/>
|
||||
<g font-family="Arial, Helvetica, sans-serif" fill="#20252b">
|
||||
<text x="40" y="96" font-size="68" font-weight="700">REA investigation flow</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.5 KiB |
@@ -2,7 +2,23 @@
|
||||
<title id="title">TH04: spacing and aiming a ring of bullets</title>
|
||||
<desc id="description">A full clockwise turn has 256 angle units. Sixteen bullets start at angles zero, sixteen, thirty-two, through 240. Adding an example player direction of forty turns all sixteen directions together; the first bullet points at the player. Template rotation is zero.</desc>
|
||||
<defs><marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#294f82" /></marker></defs>
|
||||
<style>text { font-family: Arial, Helvetica, sans-serif; fill: #20252b; } .heading { font-size: 26px; font-weight: 600; } .note { font-size: 19px; fill: #5b6570; } .mono { font-family: Consolas, 'Liberation Mono', monospace; font-size: 19px; } .accent { fill: #294f82; } .spoke { stroke: #d2dbe4; stroke-width: 1.6; } .bullet { fill: #9eafc0; } .first { fill: #294f82; } </style>
|
||||
<style>text { font-family: Arial, Helvetica, sans-serif; fill: #20252b; } .heading { font-size: 26px; font-weight: 600; } .note { font-size: 19px; fill: #5b6570; } .mono { font-family: Consolas, 'Liberation Mono', monospace; font-size: 19px; } .accent { fill: #294f82; } .spoke { stroke: #d2dbe4; stroke-width: 1.6; } .bullet { fill: #9eafc0; } .first { fill: #294f82; }
|
||||
@media (prefers-color-scheme: dark){
|
||||
svg{background-color:#181825}
|
||||
[fill="#20252b"]{fill:#cdd6f4}
|
||||
[fill="#294f82"]{fill:#89b4fa}
|
||||
[stroke="#294f82"]{stroke:#89b4fa}
|
||||
[stroke="#e0e5ea"]{stroke:#45475a}
|
||||
[fill="#edf2f8"]{fill:#313244}
|
||||
[fill="#ffffff"]{fill:#181825}
|
||||
text{fill:#cdd6f4}
|
||||
.note{fill:#a6adc8}
|
||||
.accent{fill:#89b4fa}
|
||||
.spoke{stroke:#6c7086}
|
||||
.bullet{fill:#9399b2}
|
||||
.first{fill:#89b4fa}
|
||||
}
|
||||
</style>
|
||||
<rect width="1000" height="520" fill="#ffffff" />
|
||||
<line x1="500" y1="42" x2="500" y2="428" stroke="#e0e5ea" />
|
||||
<text x="42" y="58" class="heading">Fixed ring</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.3 KiB |
@@ -51,7 +51,7 @@ pre {
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
code {
|
||||
font-size: 0.9em;
|
||||
font-size: max(0.9em, 0.75rem);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
span[translate="no"] {
|
||||
@@ -77,9 +77,14 @@ kbd {
|
||||
p {
|
||||
margin: 0 0 1.2rem;
|
||||
}
|
||||
th,
|
||||
td {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
overflow-wrap: break-word;
|
||||
line-height: 1.14;
|
||||
font-weight: 650;
|
||||
letter-spacing: -0.035em;
|
||||
@@ -236,7 +241,7 @@ section[id] {
|
||||
}
|
||||
.brand-caption {
|
||||
color: var(--muted);
|
||||
font-size: 0.875rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.navigation {
|
||||
display: flex;
|
||||
@@ -247,6 +252,9 @@ section[id] {
|
||||
gap: 0.65rem 1.4rem;
|
||||
}
|
||||
.navigation a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
@@ -322,7 +330,7 @@ section[id] {
|
||||
}
|
||||
.eyebrow {
|
||||
margin-bottom: 1.2rem;
|
||||
font-size: 0.875rem;
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
.hero {
|
||||
@@ -385,8 +393,8 @@ section[id] {
|
||||
.home-definition {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 3rem;
|
||||
align-items: start;
|
||||
gap: 3.5rem;
|
||||
align-items: baseline;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.home-definition h2,
|
||||
@@ -493,8 +501,8 @@ section[id] {
|
||||
.home-try-grid p {
|
||||
color: var(--muted);
|
||||
}
|
||||
.home-analysis-terminal {
|
||||
margin: 0 0 0.9rem;
|
||||
.agent-terminal.home-analysis-terminal {
|
||||
margin-block: 1rem;
|
||||
}
|
||||
.terminal-target {
|
||||
margin: 1rem 1.4rem 0;
|
||||
@@ -508,7 +516,7 @@ section[id] {
|
||||
}
|
||||
.agent-reply .reply-label {
|
||||
color: var(--accent);
|
||||
font-size: 0.8rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.agent-reply > :last-child {
|
||||
@@ -530,7 +538,7 @@ section[id] {
|
||||
margin-block: 1rem;
|
||||
}
|
||||
.home-setup .code-inline {
|
||||
margin-block: 0.5rem 0.8rem;
|
||||
margin-block: 1rem;
|
||||
}
|
||||
.home-setup > .caption {
|
||||
margin-bottom: 0;
|
||||
@@ -544,13 +552,15 @@ section[id] {
|
||||
}
|
||||
.code-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
overflow-wrap: anywhere;
|
||||
padding: 0.6rem 1rem;
|
||||
border-bottom: 1px solid var(--line);
|
||||
color: var(--muted);
|
||||
font-size: 0.875rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.copy-button {
|
||||
padding: 0.15rem 0.45rem;
|
||||
@@ -558,7 +568,7 @@ section[id] {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
font-size: 0.875rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.copy-button:hover {
|
||||
background: #e5e9ee;
|
||||
@@ -687,6 +697,9 @@ pre code {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
.footer-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
color: var(--muted);
|
||||
}
|
||||
.page-heading {
|
||||
@@ -838,7 +851,7 @@ pre code {
|
||||
.flywheel-node .flywheel-kicker {
|
||||
margin: 0 0 0.4rem;
|
||||
color: var(--accent);
|
||||
font-size: 0.6875rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.09em;
|
||||
text-transform: uppercase;
|
||||
@@ -943,14 +956,14 @@ pre code {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.flywheel-node .flywheel-kicker {
|
||||
font-size: 0.6rem;
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.flywheel-center {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.flywheel-retry {
|
||||
font-size: 0.625rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.flywheel-projects {
|
||||
gap: 1rem;
|
||||
@@ -1099,6 +1112,11 @@ pre code {
|
||||
box-decoration-break: clone;
|
||||
-webkit-box-decoration-break: clone;
|
||||
}
|
||||
.step-comparison pre .code-step.is-active {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.step-detail {
|
||||
margin-block: 1.1rem;
|
||||
padding-left: 1rem;
|
||||
@@ -1302,7 +1320,7 @@ pre code {
|
||||
margin-block: 1.5rem;
|
||||
overflow: hidden;
|
||||
border: 1px solid #303d4a;
|
||||
border-radius: 6px;
|
||||
border-radius: 5px;
|
||||
background: #202933;
|
||||
color: #f1f4f8;
|
||||
}
|
||||
@@ -1340,6 +1358,7 @@ pre code {
|
||||
}
|
||||
.agent-terminal .terminal-prompt {
|
||||
margin: 0;
|
||||
overflow-wrap: anywhere;
|
||||
padding: 1.4rem;
|
||||
color: #f1f4f8;
|
||||
font-family: var(--font-mono);
|
||||
@@ -1661,7 +1680,7 @@ pre code {
|
||||
.home-expert-shortcut {
|
||||
margin-block: 1.5rem 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.home-expert-shortcut a {
|
||||
white-space: normal;
|
||||
@@ -1719,7 +1738,7 @@ pre code {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
gap: 3.5rem;
|
||||
align-items: center;
|
||||
align-items: baseline;
|
||||
}
|
||||
.home-start-grid h1 {
|
||||
font-size: clamp(2.8rem, 5vw, 4.2rem);
|
||||
@@ -1730,6 +1749,7 @@ pre code {
|
||||
margin-bottom: 0.7rem;
|
||||
}
|
||||
.home-start-grid .home-setup > p {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
@@ -1747,8 +1767,8 @@ pre code {
|
||||
color: var(--muted);
|
||||
}
|
||||
.prose-highlight {
|
||||
padding: 0.04em 0.16em;
|
||||
border-radius: 2px;
|
||||
padding: 0.08em 0.35em;
|
||||
border-radius: 4px;
|
||||
background: #e4ecf5;
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
@@ -1847,10 +1867,11 @@ pre code {
|
||||
.expert-step-selector button {
|
||||
min-height: 44px;
|
||||
padding: 0.6rem 0.4rem;
|
||||
border-radius: 5px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.expert-step-selector button span {
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.expert-analysis-grid {
|
||||
display: grid;
|
||||
@@ -1863,8 +1884,8 @@ pre code {
|
||||
margin: 0;
|
||||
}
|
||||
.expert-assembly .code-header {
|
||||
padding: 0.7rem 0.8rem;
|
||||
font-size: 0.7rem;
|
||||
padding: 0.9rem 1rem;
|
||||
font-size: 0.75rem;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
}
|
||||
@@ -1886,7 +1907,7 @@ pre code {
|
||||
.expert-assembly pre {
|
||||
margin: 0;
|
||||
padding: 0.8rem;
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.assembly-omission {
|
||||
@@ -1894,7 +1915,6 @@ pre code {
|
||||
}
|
||||
.expert-reasoning {
|
||||
min-width: 0;
|
||||
padding-top: 0.1rem;
|
||||
}
|
||||
.expert-thought {
|
||||
position: relative;
|
||||
@@ -1928,13 +1948,13 @@ pre code {
|
||||
}
|
||||
.expert-thought > p {
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.65;
|
||||
}
|
||||
.expert-thought > .thought-label {
|
||||
margin-bottom: 0.6rem;
|
||||
color: var(--accent);
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.expert-thought > .expert-task {
|
||||
@@ -1948,7 +1968,7 @@ pre code {
|
||||
margin: 0.9rem 0 0;
|
||||
padding-top: 0.8rem;
|
||||
border-top: 1px solid var(--line);
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.expert-facts div {
|
||||
display: flex;
|
||||
@@ -1983,13 +2003,13 @@ pre code {
|
||||
.expert-caption {
|
||||
margin: 0.5rem 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.65rem;
|
||||
font-size: 0.75rem;
|
||||
text-align: right;
|
||||
}
|
||||
.manual-work-summary {
|
||||
margin: 1rem 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.manual-work-summary strong {
|
||||
font-weight: 500;
|
||||
@@ -1998,7 +2018,7 @@ pre code {
|
||||
margin: 1.2rem 0 0.3rem;
|
||||
color: var(--accent);
|
||||
font-size: clamp(1.8rem, 3vw, 2.5rem);
|
||||
font-weight: 600;
|
||||
font-weight: 650;
|
||||
letter-spacing: -0.045em;
|
||||
}
|
||||
.agent-intro {
|
||||
@@ -2037,7 +2057,7 @@ pre code {
|
||||
.agent-evidence-roles dd {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.agent-investigation-note {
|
||||
color: var(--muted);
|
||||
@@ -2184,6 +2204,11 @@ pre code {
|
||||
gap: 2.5rem;
|
||||
}
|
||||
.dino-stage {
|
||||
--dino-ground: #b7c0c9;
|
||||
--dino-ink: #5b6570;
|
||||
--dino-player: #294f82;
|
||||
--dino-crash: #8c4b40;
|
||||
--dino-eye: #ffffff;
|
||||
overflow: hidden;
|
||||
margin-block: 0.8rem;
|
||||
background: var(--soft);
|
||||
@@ -2328,7 +2353,7 @@ pre code {
|
||||
text-align: left;
|
||||
}
|
||||
.expert-step-selector button {
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.expert-step-selector button span {
|
||||
display: block;
|
||||
@@ -2561,6 +2586,98 @@ pre code {
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
--ink: #cdd6f4;
|
||||
--muted: #a6adc8;
|
||||
--line: #45475a;
|
||||
--soft: #181825;
|
||||
--accent: #89b4fa;
|
||||
--page: #1e1e2e;
|
||||
}
|
||||
::selection {
|
||||
background: #45475a;
|
||||
}
|
||||
.dino-stage {
|
||||
--dino-ground: #45475a;
|
||||
--dino-ink: #a6adc8;
|
||||
--dino-player: #89b4fa;
|
||||
--dino-crash: #f38ba8;
|
||||
--dino-eye: #181825;
|
||||
}
|
||||
.reconstruction-flywheel [stroke="#294f82"] {
|
||||
stroke: var(--accent);
|
||||
}
|
||||
.reconstruction-flywheel [stroke="#5b6570"] {
|
||||
stroke: var(--muted);
|
||||
}
|
||||
.skip-link,
|
||||
.button,
|
||||
.dino-buttons .button {
|
||||
color: var(--page);
|
||||
}
|
||||
.button {
|
||||
border-color: #bac2de;
|
||||
background: #bac2de;
|
||||
}
|
||||
.button:hover {
|
||||
border-color: #a6adc8;
|
||||
background: #a6adc8;
|
||||
}
|
||||
.code-key,
|
||||
.notion-channel,
|
||||
.prose-highlight,
|
||||
.step-selector button[aria-pressed="true"],
|
||||
.percent-operation button[aria-pressed="true"],
|
||||
.flow-result,
|
||||
.home-nav-links a[aria-current="location"] {
|
||||
background: #313244;
|
||||
}
|
||||
.copy-button:hover {
|
||||
background: #313244;
|
||||
}
|
||||
.step-comparison .is-active {
|
||||
background: #313244;
|
||||
color: #b4befe;
|
||||
}
|
||||
.article p,
|
||||
.article li,
|
||||
.guide-route span {
|
||||
color: #bac2de;
|
||||
}
|
||||
.prompt {
|
||||
border-left-color: #585b70;
|
||||
}
|
||||
.agent-terminal {
|
||||
border-color: var(--line);
|
||||
background: #181825;
|
||||
}
|
||||
.terminal-header {
|
||||
border-bottom-color: #313244;
|
||||
}
|
||||
.agent-terminal .copy-button:hover {
|
||||
background: #313244;
|
||||
}
|
||||
.agent-one-prompt {
|
||||
color: var(--ink);
|
||||
}
|
||||
.workflow-figure {
|
||||
background: var(--soft);
|
||||
}
|
||||
.flow-node {
|
||||
background: #313244;
|
||||
border-color: #585b70;
|
||||
}
|
||||
.flow-steps li:not(:last-child)::after,
|
||||
.notion-mini-flow li:not(:last-child)::after {
|
||||
color: #9399b2;
|
||||
}
|
||||
.percent-controls .percent-key {
|
||||
border-color: #585b70;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.stats,
|
||||
.case-stats {
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../assets/styles.css" />
|
||||
<script src="../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../assets/styles.css" />
|
||||
<script src="../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../assets/styles.css" />
|
||||
<script src="../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../assets/styles.css" />
|
||||
<script src="../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../assets/styles.css" />
|
||||
<script src="../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="assets/styles.css" />
|
||||
<script src="assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../assets/styles.css" />
|
||||
<script src="../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||||
/>
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||||
<script src="../../assets/main.js" defer></script>
|
||||
|
||||
@@ -219,14 +219,20 @@ display size; scaling small labels down is not a mobile layout.
|
||||
|
||||
The shared stylesheet defines the site. Its core colors are:
|
||||
|
||||
| Token | Value | Use |
|
||||
| ---------- | --------- | -------------------------------- |
|
||||
| `--page` | `#ffffff` | Page background |
|
||||
| `--ink` | `#20252b` | Main text |
|
||||
| `--muted` | `#5b6570` | Secondary text |
|
||||
| `--line` | `#e0e5e9` | Section and component boundaries |
|
||||
| `--soft` | `#f4f6f8` | Code and supporting surfaces |
|
||||
| `--accent` | `#294f82` | Links and meaningful highlights |
|
||||
| Token | Light | Dark | Use |
|
||||
| ---------- | --------- | --------- | -------------------------------- |
|
||||
| `--page` | `#ffffff` | `#1e1e2e` | Page background |
|
||||
| `--ink` | `#20252b` | `#cdd6f4` | Main text |
|
||||
| `--muted` | `#5b6570` | `#a6adc8` | Secondary text |
|
||||
| `--line` | `#e0e5e9` | `#45475a` | Section and component boundaries |
|
||||
| `--soft` | `#f4f6f8` | `#181825` | Code and supporting surfaces |
|
||||
| `--accent` | `#294f82` | `#89b4fa` | Links and meaningful highlights |
|
||||
|
||||
The light values are the default. When the reader's system is set to dark, a
|
||||
`prefers-color-scheme: dark` block at the end of the stylesheet swaps in the dark
|
||||
values, which are [Catppuccin Mocha](https://github.com/catppuccin/palette)
|
||||
(MIT). There is no toggle. Any new fixed color needs a dark counterpart in
|
||||
that block.
|
||||
|
||||
Use the system sans-serif stack for prose and the shared monospace stack for
|
||||
code. The current container is at most 1080px wide, with article text limited to
|
||||
|
||||
@@ -8,7 +8,16 @@
|
||||
<meta name="robots" content="noindex" />
|
||||
<!-- website:sharing:start -->
|
||||
<!-- website:sharing:end -->
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#ffffff"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#1e1e2e"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<link rel="icon" href="${base}assets/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="${base}assets/styles.css" />
|
||||
<script src="${base}assets/main.js" defer></script>
|
||||
|
||||