@hgdc/docs 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/docs.schema.json +59 -0
  2. package/package.json +1 -1
  3. package/src/core/config.ts +47 -1
  4. package/src/overrides/Header.astro +14 -2
  5. package/src/overrides/Sidebar.astro +11 -2
  6. package/src/overrides/SiteFooter.astro +67 -23
  7. package/src/overrides/sections.ts +5 -0
  8. package/src/styles/theme.css +114 -14
  9. package/template/.build/404.html +4 -4
  10. package/template/.build/_astro/common.D2jViLgF.css +3 -0
  11. package/template/.build/_hgdc/corpus.json +1 -1
  12. package/template/.build/demarrer/premiere-doc/index.html +5 -5
  13. package/template/.build/explications/donnees/index.html +5 -5
  14. package/template/.build/explications/fonctionnement/index.html +5 -5
  15. package/template/.build/guides/agents/index.html +5 -5
  16. package/template/.build/guides/assistant/index.html +5 -5
  17. package/template/.build/guides/composants/index.html +6 -6
  18. package/template/.build/guides/ecrire/index.html +5 -5
  19. package/template/.build/guides/navigation/index.html +5 -5
  20. package/template/.build/guides/publier/index.html +5 -5
  21. package/template/.build/guides/theme/index.html +5 -5
  22. package/template/.build/images/famille/account.svg +1 -0
  23. package/template/.build/images/famille/analytics.svg +1 -0
  24. package/template/.build/images/famille/docs.svg +1 -0
  25. package/template/.build/images/famille/host.svg +1 -0
  26. package/template/.build/images/famille/mail.svg +1 -0
  27. package/template/.build/images/famille/portal.svg +1 -0
  28. package/template/.build/images/famille/status.svg +1 -0
  29. package/template/.build/index.html +5 -5
  30. package/template/.build/llms-full.txt +4 -0
  31. package/template/.build/pagefind/fragment/fr-ch_1a9a1fc.pf_fragment +0 -0
  32. package/template/.build/pagefind/index/fr-ch_1c27d4e.pf_index +0 -0
  33. package/template/.build/pagefind/pagefind-entry.json +1 -1
  34. package/template/.build/pagefind/pagefind.fr-ch_6bf31b937df47.pf_meta +0 -0
  35. package/template/.build/reference/api-assistant/index.html +5 -5
  36. package/template/.build/reference/cli/index.html +5 -5
  37. package/template/.build/reference/docs-json/index.html +30 -6
  38. package/template/.build/reference/docs-json.md +4 -0
  39. package/template/.build/reference/mcp/index.html +5 -5
  40. package/template/node_modules/.vite/deps/_metadata.json +8 -8
  41. package/template/.build/_astro/common.BoKrWC_6.css +0 -3
  42. package/template/.build/pagefind/fragment/fr-ch_a4b68e2.pf_fragment +0 -0
  43. package/template/.build/pagefind/index/fr-ch_481c81a.pf_index +0 -0
  44. package/template/.build/pagefind/pagefind.fr-ch_46a632d8eba7e.pf_meta +0 -0
package/docs.schema.json CHANGED
@@ -233,6 +233,21 @@
233
233
  }
234
234
  }
235
235
  },
236
+ "app": {
237
+ "type": "object",
238
+ "properties": {
239
+ "href": {
240
+ "type": "string",
241
+ "format": "uri"
242
+ },
243
+ "label": {
244
+ "type": "string",
245
+ "minLength": 1,
246
+ "maxLength": 40
247
+ }
248
+ },
249
+ "required": ["href"]
250
+ },
236
251
  "footer": {
237
252
  "type": "object",
238
253
  "properties": {
@@ -245,6 +260,50 @@
245
260
  "type": "string",
246
261
  "format": "uri"
247
262
  }
263
+ },
264
+ "links": {
265
+ "maxItems": 6,
266
+ "type": "array",
267
+ "items": {
268
+ "type": "object",
269
+ "properties": {
270
+ "header": {
271
+ "type": "string",
272
+ "minLength": 1,
273
+ "maxLength": 40
274
+ },
275
+ "items": {
276
+ "minItems": 1,
277
+ "maxItems": 12,
278
+ "type": "array",
279
+ "items": {
280
+ "type": "object",
281
+ "properties": {
282
+ "label": {
283
+ "type": "string",
284
+ "minLength": 1,
285
+ "maxLength": 60
286
+ },
287
+ "href": {
288
+ "type": "string",
289
+ "minLength": 1
290
+ },
291
+ "icon": {
292
+ "type": "string",
293
+ "pattern": "^\\/(?!\\/)[\\w./-]+$"
294
+ }
295
+ },
296
+ "required": ["label", "href"]
297
+ }
298
+ }
299
+ },
300
+ "required": ["items"]
301
+ }
302
+ },
303
+ "copyright": {
304
+ "type": "string",
305
+ "minLength": 1,
306
+ "maxLength": 80
248
307
  }
249
308
  }
250
309
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hgdc/docs",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "Modèle de site de HGDC Docs : documentation MDX (docs.json) construite avec Astro Starlight, recherche, versions, llms.txt et assistant.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -82,6 +82,25 @@ export function socialNetwork(key: string): (typeof SOCIAL_NETWORKS)[keyof typeo
82
82
  return SOCIAL_NETWORKS[name] ?? null
83
83
  }
84
84
 
85
+ /**
86
+ * Lien du pied de page : un chemin du site (« /guides/publier », préfixé par `base`), une
87
+ * adresse https:// ou mailto:. `icon` : image du site (« /images/x.svg ») affichée devant.
88
+ */
89
+ const footerLink = z.object({
90
+ label: z.string().min(1).max(60),
91
+ href: z
92
+ .string()
93
+ .min(1)
94
+ .refine(
95
+ (value) => /^\/(?!\/)/.test(value) || /^https:\/\/[^\s]+$/.test(value) || /^mailto:[^\s@]+@[^\s@]+$/.test(value),
96
+ "lien attendu : un chemin du site (« /… »), une adresse https:// ou mailto:",
97
+ ),
98
+ icon: z
99
+ .string()
100
+ .regex(/^\/(?!\/)[\w./-]+$/, "image attendue : un chemin du site (ex. /images/logo.svg)")
101
+ .optional(),
102
+ })
103
+
85
104
  const REDIRECT_SOURCE = /^\/(?!\/)[A-Za-z0-9._~\-/%]*$/
86
105
 
87
106
  /** Ancienne adresse vers la nouvelle (champ `redirects` de Mintlify), sans motif. */
@@ -126,7 +145,34 @@ export const docsConfigSchema = z.object({
126
145
  primary: z.object({ label: z.string(), href: z.url() }).optional(),
127
146
  })
128
147
  .optional(),
129
- footer: z.object({ socials: z.record(z.string(), z.url()).optional() }).optional(),
148
+ /**
149
+ * Application que la doc accompagne (champ HGDC) : bouton « Ouvrir <name> » dans l'en-tête
150
+ * et en tête du menu de téléphone. Sans lui, la lectrice n'a aucun chemin vers le produit.
151
+ */
152
+ app: z
153
+ .object({
154
+ href: z.url({ protocol: /^https$/, error: "adresse attendue, en https://" }),
155
+ /** Libellé du bouton ; « Ouvrir <name> » par défaut. */
156
+ label: z.string().min(1).max(40).optional(),
157
+ })
158
+ .optional(),
159
+ footer: z
160
+ .object({
161
+ socials: z.record(z.string(), z.url()).optional(),
162
+ /** Colonnes de liens (champ `footer.links` de Mintlify), plus une `icon` facultative par lien. */
163
+ links: z
164
+ .array(
165
+ z.object({
166
+ header: z.string().min(1).max(40).optional(),
167
+ items: z.array(footerLink).min(1, "une colonne contient au moins un lien").max(12),
168
+ }),
169
+ )
170
+ .max(6, "6 colonnes au plus")
171
+ .optional(),
172
+ /** Titulaire affiché après « © <année> » au bas du pied (champ HGDC) ; `name` par défaut. */
173
+ copyright: z.string().min(1).max(80).optional(),
174
+ })
175
+ .optional(),
130
176
  redirects: z.array(redirect).max(500, "500 redirections au plus").optional(),
131
177
  assistant: z
132
178
  .object({
@@ -2,14 +2,17 @@
2
2
  import Search from "virtual:starlight/components/Search"
3
3
  import data from "virtual:hgdc-docs/config"
4
4
 
5
- import { assistantEnabled, docsSections, sectionHref } from "./sections.ts"
5
+ import { appLink, assistantEnabled, docsSections, sectionHref } from "./sections.ts"
6
6
  import Icon from "./Icon.astro"
7
7
  import ThemeToggle from "./ThemeToggle.astro"
8
8
 
9
9
  /**
10
10
  * En-tête, comme chez Mintlify : produit à gauche, onglets de docs.json au centre, puis la
11
11
  * recherche, l'assistant, les liens de `navbar` et le thème. Sur téléphone, le menu, le
12
- * produit, la recherche et l'assistant seulement : le reste passe dans le menu.
12
+ * produit, la recherche, l'assistant et « Ouvrir <produit> » : le reste passe dans le menu.
13
+ *
14
+ * Le nom du produit mène à l'accueil de la doc (on reste dans le site qu'on lit, comme le
15
+ * logo de tout site) ; le chemin vers l'application est le bouton « Ouvrir <produit> » (`app`).
13
16
  */
14
17
  const { tabs, current } = docsSections(data.tree, Astro.locals.hgdcSection ?? 0)
15
18
  const home = `${data.base}/`
@@ -18,6 +21,7 @@ const src = (path: string) => `${data.base}${path.startsWith("/") ? path : `/${p
18
21
  const links = data.config.navbar?.links ?? []
19
22
  const primary = data.config.navbar?.primary
20
23
  const assistant = assistantEnabled(data.config)
24
+ const app = appLink(data.config)
21
25
  ---
22
26
 
23
27
  <div class="hd-header">
@@ -88,5 +92,13 @@ const assistant = assistantEnabled(data.config)
88
92
  )
89
93
  }
90
94
  <ThemeToggle variant="button" />
95
+ {
96
+ app && (
97
+ <a class="hd-pill hd-pill--primary hd-app-button" href={app.href}>
98
+ {app.label}
99
+ <Icon name="arrow-up-right" size={16} />
100
+ </a>
101
+ )
102
+ }
91
103
  </div>
92
104
  </div>
@@ -2,14 +2,14 @@
2
2
  import data from "virtual:hgdc-docs/config"
3
3
 
4
4
  import Icon from "./Icon.astro"
5
- import { docsSections, sectionHref } from "./sections.ts"
5
+ import { appLink, docsSections, sectionHref } from "./sections.ts"
6
6
  import SidebarList from "./SidebarList.astro"
7
7
  import ThemeToggle from "./ThemeToggle.astro"
8
8
 
9
9
  /**
10
10
  * Barre latérale : la version (s'il y en a plusieurs), puis les groupes de docs.json. Sur
11
11
  * téléphone, le même panneau sert de menu : il reprend les onglets et les liens de
12
- * l'en-tête, et le choix du thème.
12
+ * l'en-tête, le bouton vers l'application et le choix du thème.
13
13
  */
14
14
  const { tabs, versions, current } = docsSections(data.tree, Astro.locals.hgdcSection ?? 0)
15
15
  const tabPosition = current.version.tabs.indexOf(current.tab)
@@ -17,6 +17,7 @@ const versionHref = (version: (typeof versions)[number]) =>
17
17
  sectionHref(data.base, (version.tabs[tabPosition] ?? version.tabs[0]!).items)
18
18
  const links = data.config.navbar?.links ?? []
19
19
  const primary = data.config.navbar?.primary
20
+ const app = appLink(data.config)
20
21
  ---
21
22
 
22
23
  <div class="hd-mobile-only hd-sidebar-head">
@@ -25,6 +26,14 @@ const primary = data.config.navbar?.primary
25
26
  <Icon name="x" />
26
27
  </button>
27
28
  </div>
29
+ {
30
+ app && (
31
+ <a class="hd-mobile-only hd-pill hd-pill--primary hd-sidebar-app" href={app.href}>
32
+ {app.label}
33
+ <Icon name="arrow-up-right" size={16} />
34
+ </a>
35
+ )
36
+ }
28
37
 
29
38
  {
30
39
  versions.length > 1 && (
@@ -3,49 +3,93 @@ import { Icon as StarlightIcon } from "@astrojs/starlight/components"
3
3
  import data from "virtual:hgdc-docs/config"
4
4
 
5
5
  import { socialNetwork } from "../core/config.ts"
6
+ import { withBase } from "../core/navigation.ts"
7
+ import Icon from "./Icon.astro"
8
+ import { appLink } from "./sections.ts"
6
9
  import ThemeToggle from "./ThemeToggle.astro"
7
10
 
8
11
  /**
9
- * Pied de page du site, à droite de la barre latérale : le produit, ses réseaux
10
- * (`footer.socials`) et le choix du thème.
12
+ * Pied de page du site, à droite de la barre latérale. En haut, le produit (logo, phrase,
13
+ * bouton vers l'application, réseaux) et les colonnes de `footer.links` ; en bas, « © année
14
+ * titulaire » et le choix du thème. Tout vient de docs.json : le modèle n'invente aucun lien.
11
15
  */
12
16
  const logo = typeof data.config.logo === "string" ? { light: data.config.logo } : data.config.logo
13
- const src = (path: string) => `${data.base}${path.startsWith("/") ? path : `/${path}`}`
17
+ const src = (path: string) => withBase(data.base, path.startsWith("/") ? path : `/${path}`)
14
18
  const socials = Object.entries(data.config.footer?.socials ?? {}).flatMap(([key, href]) => {
15
19
  const network = socialNetwork(key)
16
20
  return network ? [{ ...network, href }] : []
17
21
  })
22
+ const columns = data.config.footer?.links ?? []
23
+ const app = appLink(data.config)
24
+ const owner = data.config.footer?.copyright ?? data.config.name
25
+ const year = new Date().getFullYear()
18
26
  ---
19
27
 
20
28
  <footer class="hd-site-footer" data-pagefind-ignore>
21
- <div class="hd-site-footer__row">
22
- <a class="hd-brand hd-brand--footer" href={`${data.base}/`}>
29
+ <div class="hd-site-footer__top">
30
+ <div class="hd-site-footer__about">
31
+ <a class="hd-brand hd-brand--footer" href={`${data.base}/`}>
32
+ {
33
+ logo && (
34
+ <span class="hd-brand__mark">
35
+ <img class="hd-brand__light" src={src(logo.light)} alt="" width="20" height="20" loading="lazy" />
36
+ <img class="hd-brand__dark" src={src(logo.dark ?? logo.light)} alt="" width="20" height="20" loading="lazy" />
37
+ </span>
38
+ )
39
+ }
40
+ <span class="hd-brand__name">{data.config.name}</span>
41
+ </a>
42
+ {data.config.description && <p class="hd-site-footer__lede">{data.config.description}</p>}
23
43
  {
24
- logo && (
25
- <span class="hd-brand__mark">
26
- <img class="hd-brand__light" src={src(logo.light)} alt="" width="20" height="20" loading="lazy" />
27
- <img class="hd-brand__dark" src={src(logo.dark ?? logo.light)} alt="" width="20" height="20" loading="lazy" />
28
- </span>
44
+ app && (
45
+ <a class="hd-pill hd-pill--ghost hd-site-footer__app" href={app.href}>
46
+ {app.label}
47
+ <Icon name="arrow-up-right" size={16} />
48
+ </a>
29
49
  )
30
50
  }
31
- <span class="hd-brand__name">{data.config.name}</span>
32
- </a>
51
+ {
52
+ socials.length > 0 && (
53
+ <ul class="hd-socials" aria-label="Réseaux">
54
+ {socials.map((social) => (
55
+ <li>
56
+ <a class="hd-icon-button" href={social.href} rel="me noopener" aria-label={social.label} title={social.label}>
57
+ <StarlightIcon name={social.icon as "github"} size="1.1rem" />
58
+ </a>
59
+ </li>
60
+ ))}
61
+ </ul>
62
+ )
63
+ }
64
+ </div>
33
65
  {
34
- socials.length > 0 && (
35
- <ul class="hd-socials" aria-label="Réseaux">
36
- {socials.map((social) => (
37
- <li>
38
- <a class="hd-icon-button" href={social.href} rel="me noopener" aria-label={social.label} title={social.label}>
39
- <StarlightIcon name={social.icon as "github"} size="1.1rem" />
40
- </a>
41
- </li>
66
+ columns.length > 0 && (
67
+ <nav class="hd-site-footer__columns" aria-label="Pied de page">
68
+ {columns.map((column, index) => (
69
+ <div class="hd-site-footer__column">
70
+ {column.header && (
71
+ <h2 class="hd-site-footer__heading" id={`hd-footer-col-${index}`}>
72
+ {column.header}
73
+ </h2>
74
+ )}
75
+ <ul aria-labelledby={column.header ? `hd-footer-col-${index}` : undefined}>
76
+ {column.items.map((item) => (
77
+ <li>
78
+ <a class="hd-site-footer__link" href={withBase(data.base, item.href)}>
79
+ {item.icon && <img src={src(item.icon)} alt="" width="18" height="18" loading="lazy" />}
80
+ <span>{item.label}</span>
81
+ </a>
82
+ </li>
83
+ ))}
84
+ </ul>
85
+ </div>
42
86
  ))}
43
- </ul>
87
+ </nav>
44
88
  )
45
89
  }
46
90
  </div>
47
- <div class="hd-site-footer__row hd-site-footer__row--meta">
48
- {data.config.description && <p>{data.config.description}</p>}
91
+ <div class="hd-site-footer__bottom">
92
+ <p class="hd-site-footer__legal">© {year} {owner}</p>
49
93
  <ThemeToggle variant="segmented" />
50
94
  </div>
51
95
  </footer>
@@ -27,3 +27,8 @@ export function sectionHref(base: string, items: Array<NavItem>): string {
27
27
  export function assistantEnabled(config: DocsConfig): boolean {
28
28
  return Boolean(config.project) && config.assistant?.enabled !== false
29
29
  }
30
+
31
+ /** Bouton vers l'application (`app`) : « Ouvrir <name> » sauf libellé donné. */
32
+ export function appLink(config: DocsConfig): { href: string; label: string } | null {
33
+ return config.app ? { href: config.app.href, label: config.app.label ?? `Ouvrir ${config.name}` } : null
34
+ }
@@ -326,6 +326,30 @@ body {
326
326
  .hd-header__links {
327
327
  display: none;
328
328
  }
329
+ /* « Ouvrir <produit> » : toujours visible, le seul chemin vers l'application. Sur un
330
+ téléphone étroit, le logo seul tient lieu de nom pour lui laisser la place. */
331
+ .hd-app-button {
332
+ height: 2.25rem;
333
+ padding: 0 0.75rem 0 0.875rem;
334
+ gap: 0.25rem;
335
+ margin-inline-start: 0.25rem;
336
+ font-size: 0.8125rem;
337
+ }
338
+ @media (max-width: 29.99em) {
339
+ .hd-header:has(.hd-app-button) .hd-brand:has(.hd-brand__mark) .hd-brand__name {
340
+ display: none;
341
+ }
342
+ }
343
+ @media (min-width: 50em) {
344
+ .hd-app-button {
345
+ padding: 0 0.875rem 0 1rem;
346
+ font-size: 0.875rem;
347
+ }
348
+ }
349
+ .hd-sidebar-app {
350
+ align-self: stretch;
351
+ height: 2.75rem;
352
+ }
329
353
 
330
354
  .hd-brand {
331
355
  display: inline-flex;
@@ -788,25 +812,28 @@ starlight-toc ul ul {
788
812
  }
789
813
  starlight-toc a {
790
814
  display: block;
791
- padding: 0.3rem 0 0.3rem 0.875rem;
792
- border-inline-start: 1px solid var(--hd-border);
815
+ padding: 0.3rem 0;
793
816
  color: var(--hd-muted-fg);
794
817
  font: 400 0.8125rem/1.4 var(--hd-font-sans);
795
818
  text-decoration: none;
796
819
  transition: color 120ms ease;
797
820
  }
798
821
  starlight-toc ul ul a {
799
- margin-inline-start: -0.75rem;
800
- padding-inline-start: 1.625rem;
822
+ margin-inline-start: 0;
823
+ padding-inline-start: 0;
801
824
  }
802
825
  starlight-toc a:hover {
803
826
  color: var(--hd-fg);
804
827
  }
805
828
  starlight-toc a[aria-current="true"] {
806
- border-inline-start-color: var(--hd-accent);
807
829
  color: var(--hd-accent);
808
830
  font-weight: 500;
809
831
  }
832
+ starlight-toc a:focus-visible {
833
+ border-radius: 0.25rem;
834
+ outline: 2px solid var(--hd-accent);
835
+ outline-offset: 2px;
836
+ }
810
837
  starlight-toc a .hd-method {
811
838
  display: none;
812
839
  }
@@ -1811,25 +1838,75 @@ starlight-tabs [role="tabpanel"] {
1811
1838
  /* --- Pied de page du site --- */
1812
1839
 
1813
1840
  .hd-site-footer {
1814
- display: grid;
1815
- gap: 1.25rem;
1816
- margin: 2rem var(--hd-gutter) 0;
1817
- padding: 2rem 0 2.5rem;
1841
+ margin: 3rem var(--hd-gutter) 0;
1842
+ padding: 2.5rem 0 2rem;
1818
1843
  border-top: 1px solid var(--hd-border);
1819
1844
  }
1820
- .hd-site-footer__row {
1845
+ .hd-site-footer__top {
1846
+ display: grid;
1847
+ gap: 2.5rem;
1848
+ }
1849
+ .hd-site-footer__about {
1850
+ display: grid;
1851
+ align-content: start;
1852
+ justify-items: start;
1853
+ gap: 0.875rem;
1854
+ }
1855
+ .hd-site-footer__lede {
1856
+ max-width: 22rem;
1857
+ margin: 0;
1858
+ color: var(--hd-muted-fg);
1859
+ font-size: 0.875rem;
1860
+ line-height: 1.55;
1861
+ }
1862
+ .hd-site-footer__columns {
1863
+ display: grid;
1864
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1865
+ gap: 2rem 1.5rem;
1866
+ }
1867
+ .hd-site-footer__heading {
1868
+ margin: 0 0 0.625rem;
1869
+ color: var(--hd-fg);
1870
+ font: 600 0.8125rem/1.3 var(--hd-font-heading);
1871
+ letter-spacing: -0.005em;
1872
+ }
1873
+ .hd-site-footer__column ul {
1874
+ display: grid;
1875
+ margin: 0;
1876
+ padding: 0;
1877
+ list-style: none;
1878
+ }
1879
+ .hd-site-footer__link {
1880
+ display: inline-flex;
1881
+ align-items: center;
1882
+ gap: 0.5rem;
1883
+ min-height: 2rem;
1884
+ color: var(--hd-muted-fg);
1885
+ font-size: 0.875rem;
1886
+ line-height: 1.35;
1887
+ text-decoration: none;
1888
+ transition: color 150ms ease;
1889
+ }
1890
+ .hd-site-footer__link:hover {
1891
+ color: var(--hd-fg);
1892
+ }
1893
+ .hd-site-footer__link img {
1894
+ flex-shrink: 0;
1895
+ width: 1.125rem;
1896
+ height: 1.125rem;
1897
+ }
1898
+ .hd-site-footer__bottom {
1821
1899
  display: flex;
1822
1900
  flex-wrap: wrap;
1823
1901
  align-items: center;
1824
1902
  justify-content: space-between;
1825
1903
  gap: 1rem;
1904
+ margin-top: 2.5rem;
1826
1905
  }
1827
- .hd-site-footer__row--meta p {
1828
- max-width: 32rem;
1906
+ .hd-site-footer__legal {
1829
1907
  margin: 0;
1830
1908
  color: var(--hd-muted-fg);
1831
- font-size: 0.875rem;
1832
- line-height: 1.55;
1909
+ font-size: 0.8125rem;
1833
1910
  }
1834
1911
  .hd-brand--footer {
1835
1912
  margin-inline-start: -0.5rem;
@@ -1837,6 +1914,21 @@ starlight-tabs [role="tabpanel"] {
1837
1914
  .hd-brand--footer .hd-brand__name {
1838
1915
  font-size: 0.9375rem;
1839
1916
  }
1917
+ /* Trois colonnes au plus tant que le produit est au-dessus : 3 + 2 plutôt que 4 + 1. */
1918
+ @media (min-width: 40em) {
1919
+ .hd-site-footer__columns {
1920
+ grid-template-columns: repeat(auto-fit, minmax(max(8.5rem, 30%), 1fr));
1921
+ }
1922
+ }
1923
+ @media (min-width: 72em) {
1924
+ .hd-site-footer__columns {
1925
+ grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
1926
+ }
1927
+ .hd-site-footer__top {
1928
+ grid-template-columns: minmax(12rem, 15rem) minmax(0, 1fr);
1929
+ gap: 3rem;
1930
+ }
1931
+ }
1840
1932
  .hd-socials {
1841
1933
  display: flex;
1842
1934
  gap: 0.25rem;
@@ -2385,6 +2477,14 @@ hgdc-assistant::before {
2385
2477
 
2386
2478
  /* Cibles tactiles de 44 px au doigt, sans changer le dessin à la souris. */
2387
2479
  @media (pointer: coarse) {
2480
+ .hd-pill,
2481
+ .hd-site-footer__link {
2482
+ min-height: 2.75rem;
2483
+ }
2484
+ .hd-theme-choice button {
2485
+ width: 2.75rem;
2486
+ height: 2.75rem;
2487
+ }
2388
2488
  .hd-nav__link {
2389
2489
  min-height: 2.75rem;
2390
2490
  }