{"id":50903774,"url":"https://github.com/hatimhtm/maison-brume-site","last_synced_at":"2026-06-16T05:05:28.434Z","repository":{"id":358763252,"uuid":"1242968289","full_name":"hatimhtm/maison-brume-site","owner":"hatimhtm","description":"Maison Brume — the editorial web-design studio's own site. Astro 5 + Tailwind v4, restrained editorial system, deferred WebGL 'brume' mist hero, CSS-only reveals (no JS/scroll gate), French-default i18n with persisted choice, 5 real client screenshots, 21 static pages. Near-zero JS on mobile. Auto-deploys to GitHub Pages, zero-config, $0.","archived":false,"fork":false,"pushed_at":"2026-05-19T02:03:27.000Z","size":1105,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-19T02:23:42.362Z","etag":null,"topics":["agency-site","astro","design-studio","editorial","english","fashion","french","github-actions","github-pages","glsl","i18n","lenis","morocco","paris","portfolio","static-site","tailwindcss","typescript","web-design","webgl"],"latest_commit_sha":null,"homepage":"https://hatimhtm.github.io/maison-brume-site/","language":"Astro","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hatimhtm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-18T23:47:10.000Z","updated_at":"2026-05-19T02:03:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hatimhtm/maison-brume-site","commit_stats":null,"previous_names":["hatimhtm/maison-brume-site"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hatimhtm/maison-brume-site","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fmaison-brume-site","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fmaison-brume-site/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fmaison-brume-site/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fmaison-brume-site/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hatimhtm","download_url":"https://codeload.github.com/hatimhtm/maison-brume-site/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fmaison-brume-site/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34391761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agency-site","astro","design-studio","editorial","english","fashion","french","github-actions","github-pages","glsl","i18n","lenis","morocco","paris","portfolio","static-site","tailwindcss","typescript","web-design","webgl"],"created_at":"2026-06-16T05:05:27.577Z","updated_at":"2026-06-16T05:05:28.416Z","avatar_url":"https://github.com/hatimhtm.png","language":"Astro","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets-readme/hero-banner-dark.svg\" /\u003e\n    \u003cimg src=\"assets-readme/hero-banner.svg\" alt=\"Maison Brume — editorial web design for fashion brands\" width=\"100%\" /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/hatimhtm/maison-brume-site/actions/workflows/deploy.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/hatimhtm/maison-brume-site/deploy.yml?branch=main\u0026style=for-the-badge\u0026label=DEPLOY\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"Deploy\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://hatimhtm.github.io/maison-brume-site/\"\u003e\u003cimg src=\"https://img.shields.io/badge/LIVE-GH_PAGES-1A1A1A?style=for-the-badge\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"Live on GitHub Pages\" /\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/STUDIO_SITE-OWN_BRAND-1A1A1A?style=for-the-badge\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"Studio's own site\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Astro-5-1A1A1A?style=for-the-badge\u0026logo=astro\u0026logoColor=CCFF00\" alt=\"Astro 5\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Tailwind-v4-1A1A1A?style=for-the-badge\u0026logo=tailwindcss\u0026logoColor=CCFF00\" alt=\"Tailwind v4\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/TypeScript-1A1A1A?style=for-the-badge\u0026logo=typescript\u0026logoColor=CCFF00\" alt=\"TypeScript\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/WebGL-GLSL-1A1A1A?style=for-the-badge\u0026logo=webgl\u0026logoColor=CCFF00\" alt=\"WebGL / GLSL\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Lenis-1.1-1A1A1A?style=for-the-badge\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"Lenis 1.1\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/EN_·_FR-FR_default-1A1A1A?style=for-the-badge\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"EN · FR, French default\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/License-MIT-1A1A1A?style=for-the-badge\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"MIT licence\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eThe studio's \u003cstrong\u003eown\u003c/strong\u003e site — \u003cstrong\u003eMaison Brume\u003c/strong\u003e, an editorial web-design studio for fashion brands, Morocco · Paris. \u003cstrong\u003eAstro 5 + Tailwind v4\u003c/strong\u003e, restrained editorial system (Fraunces optical axes, warm-mono palette), a deferred \u003cstrong\u003eWebGL \"brume\"\u003c/strong\u003e mist hero, \u003cstrong\u003eCSS-only\u003c/strong\u003e entrance (no JS/scroll gate — content can never hide itself), \u003cstrong\u003eFrench-default\u003c/strong\u003e browser detection with a persisted explicit choice, real client screenshots as the work. 21 static pages, near-zero JS on mobile, auto-deploys to \u003cstrong\u003eGitHub Pages\u003c/strong\u003e with zero config and zero cost.\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n### `/// THE BRIEF`\n\nA studio that sells web design has to *be* its own best argument. The brief, set against the conversion funnel, not taste:\n\n1. **Restraint, not austerity** — quiet-luxury editorial (The Row / Aesop register), but carried by the actual work shown, never bare type.\n2. **Mobile is the audience** — Morocco/France brand owners on phones. Sub-2s, 60fps, near-zero JS. The flex is craft, not a WebGL circus.\n3. **Prove it by showing** — real screenshots of five live client/concept sites are the portfolio; each case is a story in plain language, not jargon.\n4. **French-first** — most prospects browse in French; the default is FR unless the browser's primary language is English. An explicit language choice is remembered and never overridden.\n5. **Free + ownable** — pure static, GitHub Pages, no runtime deps, no lock-in. Custom domain swaps in via env when a client engagement justifies it.\n\n---\n\n### `/// SECTIONS`\n\n```\n┌────────────────────────────────────────────────────────────────┐\n│ Nav — MB mark · Work · Services · Studio · WhatsApp · EN/FR     │\n├────────────────────────────────────────────────────────────────┤\n│ Hero — deferred WebGL brume (drifting mist), problem-first      │\n│   headline grounded at baseline, prefilled-WhatsApp CTA         │\n├────────────────────────────────────────────────────────────────┤\n│ Manifesto — the point of view (\"Most fashion sites betray…\")    │\n├────────────────────────────────────────────────────────────────┤\n│ Selected Work — 5 real sites, image-led, proof-first order      │\n├────────────────────────────────────────────────────────────────┤\n│ What I build — services teaser → /services                     │\n├────────────────────────────────────────────────────────────────┤\n│ How it begins — the proof-first offer (concept before contract) │\n├────────────────────────────────────────────────────────────────┤\n│ How it works — 4-step process (Study · Concept · Build · Yours) │\n├────────────────────────────────────────────────────────────────┤\n│ Close — a real ending + prefilled WhatsApp                      │\n├────────────────────────────────────────────────────────────────┤\n│ Footer — mark · nav · WhatsApp · email                          │\n└────────────────────────────────────────────────────────────────┘\n\nRoutes (×2 locales, EN at root · FR under /fr)\n  /  ·  /work  ·  /work/[5 cases]  ·  /services  ·  /studio\n  /contact  ·  404                              → 21 static pages\n```\n\n---\n\n### `/// HIGHLIGHTS`\n\n| | |\n|---|---|\n| **CSS-only entrance — content can never hide itself** | Reveal/clip/scale live *only* inside `@keyframes` with `animation-fill-mode: both`, guarded by `prefers-reduced-motion`. No JS, no IntersectionObserver, no scroll gate. A prior JS-gated version could leave every image invisible on a slow phone or a screenshot — that class of bug is now structurally impossible. |\n| **Deferred WebGL \"brume\"** | Hand-written GLSL fbm mist behind the hero — the studio's name, made literal. Raw WebGL, no library, `requestIdleCallback`-lazy, DPR-capped, paused off-screen/hidden, skipped on reduced-motion or no-WebGL. Zero first-paint cost; the page is fully usable without it. |\n| **French-default i18n, no server** | An inline `\u003chead\u003e` script (EN pages only) redirects to the FR equivalent unless the browser's primary language is English. An explicit switch writes `localStorage` and is **never** overridden — no one is trapped. Pure static; works on GitHub Pages. |\n| **Restrained design system** | One fluid type scale, Fraunces variable axes (`opsz`/`SOFT`/`WONK`) set per use, warm-mono palette (WCAG-AA), one easing everywhere, a subliminal SVG grain layer, an SVG maker's-mark ornament. No template tells. |\n| **Real work, real screenshots** | Five live client/concept sites captured, optimised, shown image-led with full-page scroll-throughs on each case page, plus a plain-language \"in plain terms\" outcome — honestly labelled (prototype / concept / shipped to production). |\n| **Mobile-first budget** | Near-zero JS (Lenis loads only on fine-pointer + motion-allowed; brume only on capable devices). Tailwind v4, inlined CSS, static output. Sub-2s on mid-range phones. |\n| **GitHub Pages, base-path-correct** | `site`/`base` env-driven, every internal link + asset base-aware, trailing-slash aligned to directory output, `.nojekyll` shipped, Actions deploy. Custom domain = two env vars when the time comes. |\n\n---\n\n### `/// I18N`\n\n| Locale | Path | Default for | Notes |\n|---|---|---|---|\n| `fr` | `/fr/...` | **Everyone except English browsers** | Transcreated (luxury cadence, not literal). \"Maison Brume\" stays a proper noun; generic \"maison\" → marque/activité |\n| `en` | `/` (root) | Browsers whose primary language is English | Authored copy; problem-first voice |\n\nDetection runs before paint, in `\u003chead\u003e`, EN pages only. Explicit choice (`localStorage: mb-lang`) wins forever. FR pages carry no redirect logic — zero loops.\n\n---\n\n### `/// STACK`\n\n```\nAstro 5                      · static output, i18n routing\nTailwind v4 (@tailwindcss/vite) · design tokens via @theme\nTypeScript (strict)          · astro/tsconfigs/strict\nFraunces + Schibsted Grotesk · @fontsource-variable, latin\nLenis 1.1                    · smooth scroll (fine-pointer only)\nRaw WebGL + GLSL             · the brume mist, no library\nInline SVG                   · ornament · grain · banners\n```\n\nNo UI kit. No chart/animation libraries. CDN-free — fonts self-hosted via Fontsource.\n\n---\n\n### `/// PROJECT LAYOUT`\n\n```\n.\n├── astro.config.mjs           site/base env-driven · i18n · Tailwind v4 vite\n├── src/\n│   ├── lib/\n│   │   ├── content.ts         single source of all copy (EN + FR) + waLink\n│   │   └── paths.ts           base/locale-aware url + asset helpers\n│   ├── layouts/Base.astro     head · FR-default detector · skip-link · Lenis\n│   ├── components/            Nav · Footer · Mark · Ornament · BrumeFog\n│   │                          Home · WorkIndex · CaseStudy · Services\n│   │                          Studio · Contact\n│   ├── pages/                 index · work · work/[slug] · services\n│   │   └── fr/                studio · contact · 404   (mirrored under /fr)\n│   └── styles/global.css      design system — tokens, type, motion, grain\n├── public/\n│   ├── work/                  5 site screenshots + full-page scroll-throughs\n│   └── .nojekyll\n├── assets-readme/             this README's hero (light · dark)\n├── .github/workflows/deploy.yml   withastro/action → Pages\n└── README.md\n```\n\n---\n\n### `/// LOCAL DEV`\n\n```bash\nnpm install\nnpm run dev        # http://localhost:4321\nnpm run build      # static output → dist/\nnpm run preview    # serve the build\n```\n\nNo external services. The contact path is WhatsApp-first (prefilled deep links) — no backend, no form server.\n\n---\n\n### `/// DEPLOY`\n\n```\npush to main → .github/workflows/deploy.yml (withastro/action)\n            → builds, injects .nojekyll, uploads Pages artifact\n            → https://hatimhtm.github.io/maison-brume-site/\n```\n\nCustom domain later: set repo variables `SITE_URL` + `BASE_PATH` (empty), add `public/CNAME`. No code change.\n\n---\n\n### `/// CHECKS`\n\n```bash\nnpx astro check    # 0 errors · 0 warnings · 0 hints\nnpm run build      # 21 pages, clean\n```\n\nVerification is done by inspecting built output / a cache-busted screenshot — never by HTTP status alone. (Learned the hard way; written down so it stays learned.)\n\n---\n\n\u003cp align=\"center\"\u003e\u003csub\u003e© Maison Brume — studio site. MIT licensed. Built in the open.\u003c/sub\u003e\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhatimhtm%2Fmaison-brume-site","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhatimhtm%2Fmaison-brume-site","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhatimhtm%2Fmaison-brume-site/lists"}