Files
ckochandClaude Opus 5 a99c8381b1 Disable critical-CSS inlining so the stylesheet survives the CSP
Angular's production build defers the main stylesheet with
`media="print" onload="this.media='all'"` and inlines a critical subset
ahead of it. The nginx CSP sets `script-src 'self'`, which blocks that
inline event handler — so the swap never ran and the stylesheet stayed
print-only. The app rendered from the ~23kB critical subset alone.

Most of the page still looked right, which is what made it easy to miss.
Material icons did not: `.material-icons` was not in the critical subset,
so every icon fell back to the body font and rendered its ligature name
("videogame_asset") clipped to the icon box.

`inlineCritical: false` emits a plain <link rel="stylesheet">. The
stylesheet is 24kB and same-origin, so the optimisation bought little and
cost correctness under a strict CSP.

Verified in headless Chromium: icons render as glyphs across the toolbar,
grid, editor and mobile layouts, and the console is now clean where it
previously logged four CSP violations per page load.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 10:45:46 -04:00

93 lines
2.5 KiB
JSON

{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "npm"
},
"newProjectRoot": "projects",
"projects": {
"ludos-web": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"browser": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"@fontsource/roboto/400.css",
"@fontsource/roboto/500.css",
"@fontsource/roboto/700.css",
"material-icons/iconfont/filled.css",
"src/styles.scss"
]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all",
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
}
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "ludos-web:build:production"
},
"development": {
"buildTarget": "ludos-web:build:development"
}
},
"defaultConfiguration": "development",
"options": {
"proxyConfig": "proxy.conf.json"
}
},
"test": {
"builder": "@angular/build:unit-test"
}
}
}
}
}