@plus234feed/ds 0.4.0 → 0.6.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/components.css +115 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plus234feed/ds",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Plus234Feed design system. Editorial tokens, type scale and components for a news intelligence platform: newspaper hierarchy, accessible colour in both themes, one component per job.",
5
5
  "keywords": [
6
6
  "design-system",
@@ -315,8 +315,17 @@
315
315
  max-width: var(--p234-measure-text);
316
316
  }
317
317
  .p234-prose > * + * { margin-top: var(--p234-space-5); }
318
- .p234-prose a { color: var(--p234-color-link); text-underline-offset: 2px; }
319
- .p234-prose a:visited { color: var(--p234-color-link-visited); }
318
+ /* Links in running text, but not links that are already a component.
319
+ *
320
+ * `.p234-prose a` is a class and a type, which outranks the single class on
321
+ * `.p234-btn`, so without this guard a button inside prose takes the link
322
+ * colour: brand green text on a brand green fill, which renders as an empty
323
+ * green rectangle. The same applied to a tag, a toggle and a directory row.
324
+ *
325
+ * Excluding anything that carries a p234- class keeps the component in charge
326
+ * of its own colour, which is the rule everywhere else in here. */
327
+ .p234-prose a:not([class*="p234-"]) { color: var(--p234-color-link); text-underline-offset: 2px; }
328
+ .p234-prose a:not([class*="p234-"]):visited { color: var(--p234-color-link-visited); }
320
329
  .p234-prose blockquote {
321
330
  font-family: var(--p234-type-quote-family);
322
331
  font-size: var(--p234-type-quote-size);
@@ -328,6 +337,91 @@
328
337
  color: var(--p234-color-ink);
329
338
  }
330
339
 
340
+ /* Headings, lists and small print, styled on the element itself.
341
+ *
342
+ * An article body arrives as markup from the pipeline and a policy page is
343
+ * written by hand, but both are the same thing: a document. Styling the
344
+ * element rather than a class is what lets a page body be plain semantic
345
+ * HTML, which is also the only version of these pages anyone will maintain.
346
+ *
347
+ * Section headings carry a hairline above instead of sitting in a bordered
348
+ * box. A page of eight boxes reads as eight unrelated panels; a page of eight
349
+ * ruled sections reads as one document, which is what it is. */
350
+ .p234-prose h2 {
351
+ font-family: var(--p234-type-headline-sm-family);
352
+ font-size: var(--p234-type-headline-sm-size);
353
+ line-height: var(--p234-type-headline-sm-leading);
354
+ letter-spacing: var(--p234-type-headline-sm-tracking);
355
+ font-weight: var(--p234-type-headline-sm-weight);
356
+ color: var(--p234-color-ink);
357
+ border-top: var(--p234-border-hairline) solid var(--p234-color-rule);
358
+ padding-top: var(--p234-space-4);
359
+ }
360
+ .p234-prose > * + h2 { margin-top: var(--p234-space-7); }
361
+
362
+ .p234-prose h3 {
363
+ font-family: var(--p234-type-headline-xs-family);
364
+ font-size: var(--p234-type-headline-xs-size);
365
+ line-height: var(--p234-type-headline-xs-leading);
366
+ letter-spacing: var(--p234-type-headline-xs-tracking);
367
+ font-weight: var(--p234-type-headline-xs-weight);
368
+ color: var(--p234-color-ink);
369
+ }
370
+ .p234-prose > * + h3 { margin-top: var(--p234-space-6); }
371
+
372
+ /* A heading followed straight by its own text should not carry a full gap:
373
+ the two belong together. */
374
+ .p234-prose h2 + *,
375
+ .p234-prose h3 + * { margin-top: var(--p234-space-3); }
376
+
377
+ .p234-prose ul,
378
+ .p234-prose ol { padding-left: var(--p234-space-6); }
379
+ .p234-prose ul { list-style: disc; }
380
+ .p234-prose ol { list-style: decimal; }
381
+ .p234-prose li + li { margin-top: var(--p234-space-3); }
382
+ .p234-prose li::marker { color: var(--p234-color-ink-subtle); }
383
+
384
+ .p234-prose strong { font-weight: 700; }
385
+ .p234-prose em { font-style: italic; }
386
+ .p234-prose hr {
387
+ border: 0;
388
+ border-top: var(--p234-border-hairline) solid var(--p234-color-rule);
389
+ }
390
+ .p234-prose code {
391
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
392
+ font-size: 0.9em;
393
+ background: var(--p234-color-paper-sunk);
394
+ padding: 0.1em 0.3em;
395
+ border-radius: var(--p234-radius-sm);
396
+ }
397
+ .p234-prose pre {
398
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
399
+ font-size: var(--p234-type-ui-sm-size);
400
+ line-height: 1.55;
401
+ background: var(--p234-color-paper-sunk);
402
+ border: var(--p234-border-hairline) solid var(--p234-color-rule);
403
+ border-radius: var(--p234-radius-sm);
404
+ padding: var(--p234-space-4);
405
+ overflow-x: auto;
406
+ }
407
+ .p234-prose pre code { background: none; padding: 0; }
408
+
409
+ /* The line under a document: last updated, a version, a notice. */
410
+ .p234-prose small {
411
+ display: block;
412
+ font-family: var(--p234-type-meta-family);
413
+ font-size: var(--p234-type-meta-size);
414
+ line-height: var(--p234-type-meta-leading);
415
+ color: var(--p234-color-ink-muted);
416
+ }
417
+
418
+ /* A document page is a column of sections, not a reading column of 66
419
+ characters: its lists and definition rows want the wider measure. */
420
+ .p234-prose--document { max-width: var(--p234-measure-wide); }
421
+ .p234-prose--document > p,
422
+ .p234-prose--document > ul,
423
+ .p234-prose--document > ol { max-width: var(--p234-measure-text); }
424
+
331
425
  /* --- ad slot -----------------------------------------------------------
332
426
  Declared, labelled and bounded. The article template allows two of these,
333
427
  total. The count is a design decision, not an inventory decision: at six
@@ -376,7 +470,10 @@
376
470
  font-weight: 700;
377
471
  color: var(--p234-color-brand);
378
472
  }
379
- .p234-nextstep a {
473
+ /* Same guard as prose: a link that is already a component keeps its own
474
+ colour. Without it a button or tag dropped into this box would be styled
475
+ as one of the box's own link rows. */
476
+ .p234-nextstep a:not([class*="p234-"]) {
380
477
  font-family: var(--p234-type-headline-xs-family);
381
478
  font-size: var(--p234-type-headline-xs-size);
382
479
  line-height: var(--p234-type-headline-xs-leading);
@@ -384,7 +481,7 @@
384
481
  color: var(--p234-color-ink);
385
482
  text-decoration: none;
386
483
  }
387
- .p234-nextstep a:hover { text-decoration: underline; text-underline-offset: 2px; }
484
+ .p234-nextstep a:not([class*="p234-"]):hover { text-decoration: underline; text-underline-offset: 2px; }
388
485
 
389
486
  /* --- breadcrumb --------------------------------------------------------
390
487
  34 files hand-roll this today, each with its own separator and spacing. */
@@ -408,8 +505,8 @@
408
505
  content: "/";
409
506
  color: var(--p234-color-rule-strong);
410
507
  }
411
- .p234-breadcrumb a { color: var(--p234-color-ink-muted); text-decoration: none; }
412
- .p234-breadcrumb a:hover { color: var(--p234-color-ink); text-decoration: underline; text-underline-offset: 2px; }
508
+ .p234-breadcrumb a:not([class*="p234-"]) { color: var(--p234-color-ink-muted); text-decoration: none; }
509
+ .p234-breadcrumb a:not([class*="p234-"]):hover { color: var(--p234-color-ink); text-decoration: underline; text-underline-offset: 2px; }
413
510
  .p234-breadcrumb [aria-current="page"] { color: var(--p234-color-ink); }
414
511
 
415
512
  /* --- figure ------------------------------------------------------------
@@ -626,7 +723,7 @@
626
723
  justify-content: center;
627
724
  gap: var(--p234-space-5);
628
725
  }
629
- .p234-masthead__editions a {
726
+ .p234-masthead__editions a:not([class*="p234-"]) {
630
727
  font-family: var(--p234-type-ui-sm-family);
631
728
  font-size: var(--p234-type-ui-sm-size);
632
729
  font-weight: 600;
@@ -637,7 +734,7 @@
637
734
  white-space: nowrap;
638
735
  }
639
736
  .p234-masthead__editions a:hover,
640
- .p234-masthead__editions a[aria-current] { color: var(--p234-color-ink); }
737
+ .p234-masthead__editions a:not([class*="p234-"])[aria-current] { color: var(--p234-color-ink); }
641
738
 
642
739
  /* Row 2: the wordmark, centred. */
643
740
  .p234-masthead__bar {
@@ -755,13 +852,13 @@
755
852
  }
756
853
  .p234-megamenu ul { list-style: none; margin: 0; padding: 0; }
757
854
  .p234-megamenu li { margin-bottom: var(--p234-space-4); }
758
- .p234-megamenu a {
855
+ .p234-megamenu a:not([class*="p234-"]) {
759
856
  font-family: var(--p234-type-ui-family);
760
857
  font-size: var(--p234-type-ui-size);
761
858
  color: var(--p234-color-ink);
762
859
  text-decoration: none;
763
860
  }
764
- .p234-megamenu a:hover { text-decoration: underline; text-underline-offset: 2px; }
861
+ .p234-megamenu a:not([class*="p234-"]):hover { text-decoration: underline; text-underline-offset: 2px; }
765
862
 
766
863
  /* The phone drawer: a full screen panel, search first, then the sections as
767
864
  accordions. <details> so it works with no JavaScript. */
@@ -795,7 +892,7 @@
795
892
  gap: var(--p234-space-4);
796
893
  padding-bottom: var(--p234-space-5);
797
894
  }
798
- .p234-drawer__links a {
895
+ .p234-drawer__links a:not([class*="p234-"]) {
799
896
  font-family: var(--p234-type-ui-family);
800
897
  font-size: var(--p234-type-ui-size);
801
898
  color: var(--p234-color-ink);
@@ -820,7 +917,7 @@
820
917
  max-width: var(--p234-layout-container);
821
918
  margin-inline: auto;
822
919
  }
823
- .p234-subnav a {
920
+ .p234-subnav a:not([class*="p234-"]) {
824
921
  display: block;
825
922
  font-family: var(--p234-type-ui-sm-family);
826
923
  font-size: var(--p234-type-ui-sm-size);
@@ -832,8 +929,8 @@
832
929
  border-bottom: var(--p234-border-thick) solid transparent;
833
930
  margin-bottom: -1px;
834
931
  }
835
- .p234-subnav a:hover { color: var(--p234-color-ink); }
836
- .p234-subnav a[aria-current] {
932
+ .p234-subnav a:not([class*="p234-"]):hover { color: var(--p234-color-ink); }
933
+ .p234-subnav a:not([class*="p234-"])[aria-current] {
837
934
  color: var(--p234-color-ink);
838
935
  border-bottom-color: var(--p234-color-brand);
839
936
  }
@@ -899,13 +996,13 @@
899
996
  }
900
997
  .p234-footer ul { list-style: none; margin: 0; padding: 0; }
901
998
  .p234-footer li { margin-bottom: var(--p234-space-3); }
902
- .p234-footer a {
999
+ .p234-footer a:not([class*="p234-"]) {
903
1000
  font-family: var(--p234-type-ui-sm-family);
904
1001
  font-size: var(--p234-type-ui-sm-size);
905
1002
  color: var(--p234-color-ink);
906
1003
  text-decoration: none;
907
1004
  }
908
- .p234-footer a:hover { text-decoration: underline; text-underline-offset: 2px; }
1005
+ .p234-footer a:not([class*="p234-"]):hover { text-decoration: underline; text-underline-offset: 2px; }
909
1006
  .p234-footer__legal {
910
1007
  border-top: var(--p234-border-hairline) solid var(--p234-color-rule);
911
1008
  padding-top: var(--p234-space-5);
@@ -1465,7 +1562,7 @@ textarea.p234-field__control {
1465
1562
  margin: 0;
1466
1563
  padding: 0;
1467
1564
  }
1468
- .p234-linkgrid a {
1565
+ .p234-linkgrid a:not([class*="p234-"]) {
1469
1566
  display: block;
1470
1567
  border-top: var(--p234-border-thick) solid var(--p234-color-ink);
1471
1568
  padding-top: var(--p234-space-3);
@@ -1475,7 +1572,7 @@ textarea.p234-field__control {
1475
1572
  color: var(--p234-color-ink);
1476
1573
  text-decoration: none;
1477
1574
  }
1478
- .p234-linkgrid a:hover { color: var(--p234-color-brand); }
1575
+ .p234-linkgrid a:not([class*="p234-"]):hover { color: var(--p234-color-brand); }
1479
1576
  .p234-linkgrid__count {
1480
1577
  display: block;
1481
1578
  font-family: var(--p234-type-meta-family);