admin.css: replace .admin-main, .admin-page-title, .admin-table, .admin-fieldset with semantic selectors

Replace four presentational class names in admin.css with structural selectors
that target native HTML elements already present in every admin template:

  .admin-main           → .admin-body main
  .admin-page-title     → .admin-body main > h1
  .admin-table          → .admin-body table
  .admin-fieldset       → .admin-body fieldset
  .admin-fieldset-legend → .admin-body legend

Also migrate the .admin-main > section / h2 / dl / dt / dd block to
.admin-body main > section so the thanks-page section styles survive.

Add .admin-body main > table { margin-top: 1.5rem } to absorb the inline
style="margin-top:1.5rem" that was on tags.php's <table class="admin-table">.

All 10 affected admin templates updated (add, edit, account, index, import,
pages, pages-edit, tags, system, thanks) — class attributes removed where
the element alone is now the selector.  Zero visual changes.
This commit is contained in:
Pontoporeia
2026-04-02 12:16:59 +02:00
parent cb1ced535b
commit 0ab08f3aa0
12 changed files with 52 additions and 47 deletions

View File

@@ -3,15 +3,15 @@
## Template Simplification — Remove Custom Classes Where Semantic HTML Suffices
### CSS class audit: replace with semantic selectors
- [ ] **`admin.css`**: Replace `.admin-main` with `.admin-body main` — only one `<main>` per page
- [ ] **`admin.css`**: Replace `.admin-page-title` with `.admin-body main > h1` — always the first `h1` in `<main>`
- [x] **`admin.css`**: Replace `.admin-main` with `.admin-body main` — only one `<main>` per page
- [x] **`admin.css`**: Replace `.admin-page-title` with `.admin-body main > h1` — always the first `h1` in `<main>`
- [ ] **`admin.css`**: Replace `.admin-alert` / `.admin-alert--error` / `.admin-alert--success` with `[role="alert"]` or `.admin-body main > .alert` using `data-type="error|success"` attribute instead of modifier classes
- [ ] **`admin.css`**: Replace `.admin-form-row` with `.admin-body form > div` or `.admin-body form > .row` — form rows are always direct `<div>` children of `<form>`
- [ ] **`admin.css`**: Replace `.admin-label` with `.admin-body form label` — every label in admin forms
- [ ] **`admin.css`**: Replace `.admin-input` / `.admin-select` / `.admin-textarea` with `.admin-body form input[type="text"]`, `.admin-body form select`, `.admin-body form textarea` — leverage native element selectors
- [x] **`admin.css`**: Replace `.admin-hint` with `.admin-body form small` — use `<small>` instead of `<p class="admin-hint">`
- [ ] **`admin.css`**: Replace `.admin-table` with `.admin-body table` — only one table per admin page
- [ ] **`admin.css`**: Replace `.admin-fieldset` / `.admin-fieldset-legend` with `.admin-body fieldset` / `.admin-body legend`
- [x] **`admin.css`**: Replace `.admin-table` with `.admin-body table` — only one table per admin page
- [x] **`admin.css`**: Replace `.admin-fieldset` / `.admin-fieldset-legend` with `.admin-body fieldset` / `.admin-body legend`
- [x] **`main.css`**: Replace `.card__caption` with `.home-body .cards-container li p` or target `li > a > p` directly
- [x] **`main.css`**: Replace `.card__media` with `.home-body figure` — already uses `<figure>` elements
- [x] **`tfe.css`**: Replace `.tfe-meta-list` selectors with `article dl`, `article dt`, `article dd` — already using `<dl>` inside `<article>`

View File

@@ -19,8 +19,8 @@ if (empty($_SESSION['csrf_token'])) {
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Compte administrateur</h1>
<main id="main-content">
<h1>Compte administrateur</h1>
<?php if ($error): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($error) ?></div>

View File

@@ -42,8 +42,8 @@ function wasSelected($key, $value) {
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Ajouter un TFE</h1>
<main id="main-content">
<h1>Ajouter un TFE</h1>
<?php if ($error): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($error) ?></div>
@@ -81,8 +81,8 @@ function wasSelected($key, $value) {
</div>
<!-- Composition du jury -->
<fieldset class="admin-fieldset">
<legend class="admin-fieldset-legend">Composition du jury</legend>
<fieldset>
<legend>Composition du jury</legend>
<!-- Président·e -->
<div class="admin-form-row">

View File

@@ -64,8 +64,8 @@ try {
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Modifier un TFE</h1>
<main id="main-content">
<h1>Modifier un TFE</h1>
<?php if ($error): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($error) ?></div>
@@ -148,8 +148,8 @@ try {
}
}
?>
<fieldset class="admin-fieldset">
<legend class="admin-fieldset-legend">Composition du jury</legend>
<fieldset>
<legend>Composition du jury</legend>
<div class="admin-form-row">
<label class="admin-label" for="jury_president">Président·e :</label>

View File

@@ -320,8 +320,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Importer une liste de TFE</h1>
<main id="main-content">
<h1>Importer une liste de TFE</h1>
<?php if (!empty($errors)): ?>
<div class="admin-alert admin-alert--error">

View File

@@ -64,8 +64,8 @@ document.addEventListener('DOMContentLoaded', () => {
});
</script>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Liste des TFE</h1>
<main id="main-content">
<h1>Liste des TFE</h1>
<?php if (isset($_SESSION['error'])): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($_SESSION['error']); unset($_SESSION['error']); ?></div>
@@ -157,7 +157,7 @@ document.addEventListener('DOMContentLoaded', () => {
<?php if (empty($theses)): ?>
<p style="color:var(--admin-text-muted);padding:1rem 0;">Aucun TFE trouvé.</p>
<?php else: ?>
<table class="admin-table">
<table>
<thead>
<tr>
<th scope="col"><input type="checkbox" onchange="toggleAll(this)"></th>

View File

@@ -81,8 +81,8 @@ JS;
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Éditer : <?= htmlspecialchars($page['title']) ?></h1>
<main id="main-content">
<h1>Éditer : <?= htmlspecialchars($page['title']) ?></h1>
<form action="/admin/actions/page.php" method="post" class="admin-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">

View File

@@ -21,14 +21,14 @@ unset($_SESSION['success']);
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Pages statiques</h1>
<main id="main-content">
<h1>Pages statiques</h1>
<?php if ($success): ?>
<div class="admin-alert admin-alert--success">✓ <?= htmlspecialchars($success) ?></div>
<?php endif; ?>
<table class="admin-table">
<table>
<thead>
<tr>
<th scope="col">Slug</th>

View File

@@ -372,8 +372,8 @@ require_once APP_ROOT . '/templates/head.php';
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Système</h1>
<main id="main-content">
<h1>Système</h1>
<p class="sys-refresh-note">
Affiché le <?= date('d/m/Y à H:i:s') ?> —

View File

@@ -25,8 +25,8 @@ unset($_SESSION['admin_error'], $_SESSION['admin_success']);
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Mots-clés (<?= count($tags) ?>)</h1>
<main id="main-content">
<h1>Mots-clés (<?= count($tags) ?>)</h1>
<?php if ($error): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($error) ?></div>
@@ -35,7 +35,7 @@ unset($_SESSION['admin_error'], $_SESSION['admin_success']);
<div class="admin-alert admin-alert--success">✓ <?= htmlspecialchars($success) ?></div>
<?php endif; ?>
<table class="admin-table" style="margin-top:1.5rem;">
<table>
<thead>
<tr>
<th scope="col" style="width:40%;">Nom</th>

View File

@@ -65,8 +65,8 @@ $pageTitle = "Récapitulatif TFE";
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content">
<h1 class="admin-page-title">Récapitulatif TFE</h1>
<main id="main-content">
<h1>Récapitulatif TFE</h1>
<?php if ($error): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($error) ?></div>
@@ -122,7 +122,7 @@ $pageTitle = "Récapitulatif TFE";
<?php if (!empty($files)): ?>
<section>
<h2>Fichiers</h2>
<table class="admin-table">
<table>
<thead><tr><th scope="col">Type</th><th scope="col">Fichier</th><th scope="col">Taille</th><th scope="col">Date</th></tr></thead>
<tbody>
<?php foreach ($files as $f): ?>

View File

@@ -87,14 +87,14 @@
}
/* Main content area */
.admin-main {
.admin-body main {
flex: 1;
padding: 2.5rem 2rem 4rem;
max-width: 1100px;
width: 100%;
}
.admin-page-title {
.admin-body main > h1 {
font-size: 1.8rem;
font-weight: 600;
letter-spacing: 0.08em;
@@ -375,13 +375,18 @@
}
/* ---- Table ---- */
.admin-table {
.admin-body table {
width: 100%;
border-collapse: collapse;
font-size: 0.88rem;
}
.admin-table th {
/* margin-top for the tags table (only table not immediately after stats/filters) */
.admin-body main > table {
margin-top: 1.5rem;
}
.admin-body table th {
text-align: left;
font-size: 0.75rem;
letter-spacing: 0.08em;
@@ -393,23 +398,23 @@
white-space: nowrap;
}
.admin-table td {
.admin-body table td {
padding: 0.65rem 0.75rem;
border-bottom: 1px solid var(--admin-border);
color: var(--admin-text);
vertical-align: top;
}
.admin-table tr:hover td {
.admin-body table tr:hover td {
background: var(--admin-bg-alt);
}
.admin-table .thesis-title {
.admin-body table .thesis-title {
font-weight: 500;
color: var(--admin-text);
}
.admin-table .thesis-subtitle {
.admin-body table .thesis-subtitle {
font-size: 0.82rem;
color: var(--admin-text-muted);
font-style: italic;
@@ -521,33 +526,33 @@
}
/* Thesis info sections (thanks page) */
.admin-main > section {
.admin-body main > section {
border: 1px solid var(--admin-border);
border-radius: 6px;
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.admin-main > section h2 {
.admin-body main > section h2 {
margin: 0 0 1rem;
font-size: 1.2rem;
border-bottom: 1px solid var(--admin-border);
padding-bottom: 0.5rem;
}
.admin-main > section dl {
.admin-body main > section dl {
display: grid;
grid-template-columns: 180px 1fr;
gap: 0.4rem 1rem;
}
.admin-main > section dt {
.admin-body main > section dt {
font-weight: 600;
font-size: 0.88rem;
color: var(--admin-text-muted);
}
.admin-main > section dd {
.admin-body main > section dd {
margin: 0;
font-size: 0.9rem;
}
@@ -622,7 +627,7 @@
}
/* Jury fieldset */
.admin-fieldset {
.admin-body fieldset {
border: 1px solid #333;
border-radius: 4px;
padding: 1rem 1.25rem;
@@ -630,7 +635,7 @@
background: rgba(255, 255, 255, 0.02);
}
.admin-fieldset-legend {
.admin-body legend {
font-size: 0.82rem;
font-weight: 600;
letter-spacing: 0.04em;