#!/usr/bin/env bash set -euo pipefail script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" repo_root="$(cd -- "${script_dir}/.." && pwd)" cd "${repo_root}" if ! command -v rg >/dev/null 2>&1; then echo "[ERROR] rg is required for css-contract-check." >&2 exit 2 fi failures=0 ok() { echo "[OK] $*" } fail() { echo "[FAIL] $*" >&2 failures=$((failures + 1)) } expected_layer_order='@layer tokens, vendor, layout, vendor-overrides, components, pages, utilities;' if rg -Fq "${expected_layer_order}" web/css/app-layers.css; then ok "Layer order declaration found in web/css/app-layers.css" else fail "Layer order declaration is missing or changed in web/css/app-layers.css" fi while IFS= read -r file; do expected_layer='' case "${file}" in web/css/base/*|modules/*/web/css/base/*) expected_layer='tokens' ;; web/css/layout/*|modules/*/web/css/layout/*) expected_layer='layout' ;; web/css/components/*|modules/*/web/css/components/*) expected_layer='components' ;; web/css/pages/*|modules/*/web/css/pages/*) expected_layer='pages' ;; web/css/vendor-overrides/*|modules/*/web/css/vendor-overrides/*) expected_layer='vendor-overrides' ;; esac if [[ -z "${expected_layer}" ]]; then continue fi if [[ "${file}" == "web/css/pages/app-error.css" || "${file}" == "web/css/pages/app-error-debug.css" ]]; then continue fi detected_layer="$(sed -n '1,120p' "${file}" | sed -nE 's/.*@layer[[:space:]]+([^[:space:]{]+).*/\1/p' | head -n1)" if [[ -z "${detected_layer}" ]]; then fail "${file}: missing @layer declaration near file top" continue fi if [[ "${detected_layer}" != "${expected_layer}" ]]; then fail "${file}: @layer ${detected_layer} does not match expected ${expected_layer}" fi done < <(rg --files web/css modules | rg '\.css$') remote_import_pattern='@import[[:space:]]+url\(["'"'"']?(https?:)?//|@import[[:space:]]+["'"'"']?(https?:)?//' remote_hits="$(rg -n -g '*.css' -e "${remote_import_pattern}" web/css modules || true)" if [[ -n "${remote_hits}" ]]; then fail "Remote CSS import detected (must vendor locally):" echo "${remote_hits}" >&2 else ok "No remote CSS imports detected" fi if [[ ! -f web/css/core.css ]]; then fail "web/css/core.css is missing" else first_import="$(rg -n '^@import' web/css/core.css | head -n1 || true)" if [[ "${first_import}" == *'app-layers.css'* ]]; then ok "web/css/core.css imports app-layers.css first" else fail "web/css/core.css must import app-layers.css as first @import" fi fi if [[ "${failures}" -gt 0 ]]; then echo "[FAIL] CSS contract check failed with ${failures} issue(s)." >&2 exit 1 fi echo "[OK] CSS contract check passed."