mapshaper 0.7.0 → 0.7.2

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 (89) hide show
  1. package/README.md +5 -3
  2. package/mapshaper.js +363 -62
  3. package/package.json +6 -2
  4. package/www/.nojekyll +0 -0
  5. package/www/assets/jetbrains-mono-regular.woff2 +0 -0
  6. package/www/assets/static-page.css +179 -0
  7. package/www/docs/_assets/cmd-search.js +213 -0
  8. package/www/docs/_assets/docs.css +722 -0
  9. package/www/docs/_assets/docs.js +75 -0
  10. package/www/docs/_assets/highlight.css +10 -0
  11. package/www/docs/essentials/command-line.html +127 -0
  12. package/www/docs/essentials/command-line.html.md +112 -0
  13. package/www/docs/essentials/web-app.html +138 -0
  14. package/www/docs/essentials/web-app.html.md +106 -0
  15. package/www/docs/examples/basics.html +275 -0
  16. package/www/docs/examples/basics.html.md +370 -0
  17. package/www/docs/examples/data/Makefile +31 -0
  18. package/www/docs/examples/data/globe.msx +0 -0
  19. package/www/docs/examples/data/globe.svg +616 -0
  20. package/www/docs/examples/data/globe.txt +21 -0
  21. package/www/docs/examples/data/globe.zip +0 -0
  22. package/www/docs/examples/data/ne_50m_admin_0_countries.geojson +1 -0
  23. package/www/docs/examples/data/ne_50m_admin_1_states_provinces_lakes.geojson +1 -0
  24. package/www/docs/examples/data/us-states.msx +0 -0
  25. package/www/docs/examples/data/us-states.svg +56 -0
  26. package/www/docs/examples/data/us-states.txt +6 -0
  27. package/www/docs/examples/data/us-states.zip +0 -0
  28. package/www/docs/examples/globe.html +108 -0
  29. package/www/docs/examples/globe.html.md +64 -0
  30. package/www/docs/examples/us-states.html +88 -0
  31. package/www/docs/examples/us-states.html.md +44 -0
  32. package/www/docs/formats/csv.html +127 -0
  33. package/www/docs/formats/csv.html.md +97 -0
  34. package/www/docs/formats/dbf.html +87 -0
  35. package/www/docs/formats/dbf.html.md +39 -0
  36. package/www/docs/formats/flatgeobuf.html +85 -0
  37. package/www/docs/formats/flatgeobuf.html.md +41 -0
  38. package/www/docs/formats/geojson.html +107 -0
  39. package/www/docs/formats/geojson.html.md +65 -0
  40. package/www/docs/formats/geopackage.html +87 -0
  41. package/www/docs/formats/geopackage.html.md +42 -0
  42. package/www/docs/formats/json.html +83 -0
  43. package/www/docs/formats/json.html.md +35 -0
  44. package/www/docs/formats/kml.html +82 -0
  45. package/www/docs/formats/kml.html.md +39 -0
  46. package/www/docs/formats/overview.html +191 -0
  47. package/www/docs/formats/overview.html.md +34 -0
  48. package/www/docs/formats/shapefile.html +123 -0
  49. package/www/docs/formats/shapefile.html.md +84 -0
  50. package/www/docs/formats/snapshot.html +87 -0
  51. package/www/docs/formats/snapshot.html.md +39 -0
  52. package/www/docs/formats/svg.html +99 -0
  53. package/www/docs/formats/svg.html.md +51 -0
  54. package/www/docs/formats/topojson.html +102 -0
  55. package/www/docs/formats/topojson.html.md +54 -0
  56. package/www/docs/gallery/index.html +80 -0
  57. package/www/docs/gallery/index.html.md +29 -0
  58. package/www/docs/guides/combining-layers.html +109 -0
  59. package/www/docs/guides/combining-layers.html.md +89 -0
  60. package/www/docs/guides/expressions.html +600 -0
  61. package/www/docs/guides/expressions.html.md +376 -0
  62. package/www/docs/guides/programmatic.html +117 -0
  63. package/www/docs/guides/programmatic.html.md +91 -0
  64. package/www/docs/guides/projections.html +158 -0
  65. package/www/docs/guides/projections.html.md +118 -0
  66. package/www/docs/guides/simplification.html +110 -0
  67. package/www/docs/guides/simplification.html.md +96 -0
  68. package/www/docs/guides/topology.html +90 -0
  69. package/www/docs/guides/topology.html.md +63 -0
  70. package/www/docs/images/cal-counties.png +0 -0
  71. package/www/docs/images/simplification-detail.png +0 -0
  72. package/www/docs/images/simplification-dp.png +0 -0
  73. package/www/docs/images/simplification-mod2.png +0 -0
  74. package/www/docs/images/tiger-counties.png +0 -0
  75. package/www/docs/index.html +101 -0
  76. package/www/docs/index.html.md +59 -0
  77. package/www/docs/reference.html +1302 -0
  78. package/www/docs/reference.html.md +1817 -0
  79. package/www/docs/whats-new.html +77 -0
  80. package/www/docs/whats-new.html.md +59 -0
  81. package/www/index.html +47 -4
  82. package/www/llms-full.txt +4053 -0
  83. package/www/llms.txt +55 -0
  84. package/www/mapshaper-gui.js +299 -5
  85. package/www/mapshaper.js +363 -62
  86. package/www/page.css +189 -11
  87. package/www/privacy.html +1 -112
  88. package/www/sponsor.html +4 -164
  89. package/www/terms.html +1 -112
@@ -0,0 +1,722 @@
1
+ /* Mapshaper docs site
2
+ * Reuses the look-and-feel of mapshaper.org (page.css):
3
+ * primary blue: #1385B7 accent: #10699b bg: #f8fdff
4
+ */
5
+
6
+ @font-face {
7
+ font-family: 'SourceSans3';
8
+ src: url('/assets/SourceSans3-VariableFont_wght.ttf') format('truetype');
9
+ font-display: swap;
10
+ }
11
+
12
+ @font-face {
13
+ font-family: 'JetBrains Mono';
14
+ src: url('/assets/jetbrains-mono-regular.woff2') format('woff2');
15
+ font-weight: 400;
16
+ font-style: normal;
17
+ font-display: swap;
18
+ }
19
+
20
+ * { box-sizing: border-box; }
21
+
22
+ html, body {
23
+ margin: 0;
24
+ padding: 0;
25
+ background-color: #f8fdff;
26
+ color: #333;
27
+ font: 16px/1.55 'SourceSans3', Arial, sans-serif;
28
+ }
29
+
30
+ a { color: #10699b; text-decoration: none; }
31
+ a:hover { color: #1A6A96; text-decoration: underline; }
32
+
33
+ code, pre, .mono {
34
+ font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
35
+ font-size: 0.88em;
36
+ }
37
+
38
+ /* --- Header ---------------------------------------------------------- */
39
+
40
+ .page-header {
41
+ background-color: #1385B7;
42
+ color: white;
43
+ /* Asymmetric vertical padding (4px top, 8px bottom) optically centers the
44
+ baseline-aligned row: ascenders are taller than descenders, so equal
45
+ padding makes the text look ~2px low. */
46
+ padding: 2px 14px 8px;
47
+ height: 32px;
48
+ display: flex;
49
+ /* baseline-align so the 18px logo and the 14px nav text share a baseline,
50
+ not just a vertical center */
51
+ align-items: baseline;
52
+ gap: 14px;
53
+ }
54
+
55
+ .mapshaper-logo,
56
+ .mapshaper-logo:hover {
57
+ font-weight: 600;
58
+ font-size: 18px;
59
+ color: white;
60
+ text-decoration: none;
61
+ }
62
+
63
+ .mapshaper-logo .logo-highlight { color: #ffa; }
64
+
65
+ .header-section-label {
66
+ font-weight: 400;
67
+ font-size: 14px;
68
+ color: rgba(255,255,255,0.85);
69
+ border-left: 1px solid rgba(255,255,255,0.3);
70
+ padding-left: 14px;
71
+ }
72
+
73
+ .header-nav {
74
+ margin-left: auto;
75
+ display: flex;
76
+ gap: 4px;
77
+ }
78
+
79
+ .header-nav a,
80
+ .header-nav a:hover {
81
+ color: white;
82
+ text-decoration: none;
83
+ font-size: 14px;
84
+ /* line-height: 1 keeps each anchor's hover background tight enough to fit
85
+ inside the 36px header once the row is baseline-aligned. */
86
+ line-height: 1;
87
+ padding: 6px 6px;
88
+ border-radius: 3px;
89
+ }
90
+
91
+ .header-nav a:hover { background-color: rgba(255,255,255,0.15); }
92
+
93
+ .header-nav a.sponsor-link,
94
+ .header-nav a.sponsor-link:hover { color: #ffa; }
95
+
96
+ .header-nav a.sponsor-link svg {
97
+ width: 12px;
98
+ height: 12px;
99
+ fill: currentColor;
100
+ vertical-align: -1px;
101
+ margin-right: 2px;
102
+ }
103
+
104
+ /* --- Layout ---------------------------------------------------------- */
105
+
106
+ .docs-layout {
107
+ display: grid;
108
+ grid-template-columns: 240px minmax(0, 1fr) 220px;
109
+ gap: 32px;
110
+ max-width: 1280px;
111
+ margin: 0 auto;
112
+ padding: 24px;
113
+ align-items: start;
114
+ }
115
+
116
+ .docs-sidebar {
117
+ position: sticky;
118
+ top: 24px;
119
+ align-self: start;
120
+ max-height: calc(100vh - 48px);
121
+ overflow-y: auto;
122
+ }
123
+
124
+ .sidebar-inner { padding-right: 8px; }
125
+
126
+ .docs-main { min-width: 0; }
127
+
128
+ .docs-article {
129
+ background: #fff;
130
+ border: 1px solid #e0e8ec;
131
+ border-radius: 4px;
132
+ padding: 28px 36px 36px;
133
+ }
134
+
135
+ .docs-toc {
136
+ position: sticky;
137
+ top: 24px;
138
+ align-self: start;
139
+ max-height: calc(100vh - 48px);
140
+ overflow-y: auto;
141
+ font-size: 14px;
142
+ }
143
+
144
+ @media (max-width: 1080px) {
145
+ .docs-layout { grid-template-columns: 220px minmax(0, 1fr); }
146
+ .docs-toc { display: none; }
147
+ }
148
+
149
+ @media (max-width: 720px) {
150
+ .docs-layout {
151
+ grid-template-columns: 1fr;
152
+ padding: 16px;
153
+ gap: 16px;
154
+ }
155
+ .docs-sidebar { position: static; max-height: none; }
156
+ .docs-article { padding: 20px; }
157
+ }
158
+
159
+ /* --- Sidebar nav ----------------------------------------------------- */
160
+
161
+ .docs-nav h2 {
162
+ font-size: 11px;
163
+ text-transform: uppercase;
164
+ letter-spacing: 0.06em;
165
+ color: #888;
166
+ margin: 18px 0 6px;
167
+ font-weight: 600;
168
+ }
169
+
170
+ .docs-nav ul { list-style: none; padding: 0; margin: 0; }
171
+
172
+ .docs-nav li { margin: 0; }
173
+
174
+ .docs-nav a {
175
+ display: block;
176
+ /* Asymmetric vertical padding (6px top, 2px bottom) optically centers
177
+ the text inside the active/hover background. */
178
+ padding: 5px 8px 2px;
179
+ border-radius: 3px;
180
+ color: #333;
181
+ font-size: 14px;
182
+ }
183
+
184
+ .docs-nav a:hover {
185
+ background-color: #eaf3f7;
186
+ color: #10699b;
187
+ text-decoration: none;
188
+ }
189
+
190
+ .docs-nav a.is-active {
191
+ background-color: #1385B7;
192
+ color: white;
193
+ font-weight: 600;
194
+ }
195
+
196
+ .docs-nav .top-links { margin-bottom: 18px; }
197
+ .docs-nav .top-links a { font-weight: 600; }
198
+
199
+ /* --- TOC ------------------------------------------------------------- */
200
+
201
+ .docs-toc-title {
202
+ font-size: 11px;
203
+ text-transform: uppercase;
204
+ letter-spacing: 0.06em;
205
+ color: #888;
206
+ margin: 0 0 8px;
207
+ font-weight: 600;
208
+ }
209
+
210
+ .docs-toc ul { list-style: none; padding: 0; margin: 0; }
211
+
212
+ .docs-toc li { margin: 2px 0; }
213
+
214
+ .docs-toc a {
215
+ color: #555;
216
+ display: block;
217
+ padding: 2px 6px;
218
+ border-left: 2px solid transparent;
219
+ line-height: 1.35;
220
+ }
221
+
222
+ .docs-toc a:hover {
223
+ color: #10699b;
224
+ border-left-color: #10699b;
225
+ text-decoration: none;
226
+ }
227
+
228
+ .docs-toc .lvl-3 { padding-left: 14px; font-size: 13px; }
229
+
230
+ /* --- Article content ------------------------------------------------- */
231
+
232
+ .docs-article h1 {
233
+ font-size: 32px;
234
+ font-weight: 600;
235
+ margin: 0 0 6px;
236
+ color: #1f2d33;
237
+ line-height: 1.2;
238
+ }
239
+
240
+ .docs-article > .lead {
241
+ font-size: 17px;
242
+ color: #555;
243
+ margin: 0 0 24px;
244
+ }
245
+
246
+ .docs-article h2 {
247
+ font-size: 22px;
248
+ font-weight: 600;
249
+ margin: 32px 0 10px;
250
+ padding-top: 8px;
251
+ color: #1f2d33;
252
+ border-top: 1px solid #eaeef0;
253
+ scroll-margin-top: 24px;
254
+ }
255
+
256
+ .docs-article h2:first-child,
257
+ .docs-article h2:first-of-type:not(:first-child) { /* keep simple */ }
258
+
259
+ .docs-article h3 {
260
+ font-size: 17px;
261
+ font-weight: 600;
262
+ margin: 22px 0 8px;
263
+ color: #1f2d33;
264
+ scroll-margin-top: 24px;
265
+ }
266
+
267
+ .docs-article h4 {
268
+ font-size: 15px;
269
+ font-weight: 600;
270
+ margin: 18px 0 6px;
271
+ color: #1f2d33;
272
+ }
273
+
274
+ .docs-article p { margin: 10px 0; }
275
+
276
+ .docs-article ul,
277
+ .docs-article ol { margin: 10px 0; padding-left: 22px; }
278
+
279
+ .docs-article li { margin: 4px 0; }
280
+
281
+ .docs-article code {
282
+ background-color: #f3f6f8;
283
+ padding: 1px 5px;
284
+ border-radius: 3px;
285
+ border: 1px solid #e6ecef;
286
+ white-space: nowrap;
287
+ }
288
+
289
+ .docs-article pre {
290
+ background-color: #1e2a30;
291
+ color: #e9eef1;
292
+ padding: 14px 16px;
293
+ border-radius: 4px;
294
+ overflow-x: auto;
295
+ line-height: 1.5;
296
+ }
297
+
298
+ /* --- Copy-to-clipboard button on code blocks ------------------------- */
299
+
300
+ .docs-article pre.has-copy-btn { position: relative; }
301
+
302
+ .copy-btn {
303
+ position: absolute;
304
+ top: 6px;
305
+ right: 6px;
306
+ padding: 3px 8px;
307
+ font: inherit;
308
+ font-size: 11px;
309
+ line-height: 1.2;
310
+ color: #cdd6da;
311
+ background-color: rgba(255,255,255,0.08);
312
+ border: 1px solid rgba(255,255,255,0.18);
313
+ border-radius: 3px;
314
+ cursor: pointer;
315
+ transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
316
+ }
317
+
318
+ .copy-btn:hover,
319
+ .copy-btn:focus {
320
+ background-color: rgba(255,255,255,0.18);
321
+ color: #fff;
322
+ outline: none;
323
+ }
324
+
325
+ .copy-btn.is-flashing {
326
+ color: #cdeac8;
327
+ border-color: rgba(180, 230, 160, 0.4);
328
+ }
329
+
330
+ .docs-article pre code {
331
+ background: transparent;
332
+ border: 0;
333
+ padding: 0;
334
+ white-space: pre;
335
+ color: inherit;
336
+ }
337
+
338
+ /* highlight.js theme overrides:
339
+ * Use the theme's per-token colors but keep our own pre/code background and
340
+ * padding (the theme would otherwise paint a different shade of dark behind
341
+ * the code and add inconsistent padding). */
342
+ .docs-article pre code.hljs,
343
+ .docs-article code.hljs {
344
+ background: transparent;
345
+ padding: 0;
346
+ color: inherit;
347
+ }
348
+
349
+ .docs-article blockquote {
350
+ border-left: 3px solid #1385B7;
351
+ margin: 14px 0;
352
+ padding: 4px 14px;
353
+ color: #444;
354
+ background-color: #f3f8fb;
355
+ }
356
+
357
+ .docs-article table {
358
+ border-collapse: collapse;
359
+ margin: 14px 0;
360
+ font-size: 14px;
361
+ }
362
+
363
+ .docs-article th,
364
+ .docs-article td {
365
+ border: 1px solid #e0e8ec;
366
+ padding: 6px 10px;
367
+ text-align: left;
368
+ vertical-align: top;
369
+ }
370
+
371
+ .docs-article th { background-color: #f3f6f8; font-weight: 600; }
372
+
373
+ /* Wrapper for wide tables (e.g. the formats comparison matrix) so they
374
+ * scroll horizontally instead of overflowing the article on narrow screens. */
375
+ .formats-table-wrap { overflow-x: auto; }
376
+ .formats-table-wrap table { margin: 14px 0; }
377
+
378
+ .docs-article hr {
379
+ border: 0;
380
+ border-top: 1px solid #e0e8ec;
381
+ margin: 28px 0;
382
+ }
383
+
384
+ /* Breadcrumbs */
385
+ .docs-breadcrumbs {
386
+ font-size: 13px;
387
+ color: #888;
388
+ margin: 0 0 14px;
389
+ }
390
+
391
+ .docs-breadcrumbs a { color: #10699b; }
392
+
393
+ /* Edit link footer */
394
+ .edit-link {
395
+ margin-top: 36px;
396
+ padding-top: 14px;
397
+ border-top: 1px solid #eaeef0;
398
+ font-size: 13px;
399
+ color: #888;
400
+ }
401
+
402
+ /* --- Home page ------------------------------------------------------- */
403
+
404
+ body.is-home .docs-article { padding: 32px 40px 40px; }
405
+
406
+ .section-cards {
407
+ display: grid;
408
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
409
+ gap: 14px;
410
+ margin: 24px 0 12px;
411
+ }
412
+
413
+ .section-card {
414
+ display: block;
415
+ border: 1px solid #d9e3e8;
416
+ border-radius: 4px;
417
+ padding: 16px 18px;
418
+ background-color: #fff;
419
+ color: inherit;
420
+ transition: border-color 0.1s, box-shadow 0.1s;
421
+ }
422
+
423
+ .section-card:hover {
424
+ border-color: #1385B7;
425
+ box-shadow: 0 1px 4px rgba(19, 133, 183, 0.12);
426
+ text-decoration: none;
427
+ color: inherit;
428
+ }
429
+
430
+ .section-card .card-title {
431
+ font-weight: 600;
432
+ font-size: 16px;
433
+ color: #1f2d33;
434
+ margin: 0 0 4px;
435
+ }
436
+
437
+ .section-card .card-desc {
438
+ font-size: 14px;
439
+ color: #555;
440
+ margin: 0;
441
+ }
442
+
443
+ .quickstart {
444
+ background-color: #1e2a30;
445
+ color: #e9eef1;
446
+ border-radius: 4px;
447
+ padding: 18px 20px;
448
+ margin: 24px 0;
449
+ }
450
+
451
+ .quickstart h3 {
452
+ margin: 0 0 8px;
453
+ font-size: 14px;
454
+ text-transform: uppercase;
455
+ letter-spacing: 0.06em;
456
+ color: #9ec3d4;
457
+ font-weight: 600;
458
+ }
459
+
460
+ .quickstart pre {
461
+ margin: 0;
462
+ background: transparent;
463
+ padding: 0;
464
+ }
465
+
466
+ /* --- Command-reference search ---------------------------------------- */
467
+
468
+ .cmd-search-wrap {
469
+ position: sticky;
470
+ top: 0;
471
+ z-index: 10;
472
+ background-color: #fff;
473
+ /* break out of the article's padding so the bottom border spans full width */
474
+ margin: 0 -36px 18px;
475
+ padding: 12px 36px 10px;
476
+ border-bottom: 1px solid #eaeef0;
477
+ }
478
+
479
+ .cmd-search-input {
480
+ width: 100%;
481
+ padding: 8px 12px;
482
+ font-family: inherit;
483
+ font-size: 15px;
484
+ color: inherit;
485
+ background-color: #fff;
486
+ border: 1px solid #c8d4d9;
487
+ border-radius: 4px;
488
+ -webkit-appearance: none;
489
+ appearance: none;
490
+ }
491
+
492
+ .cmd-search-input:focus {
493
+ outline: none;
494
+ border-color: #1385B7;
495
+ box-shadow: 0 0 0 3px rgba(19, 133, 183, 0.2);
496
+ }
497
+
498
+ /* Floating dropdown of matching commands. Positioned just below the input
499
+ * within the sticky wrap, so it overlays page content rather than pushing
500
+ * sections out of the way. */
501
+ .cmd-search-results {
502
+ position: absolute;
503
+ left: 36px;
504
+ right: 36px;
505
+ top: 100%;
506
+ margin-top: 4px;
507
+ background-color: #fff;
508
+ border: 1px solid #c8d4d9;
509
+ border-radius: 4px;
510
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
511
+ overflow: hidden;
512
+ }
513
+
514
+ .cmd-search-status {
515
+ font-size: 13px;
516
+ color: #6a7a82;
517
+ padding: 6px 12px;
518
+ background-color: #f4f8fa;
519
+ border-bottom: 1px solid #eaeef0;
520
+ }
521
+
522
+ .cmd-search-list {
523
+ list-style: none;
524
+ margin: 0;
525
+ padding: 4px 0;
526
+ max-height: 360px;
527
+ overflow-y: auto;
528
+ }
529
+
530
+ .cmd-result {
531
+ margin: 0;
532
+ }
533
+
534
+ .cmd-result-link {
535
+ display: flex;
536
+ align-items: baseline;
537
+ gap: 12px;
538
+ padding: 6px 12px;
539
+ color: inherit;
540
+ text-decoration: none;
541
+ cursor: pointer;
542
+ }
543
+
544
+ .cmd-result-link:hover {
545
+ text-decoration: none;
546
+ }
547
+
548
+ .cmd-result.is-active .cmd-result-link {
549
+ background-color: #e8f3f9;
550
+ color: #10699b;
551
+ }
552
+
553
+ .cmd-result-name {
554
+ font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
555
+ font-size: 0.92em;
556
+ color: #10699b;
557
+ white-space: nowrap;
558
+ }
559
+
560
+ .cmd-result.is-active .cmd-result-name {
561
+ color: inherit;
562
+ }
563
+
564
+ .cmd-result-cat {
565
+ margin-left: auto;
566
+ font-size: 12px;
567
+ color: #8a9aa3;
568
+ white-space: nowrap;
569
+ }
570
+
571
+ /* When the user clicks an anchor on the command reference page, leave room
572
+ * for the sticky search bar above the target heading so it doesn't end up
573
+ * hidden behind the bar. The :has() selector scopes the rule to the
574
+ * command reference article (the only one with a .cmd-search-wrap), so
575
+ * every id'd heading in that article -- including the prose headings
576
+ * above the first command (Conventions, Common options, Command files,
577
+ * Variable interpolation, Index of commands) -- gets the offset.
578
+ * scroll-margin-top has to live on the actual scroll target, which is the
579
+ * heading itself (the id is on the h2/h3/h4, not the wrapping section). */
580
+ .docs-article:has(.cmd-search-wrap) :is(h2, h3, h4)[id],
581
+ .docs-article:has(.cmd-search-wrap) .cmd-section {
582
+ scroll-margin-top: 76px;
583
+ }
584
+
585
+ @media (max-width: 720px) {
586
+ .cmd-search-wrap { margin: 0 -20px 14px; padding: 10px 20px 8px; }
587
+ .cmd-search-results { left: 20px; right: 20px; }
588
+ .docs-article:has(.cmd-search-wrap) :is(h2, h3, h4)[id],
589
+ .docs-article:has(.cmd-search-wrap) .cmd-section {
590
+ scroll-margin-top: 64px;
591
+ }
592
+ }
593
+
594
+ /* --- Gallery -------------------------------------------------------- */
595
+
596
+ .gallery-grid {
597
+ display: grid;
598
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
599
+ gap: 18px;
600
+ margin: 20px 0 28px;
601
+ }
602
+
603
+ .gallery-tile {
604
+ display: flex;
605
+ flex-direction: column;
606
+ border: 1px solid #d9e3e8;
607
+ border-radius: 4px;
608
+ background-color: #fff;
609
+ color: inherit;
610
+ overflow: hidden;
611
+ transition: border-color 0.1s, box-shadow 0.1s;
612
+ }
613
+
614
+ .gallery-tile:hover {
615
+ border-color: #1385B7;
616
+ box-shadow: 0 2px 8px rgba(19, 133, 183, 0.15);
617
+ text-decoration: none;
618
+ color: inherit;
619
+ }
620
+
621
+ .gallery-tile-image {
622
+ background-color: #f3f6f8;
623
+ aspect-ratio: 3 / 2;
624
+ display: flex;
625
+ align-items: center;
626
+ justify-content: center;
627
+ overflow: hidden;
628
+ }
629
+
630
+ .gallery-tile-image img {
631
+ width: 100%;
632
+ height: 100%;
633
+ object-fit: contain;
634
+ display: block;
635
+ }
636
+
637
+ .gallery-tile-caption {
638
+ padding: 12px 14px 14px;
639
+ }
640
+
641
+ .gallery-tile-title {
642
+ font-weight: 600;
643
+ font-size: 15px;
644
+ color: #1f2d33;
645
+ margin: 0 0 4px;
646
+ }
647
+
648
+ .gallery-tile-desc {
649
+ font-size: 13px;
650
+ color: #555;
651
+ line-height: 1.4;
652
+ }
653
+
654
+ /* Home-page featured strip: same tile look, smaller grid, no descriptions. */
655
+ .featured-maps {
656
+ display: grid;
657
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
658
+ gap: 14px;
659
+ margin: 16px 0 8px;
660
+ }
661
+
662
+ .featured-maps .gallery-tile-image { aspect-ratio: 3 / 2; }
663
+ .featured-maps .gallery-tile-caption { padding: 10px 12px 12px; }
664
+ .featured-maps .gallery-tile-title { font-size: 14px; }
665
+
666
+ .featured-maps-link {
667
+ margin: 0 0 16px;
668
+ font-size: 14px;
669
+ }
670
+
671
+ /* Example-page hero image: the <img> emitted by <!-- mapshaper:image -->.
672
+ * Targets the first paragraph that contains a single image inside an article.
673
+ * Keeps the image full-width but capped, with a subtle frame to match tiles. */
674
+ .docs-article .example-hero,
675
+ .docs-article p > img:only-child {
676
+ display: block;
677
+ max-width: 100%;
678
+ height: auto;
679
+ margin: 16px auto;
680
+ background-color: #f3f6f8;
681
+ border: 1px solid #e0e8ec;
682
+ border-radius: 4px;
683
+ }
684
+
685
+ /* What's-new entries */
686
+ .whats-new-entry {
687
+ border-left: 3px solid #1385B7;
688
+ padding: 4px 14px;
689
+ margin: 18px 0;
690
+ background-color: #f3f8fb;
691
+ }
692
+
693
+ .whats-new-entry .date {
694
+ font-size: 13px;
695
+ color: #777;
696
+ font-weight: 600;
697
+ text-transform: uppercase;
698
+ letter-spacing: 0.04em;
699
+ }
700
+
701
+ /* --- Footer ---------------------------------------------------------- */
702
+
703
+ .docs-footer {
704
+ border-top: 1px solid #e0e8ec;
705
+ margin-top: 24px;
706
+ padding: 16px 0;
707
+ background-color: #fff;
708
+ }
709
+
710
+ .docs-footer-inner {
711
+ max-width: 1280px;
712
+ margin: 0 auto;
713
+ padding: 0 24px;
714
+ display: flex;
715
+ justify-content: space-between;
716
+ flex-wrap: wrap;
717
+ gap: 12px;
718
+ font-size: 13px;
719
+ color: #777;
720
+ }
721
+
722
+ .docs-footer a { color: #777; }