@plus234feed/ds 0.6.0 → 0.8.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 +90 -21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plus234feed/ds",
3
- "version": "0.6.0",
3
+ "version": "0.8.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",
@@ -280,6 +280,71 @@
280
280
  .p234-delta[data-direction="up"]::before { content: "\25B2 "; }
281
281
  .p234-delta[data-direction="down"]::before { content: "\25BC "; }
282
282
 
283
+ /* On a cost page a rise is the bad news.
284
+ *
285
+ * The default above is a market reading: up is green because a price you hold
286
+ * went up. On petrol, food, transport and the cost of a healthy diet the same
287
+ * arrow means a household pays more, so the two colours swap. The arrow still
288
+ * points the way the number moved; only good and bad change places.
289
+ *
290
+ * This existed as a helper in the application for a while, which meant the
291
+ * next cost page would have invented its own. */
292
+ .p234-delta--cost[data-direction="up"] { color: var(--p234-color-data-down); }
293
+ .p234-delta--cost[data-direction="down"] { color: var(--p234-color-data-up); }
294
+
295
+ /* --- tile row ----------------------------------------------------------
296
+ The grid a row of tiles sits in. Every page that showed figures was
297
+ writing this inline, with a different minimum each time, and the counts
298
+ that left one tile alone on a second row were found by eye afterwards.
299
+
300
+ A lone tile on its own row reads as a separate section rather than the
301
+ fourth of four, which is the same fault the footer had with seven link
302
+ groups in a six column grid.
303
+
304
+ `min(100%, ...)` is what keeps a single column on a phone: without it the
305
+ minimum wins and the row overflows the screen. */
306
+ .p234-tiles {
307
+ display: grid;
308
+ gap: var(--p234-space-6);
309
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
310
+ }
311
+
312
+ /* Quantity queries. At the page measure a 11rem minimum fits three across,
313
+ so four tiles break as three and one, and seven as three, three and one.
314
+ A wider minimum drops those to two and four across, which divide evenly.
315
+ On a wider container they still fit four, and four divides four. */
316
+ .p234-tiles:has(> :nth-child(4):last-child) {
317
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
318
+ }
319
+ .p234-tiles:has(> :nth-child(7):last-child) {
320
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
321
+ }
322
+
323
+ /* --- meter -------------------------------------------------------------
324
+ An inline bar for one value's share of a whole: a food group's share of a
325
+ daily diet, a party's share of a vote, a source's share of coverage.
326
+
327
+ Not to be confused with .p234-progress, which is the fixed reading bar
328
+ pinned to the top of the viewport. Using that one inline stacks every bar
329
+ on the page at the top of the screen, which is exactly what happened the
330
+ first time this was needed.
331
+
332
+ The share is carried by an aria-label on the element, because a bar on its
333
+ own is read out as nothing at all. */
334
+ .p234-meter {
335
+ display: block;
336
+ height: var(--p234-border-thick);
337
+ background: var(--p234-color-rule);
338
+ overflow: hidden;
339
+ }
340
+ .p234-meter__fill {
341
+ display: block;
342
+ height: 100%;
343
+ background: var(--p234-color-brand);
344
+ }
345
+ /* A second series in the same list, for a comparison bar under the first. */
346
+ .p234-meter__fill--alt { background: var(--p234-color-ink-subtle); }
347
+
283
348
  .p234-table {
284
349
  width: 100%;
285
350
  border-collapse: collapse;
@@ -315,17 +380,21 @@
315
380
  max-width: var(--p234-measure-text);
316
381
  }
317
382
  .p234-prose > * + * { margin-top: var(--p234-space-5); }
318
- /* Links in running text, but not links that are already a component.
383
+ /* Links in running text, meaning links with no styling of their own.
319
384
  *
320
385
  * `.p234-prose a` is a class and a type, which outranks the single class on
321
386
  * `.p234-btn`, so without this guard a button inside prose takes the link
322
387
  * colour: brand green text on a brand green fill, which renders as an empty
323
388
  * green rectangle. The same applied to a tag, a toggle and a directory row.
324
389
  *
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); }
390
+ * The guard excludes any link carrying a class, not only a p234- one, because
391
+ * the first version missed a link styled by the host application's own
392
+ * utilities and it went green on green too. The rule is now simply: an
393
+ * unstyled link gets prose styling, and a link with a class styles itself.
394
+ * `:not([class])` rather than `:where()` so it does not depend on whether
395
+ * this stylesheet is imported before or after the host's reset. */
396
+ .p234-prose a:not([class]) { color: var(--p234-color-link); text-underline-offset: 2px; }
397
+ .p234-prose a:not([class]):visited { color: var(--p234-color-link-visited); }
329
398
  .p234-prose blockquote {
330
399
  font-family: var(--p234-type-quote-family);
331
400
  font-size: var(--p234-type-quote-size);
@@ -473,7 +542,7 @@
473
542
  /* Same guard as prose: a link that is already a component keeps its own
474
543
  colour. Without it a button or tag dropped into this box would be styled
475
544
  as one of the box's own link rows. */
476
- .p234-nextstep a:not([class*="p234-"]) {
545
+ .p234-nextstep a:not([class]) {
477
546
  font-family: var(--p234-type-headline-xs-family);
478
547
  font-size: var(--p234-type-headline-xs-size);
479
548
  line-height: var(--p234-type-headline-xs-leading);
@@ -481,7 +550,7 @@
481
550
  color: var(--p234-color-ink);
482
551
  text-decoration: none;
483
552
  }
484
- .p234-nextstep a:not([class*="p234-"]):hover { text-decoration: underline; text-underline-offset: 2px; }
553
+ .p234-nextstep a:not([class]):hover { text-decoration: underline; text-underline-offset: 2px; }
485
554
 
486
555
  /* --- breadcrumb --------------------------------------------------------
487
556
  34 files hand-roll this today, each with its own separator and spacing. */
@@ -505,8 +574,8 @@
505
574
  content: "/";
506
575
  color: var(--p234-color-rule-strong);
507
576
  }
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; }
577
+ .p234-breadcrumb a:not([class]) { color: var(--p234-color-ink-muted); text-decoration: none; }
578
+ .p234-breadcrumb a:not([class]):hover { color: var(--p234-color-ink); text-decoration: underline; text-underline-offset: 2px; }
510
579
  .p234-breadcrumb [aria-current="page"] { color: var(--p234-color-ink); }
511
580
 
512
581
  /* --- figure ------------------------------------------------------------
@@ -723,7 +792,7 @@
723
792
  justify-content: center;
724
793
  gap: var(--p234-space-5);
725
794
  }
726
- .p234-masthead__editions a:not([class*="p234-"]) {
795
+ .p234-masthead__editions a:not([class]) {
727
796
  font-family: var(--p234-type-ui-sm-family);
728
797
  font-size: var(--p234-type-ui-sm-size);
729
798
  font-weight: 600;
@@ -734,7 +803,7 @@
734
803
  white-space: nowrap;
735
804
  }
736
805
  .p234-masthead__editions a:hover,
737
- .p234-masthead__editions a:not([class*="p234-"])[aria-current] { color: var(--p234-color-ink); }
806
+ .p234-masthead__editions a:not([class])[aria-current] { color: var(--p234-color-ink); }
738
807
 
739
808
  /* Row 2: the wordmark, centred. */
740
809
  .p234-masthead__bar {
@@ -852,13 +921,13 @@
852
921
  }
853
922
  .p234-megamenu ul { list-style: none; margin: 0; padding: 0; }
854
923
  .p234-megamenu li { margin-bottom: var(--p234-space-4); }
855
- .p234-megamenu a:not([class*="p234-"]) {
924
+ .p234-megamenu a:not([class]) {
856
925
  font-family: var(--p234-type-ui-family);
857
926
  font-size: var(--p234-type-ui-size);
858
927
  color: var(--p234-color-ink);
859
928
  text-decoration: none;
860
929
  }
861
- .p234-megamenu a:not([class*="p234-"]):hover { text-decoration: underline; text-underline-offset: 2px; }
930
+ .p234-megamenu a:not([class]):hover { text-decoration: underline; text-underline-offset: 2px; }
862
931
 
863
932
  /* The phone drawer: a full screen panel, search first, then the sections as
864
933
  accordions. <details> so it works with no JavaScript. */
@@ -892,7 +961,7 @@
892
961
  gap: var(--p234-space-4);
893
962
  padding-bottom: var(--p234-space-5);
894
963
  }
895
- .p234-drawer__links a:not([class*="p234-"]) {
964
+ .p234-drawer__links a:not([class]) {
896
965
  font-family: var(--p234-type-ui-family);
897
966
  font-size: var(--p234-type-ui-size);
898
967
  color: var(--p234-color-ink);
@@ -917,7 +986,7 @@
917
986
  max-width: var(--p234-layout-container);
918
987
  margin-inline: auto;
919
988
  }
920
- .p234-subnav a:not([class*="p234-"]) {
989
+ .p234-subnav a:not([class]) {
921
990
  display: block;
922
991
  font-family: var(--p234-type-ui-sm-family);
923
992
  font-size: var(--p234-type-ui-sm-size);
@@ -929,8 +998,8 @@
929
998
  border-bottom: var(--p234-border-thick) solid transparent;
930
999
  margin-bottom: -1px;
931
1000
  }
932
- .p234-subnav a:not([class*="p234-"]):hover { color: var(--p234-color-ink); }
933
- .p234-subnav a:not([class*="p234-"])[aria-current] {
1001
+ .p234-subnav a:not([class]):hover { color: var(--p234-color-ink); }
1002
+ .p234-subnav a:not([class])[aria-current] {
934
1003
  color: var(--p234-color-ink);
935
1004
  border-bottom-color: var(--p234-color-brand);
936
1005
  }
@@ -996,13 +1065,13 @@
996
1065
  }
997
1066
  .p234-footer ul { list-style: none; margin: 0; padding: 0; }
998
1067
  .p234-footer li { margin-bottom: var(--p234-space-3); }
999
- .p234-footer a:not([class*="p234-"]) {
1068
+ .p234-footer a:not([class]) {
1000
1069
  font-family: var(--p234-type-ui-sm-family);
1001
1070
  font-size: var(--p234-type-ui-sm-size);
1002
1071
  color: var(--p234-color-ink);
1003
1072
  text-decoration: none;
1004
1073
  }
1005
- .p234-footer a:not([class*="p234-"]):hover { text-decoration: underline; text-underline-offset: 2px; }
1074
+ .p234-footer a:not([class]):hover { text-decoration: underline; text-underline-offset: 2px; }
1006
1075
  .p234-footer__legal {
1007
1076
  border-top: var(--p234-border-hairline) solid var(--p234-color-rule);
1008
1077
  padding-top: var(--p234-space-5);
@@ -1562,7 +1631,7 @@ textarea.p234-field__control {
1562
1631
  margin: 0;
1563
1632
  padding: 0;
1564
1633
  }
1565
- .p234-linkgrid a:not([class*="p234-"]) {
1634
+ .p234-linkgrid a:not([class]) {
1566
1635
  display: block;
1567
1636
  border-top: var(--p234-border-thick) solid var(--p234-color-ink);
1568
1637
  padding-top: var(--p234-space-3);
@@ -1572,7 +1641,7 @@ textarea.p234-field__control {
1572
1641
  color: var(--p234-color-ink);
1573
1642
  text-decoration: none;
1574
1643
  }
1575
- .p234-linkgrid a:not([class*="p234-"]):hover { color: var(--p234-color-brand); }
1644
+ .p234-linkgrid a:not([class]):hover { color: var(--p234-color-brand); }
1576
1645
  .p234-linkgrid__count {
1577
1646
  display: block;
1578
1647
  font-family: var(--p234-type-meta-family);