Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
98c990a
feat: placeholder frontpage + do-not-merge label workflow
martinydeAI Jun 9, 2026
de2c7cf
feat: frontpage previews AI Bibliotek design with sample data
martinydeAI Jun 9, 2026
d3cb04f
feat: split frontpage into anonymous Twig components
martinydeAI Jun 9, 2026
59adc1c
feat: emit dev-mode HTML comments around every Twig template
martinydeAI Jun 9, 2026
c12253e
refactor: drop Kommer snart section from frontpage
martinydeAI Jun 9, 2026
952b2e6
docs: add project Twig component conventions to CLAUDE.md
martinydeAI Jun 9, 2026
162e554
Added twig node visitor
martinyde Jun 9, 2026
6136d07
feat: add Danish translations + brand env vars
martinydeAI Jun 9, 2026
c4cca3c
fix: card hover top border + stats stacking on narrow viewports
martinydeAI Jun 9, 2026
de1696b
chore: ship brand identity defaults in .env
martinydeAI Jun 9, 2026
172cf78
docs: note Tailwind rebuild gotcha
martinydeAI Jun 9, 2026
8e4a8bb
chore: stub footer links to # until destinations are decided
martinydeAI Jun 9, 2026
ea1e55a
refactor: cards wrap into rows instead of horizontal scroll
martinydeAI Jun 9, 2026
d9e621c
refactor: promote section eyebrows to <h2>, card titles to <h3>
martinydeAI Jun 9, 2026
966f1b9
Merge branch 'develop' into feature/issue-40-frontpage-placeholder
martinyde Jun 11, 2026
0c3f5c8
ci: fix yaml-lint, composer-normalized, and phpunit checks
martinydeAI Jun 11, 2026
90ead51
docs(changelog): drop test-related entries as baseline noise
martinydeAI Jun 11, 2026
cc5ed78
Added tests for nodevisitor
martinyde Jun 11, 2026
d679b26
Added tests for nodevisitor
martinyde Jun 11, 2026
4164247
Reverted CHANGELOG change
martinyde Jun 11, 2026
466c383
Reverted a deleted method in Kernel
martinyde Jun 11, 2026
26930ab
Added Kernel test
martinyde Jun 11, 2026
090f849
refactor: .env is the only source of BRAND_* defaults
martinydeAI Jun 11, 2026
5abc7a9
fix(a11y): SearchBox label describes the field, not the submit action
martinydeAI Jun 11, 2026
cb7876a
Updated .env
martinyde Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ APP_SHARE_DIR=var/share
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
DEFAULT_URI=http://localhost
###< symfony/routing ###

###> brand identity ###
BRAND_NAME="AI Bibliotek"
BRAND_TAGLINE="del & hjemtag assistenter"
BRAND_INITIALS="AI"
###< brand identity ###
39 changes: 39 additions & 0 deletions .github/workflows/block-on-label.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
### Block merge on label
###
### Fails the check while a `do-not-merge` label is applied to the
### pull request. The label is used to gate merges that depend on
### something landing elsewhere (another PR, an upstream release, a
### review by a specific team).
###
### Removing the label and re-running the check turns it green. To
### make the merge button itself unavailable while the label is set,
### this check has to be marked as a required status check in the
### repository's branch-protection rules.

name: Block merge on label

on:
pull_request:
types:
- opened
- reopened
- synchronize
- labeled
- unlabeled

jobs:
block-on-label:
name: Block on do-not-merge label
runs-on: ubuntu-latest
steps:
- name: Check for do-not-merge label
env:
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
run: |
echo "Labels on this PR: $LABELS"
if echo "$LABELS" | grep -qx '"do-not-merge"' \
|| echo "$LABELS" | grep -q '"do-not-merge"'; then
echo "::error::This PR carries the 'do-not-merge' label. Remove the label once the blocking dependency is resolved."
exit 1
fi
echo "No blocking label present."
3 changes: 3 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
- name: Install dependencies
run: docker compose run --rm phpfpm composer install

- name: Build Tailwind CSS
run: docker compose run --rm phpfpm bin/console tailwind:build

- name: Run PHPUnit with coverage
run: docker compose run -e XDEBUG_MODE=coverage --rm phpfpm vendor/bin/phpunit --coverage-clover=coverage/clover.xml

Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Decision recorded in [ADR 002](docs/adr/002-frontend-tooling.md).
- Base Twig layout (`templates/base.html.twig`) and frontend asset
entrypoints (`assets/app.js`, `assets/styles/app.css`).
- Placeholder frontpage at `/` (`App\Controller\FrontpageController`)
that previews the AI Bibliotek design with hardcoded sample data:
hero, search prompt, sample-assistant rail, "Sådan virker det"
steps, and "Kommer snart" chips. Follows the prototype mock at
`itk-dev/research-projects/docs/public/projects/ai-bibliotek/mocks`.
- Site chrome (header with brand + nav, footer) in
`templates/base.html.twig`, with the Fraunces/Geist font stack
preloaded from Google Fonts.
- Tailwind v4 design tokens (`@theme` in `assets/styles/app.css`)
matching the prototype palette and typography.
- Stimulus controller `nav_toggle_controller` driving the mobile
navigation menu.
- GitHub Action `block-on-label` that fails the check while a
`do-not-merge` label is applied to a pull request, providing a
per-PR merge gate for dependencies (e.g. another PR that must land
first).
- `LICENSE` file at repo root containing the full Mozilla Public License 2.0 text.
- ADR `docs/adr/002-project-license-mpl-2.md` recording the MPL-2.0 license
decision and its rationale.
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,18 @@ itkdev-docker-compose php bin/console asset-map:compile
itkdev-docker-compose php bin/console debug:asset-map
```

> **Heads-up:** there is no live Tailwind watcher running by default, and
> `cache:clear` does **not** rebuild the stylesheet. After editing a
> template that introduces a utility class not already in use (e.g.
> `pt-2`, `grid-cols-1`), run `tailwind:build` — or keep a
> `tailwind:build --watch` terminal open while you style.

Source files live under [`assets/`](assets):

- `assets/app.js` — JavaScript entrypoint, boots Stimulus.
- `assets/styles/app.css` — Tailwind entrypoint (`@import "tailwindcss";`).
- `assets/controllers/` — Stimulus controllers, auto-registered by
filename (`hello_controller.js` → `data-controller="hello"`).
filename (`nav_toggle_controller.js` → `data-controller="nav-toggle"`).

For one-off commands without a dedicated task, fall back to the underlying
tools, e.g. `docker compose --profile dev run --rm prettier <args>` or
Expand Down
17 changes: 0 additions & 17 deletions assets/controllers/hello_controller.js

This file was deleted.

26 changes: 26 additions & 0 deletions assets/controllers/nav_toggle_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Controller } from "@hotwired/stimulus";

/*
* Mobile navigation toggle.
*
* Mounted on the header container (`data-controller="nav-toggle"`).
* The toggle button uses `data-action="click->nav-toggle#toggle"` and
* the nav element is the `menu` target. Flips `aria-expanded` on the
* button and the `hidden` utility class on the menu so screen readers
* and the CSS toggle effect stay in sync.
*/
export default class extends Controller {
static targets = ["menu"];

toggle(event) {
const button = event.currentTarget;
const expanded = button.getAttribute("aria-expanded") === "true";
button.setAttribute("aria-expanded", String(!expanded));

if (!this.hasMenuTarget) {
return;
}
this.menuTarget.classList.toggle("hidden", expanded);
this.menuTarget.classList.toggle("flex", !expanded);
}
}
156 changes: 156 additions & 0 deletions assets/styles/app.css
Original file line number Diff line number Diff line change
@@ -1 +1,157 @@
@import "tailwindcss";

/*
* Design tokens mirroring the AI Bibliotek prototype
* (https://github.com/itk-dev/research-projects/tree/main/docs/public/projects/ai-bibliotek/mocks).
* Registered via Tailwind v4's `@theme` so the values become utility
* variants — e.g. `bg-surface`, `text-ink`, `font-display`.
*/
@theme {
/* Surface + ink palette */
--color-bg: #ffffff;
--color-surface: #ffffff;
--color-surface-2: #fbf9f5;
--color-border: #e3ddd1;
--color-border-strong: #c8bea9;
--color-line: #ddd5c4;
--color-ink: #11192a;
--color-text: #1c2433;
--color-text-muted: #5b6478;

/* Brand */
--color-primary: #0f766e;
--color-primary-hover: #0c5e57;
--color-primary-ink: #ffffff;
--color-accent: #c89b3c;
--color-accent-soft: #f0e3c2;
--color-accent-deep: #8a6a1f;

/* Typography */
--font-display:
"Fraunces", "Source Serif Pro", "Iowan Old Style", Georgia, serif;
--font-sans:
"Geist", "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Helvetica, Arial, sans-serif;
--font-mono:
"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas,
monospace;
}

/*
* Base layer: page chrome that has to apply to <body> regardless of
* which utility classes the template carries. Mirrors the prototype's
* body styling so the same font stack and ink colour are used
* everywhere.
*/
@layer base {
body {
font-family: var(--font-sans);
color: var(--color-text);
background-color: var(--color-bg);
font-feature-settings: "ss01", "ss02";
}

h1,
h2,
h3,
h4 {
font-family: var(--font-display);
font-weight: 500;
color: var(--color-ink);
letter-spacing: -0.01em;
line-height: 1.15;
}
}

/*
* Component layer: small set of compound patterns that would be
* unwieldy as inline utility lists. Each is named after its
* prototype counterpart and only contains decorative bits that
* Tailwind utilities don't express directly (pseudo-elements,
* keyframes).
*/
@layer components {
/* Eyebrow label with leading decorative rule, used as a section kicker. */
/* font-family is set explicitly so an <h2 class="eyebrow"> renders in */
/* the sans body font instead of the serif `--font-display` that the */
/* @layer base { h1..h4 } rule above otherwise applies to headings. */
.eyebrow {
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-family: var(--font-sans);
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--color-accent-deep);
}
.eyebrow::before {
content: "";
display: inline-block;
width: 24px;
height: 1px;
background-color: var(--color-accent-deep);
}

/* Staggered fade-up on the main view's direct children. */
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.view-root > * {
animation: fade-up 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.view-root > *:nth-child(1) {
animation-delay: 0ms;
}
.view-root > *:nth-child(2) {
animation-delay: 40ms;
}
.view-root > *:nth-child(3) {
animation-delay: 80ms;
}
.view-root > *:nth-child(4) {
animation-delay: 120ms;
}
.view-root > *:nth-child(5) {
animation-delay: 160ms;
}
@media (prefers-reduced-motion: reduce) {
.view-root > * {
animation: none;
}
}

/*
* Animated hamburger toggle. The three bars rotate into an X when
* `aria-expanded="true"`. Hand-rolled because Tailwind utilities
* can't express child-element transforms tied to a parent ARIA
* state.
*/
.nav-toggle-bar {
display: block;
width: 18px;
height: 2px;
background-color: var(--color-ink);
border-radius: 2px;
transition:
transform 220ms ease,
opacity 220ms ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
transform: translateY(5.5px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
transform: translateY(-5.5px) rotate(-45deg);
}
}
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"symfony/framework-bundle": "~8.1.0",
"symfony/runtime": "~8.1.0",
"symfony/stimulus-bundle": "^3.1",
"symfony/translation": "~8.1.0",
"symfony/twig-bundle": "~8.1.0",
"symfony/ux-twig-component": "^3.1",
"symfony/yaml": "~8.1.0",
"symfonycasts/tailwind-bundle": "^0.13.0",
"twig/extra-bundle": "^2.12 || ^3.0",
Expand Down
Loading
Loading