## Implementation Plan
### 1. Add "Quizzes" link to navigation templates
**File: `devplacepy/templates/base.html`**
- **Line ~70 (desktop `.topnav-links`):** Insert the new link after the existing "News" link so the order becomes:
`๐ Home | ๐ Posts | ๐ฐ News | ๐ Gists | ๐ Projects | ๐ฑ Farm | ๐ Quizzes`
Use the same HTML structure as the other links:
```html
๐ Quizzes
```
- **Line ~133 (mobile `.topnav-mobile-links`):** Insert a corresponding link with the mobile class:
```html
๐ Quizzes
```
- **Note:** The actual route `quizzes.index` does not exist yet. Choose a placeholder route that corresponds to the future Quizzes feature (e.g., a static URL `/quizzes`). Since the ticket is only about the layout bug, create a minimal route in `devplacepy/routes/quizzes.py`:
```python
from flask import Blueprint, render_template
quizzes_bp = Blueprint('quizzes', __name__)
@quizzes_bp.route('/quizzes')
def index():
return render_template('quizzes/index.html') # start with a stub
```
Register the blueprint in `app.py`.
### 2. Harden `.topnav-link` CSS to prevent line-wrapping
**File: `static/css/base.css`**
- **Add to `.topnav-link` block (line ~622):**
```css
display: flex;
align-items: center;
gap: 0.375rem;
white-space: nowrap;
```
This matches the pattern already used for `.topnav-mobile-link` and ensures the icon and text always stay on one line.
- **Optionally ensure `.icon` has `display: inline-block` (line ~952):**
```css
display: inline-block;
```
This makes the `width: 20px` effective, though the flex approach on the parent already provides alignment.
### 3. Add Playwright e2e test for icon+text layout
**File: `tests/e2e/root.py` (or create new `tests/e2e/quizzes.py`)**
Add a test that:
- Navigates to the landing page.
- Locates all `.topnav-link` elements.
- For each, assert that the `getBoundingClientRect()` top coordinate of the `.icon` child equals the top coordinate of the text node (or the anchorโs `innerText` appears on same line).
- Simpler: assert that no `.topnav-link` has a computed `line-height` different from its `height` (indicating wrapping), or that the anchorโs scrollHeight equals its clientHeight.
Example:
```python
def test_topnav_links_icon_and_text_same_line(page):
page.goto("/")
links = page.locator(".topnav-link")
count = links.count()
for i in range(count):
link = links.nth(i)
icon = link.locator(".icon")
text = link.inner_text().replace(icon.inner_text(), "").strip()
# Check bounding boxes - they should overlap in y-axis
icon_box = icon.bounding_box()
text_range = link.locator(f"text={text}").bounding_box()
assert icon_box["y"] == text_range["y"], f"Link {i} icon and text not on same line"
```
### 4. Ensure test infrastructure is solid
- Before running tests, install Playwright browsers: `playwright install chromium`.
- If the test command does not include that, add a step in the plan to run it.
---
## Definition of Done
- [ ] The "Quizzes" link appears in the desktop `.topnav-links` and mobile `.topnav-mobile-links` navigation bars with correct icon and text.
- [ ] The `.topnav-link` CSS class now includes `display: flex; align-items: center; gap: 0.375rem; white-space: nowrap`.
- [ ] A minimal Quizzes route exists (e.g., `/quizzes`) and the link points to it without 404 errors.
- [ ] All existing e2e tests pass (including those for navigation link presence, leaderboard, mobile hamburger).
- [ ] The new test `test_topnav_links_icon_and_text_same_line` passes, verifying that for every `.topnav-link` the icon and text bounding boxes have the same vertical position.
- [ ] The projectโs verification command succeeds:
```bash
pip install -e '.[dev]' -q && python -m pytest tests/e2e/root.py tests/e2e/feed.py (and any new test file)
```
(Note: Playwright browsers must be installed prior; add `playwright install chromium` if not already done in CI.)