diff --git a/.gitignore b/.gitignore index eb65529..4647a53 100644 --- a/.gitignore +++ b/.gitignore @@ -131,4 +131,8 @@ dmypy.json .idea/ # Additional files from existing .gitignore -.envrc \ No newline at end of file +.envrc + +# Tailwind CSS generated artifacts +style.css +tailwindcss \ No newline at end of file diff --git a/build-css.sh b/build-css.sh new file mode 100755 index 0000000..b2260ab --- /dev/null +++ b/build-css.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -euo pipefail + +# Build CSS using Tailwind CSS standalone CLI +# For local development, run: +# ./build-css.sh # one-off build +# ./build-css.sh --watch # watch mode + +version="v3.4.17" +os="$(uname -s)" +arch="$(uname -m)" + +case "$os" in + Linux*) platform="linux";; + Darwin*) platform="macos";; + *) echo "Unsupported OS: $os"; exit 1;; +esac + +case "$arch" in + x86_64) arch="x64";; + arm64) arch="arm64";; + aarch64) arch="arm64";; + *) echo "Unsupported architecture: $arch"; exit 1;; +esac + +binary="tailwindcss-${platform}-${arch}" +url="https://github.com/tailwindlabs/tailwindcss/releases/download/${version}/${binary}" + +if [ ! -f "tailwindcss" ]; then + echo "Downloading Tailwind CSS standalone CLI (${version} ${platform}/${arch})..." + curl -sL "$url" -o tailwindcss + chmod +x tailwindcss +fi + +if [ "${1:-}" == "--watch" ]; then + echo "Building CSS in watch mode..." + ./tailwindcss -i ./style-input.css -o ./style.css --watch +else + echo "Building CSS..." + ./tailwindcss -i ./style-input.css -o ./style.css --minify +fi diff --git a/main.py b/main.py index 2d25ee8..6adc5dc 100644 --- a/main.py +++ b/main.py @@ -335,8 +335,8 @@ async def read_root(): ) csp = ( "default-src 'self'; " - f"script-src 'self' 'nonce-{nonce}' https://cdn.jsdelivr.net; " - "style-src 'self' https://cdn.jsdelivr.net; " + f"script-src 'self' 'nonce-{nonce}'; " + "style-src 'self'; " "connect-src 'self' https://login.infomaniak.com https://api.coingecko.com; " "img-src 'self'; " "object-src 'none'; " @@ -389,6 +389,11 @@ async def favicon(): """Serve the favicon""" return FileResponse("templates/favicon.ico") +@app.get("/style.css") +async def stylesheet(): + """Serve the Tailwind-generated stylesheet""" + return FileResponse("style.css", media_type="text/css") + @app.get("/config", response_model=ClientConfig) async def get_client_config(): """Serve client configuration to frontend""" diff --git a/style-input.css b/style-input.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/style-input.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..337e040 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./templates/index.html"], + theme: { + extend: {}, + }, + plugins: [], +} diff --git a/templates/index.html b/templates/index.html index 3d3048b..76f4361 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,54 +4,53 @@
Login with your Infomaniak account
- +Email: