diff --git a/web/scripts/plate.test.mjs b/web/scripts/plate.test.mjs index b9324f6..c5f3ced 100644 --- a/web/scripts/plate.test.mjs +++ b/web/scripts/plate.test.mjs @@ -33,6 +33,28 @@ test("a button is a plate unless it says otherwise", () => { assert.match(shape, /border-radius: 0/); }); +test("a plate's label is stencilled on", () => { + const shape = rule("button,\n.plate"); + assert.match(shape, /font-family: var\(--font-labels\)/); + assert.match(shape, /text-transform: uppercase/); + assert.match(shape, /letter-spacing:/); +}); + +test("a control that is words to read gives the stencil back", () => { + const reset = [ + ...css.matchAll(/(?:^|\n)((?:\.[\w-]+,\n)+\.[\w-]+)\s*{([^}]*)}/g), + ].find((m) => m[2].includes("text-transform: none")); + assert.ok(reset, "nothing drops the stencilled label any more"); + assert.match(reset[2], /font-family: inherit/); + assert.match(reset[2], /letter-spacing: normal/); + // The bar's own buttons set these capitals for themselves, so a reset on + // them would put the chrome back into sentence case. + assert.ok( + !/\.(account|theme)-button/.test(reset[1]), + "a chrome label is in the reset list", + ); +}); + test("a plate's focus ring is inset", () => { const ring = rule("button:focus-visible,\n.plate:focus-visible"); assert.ok(ring, "no shared focus-visible rule for plates"); diff --git a/web/src/styles.css b/web/src/styles.css index 6efe39e..857f637 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -1819,14 +1819,9 @@ body:has(.hero) { align-items: center; padding: 0.4rem 0.8rem; text-decoration: none; - /* Small tracked capitals in the display face: the same treatment the site's - chrome labels get, so the secondary half is quiet without being a - different kind of thing from the half beside it. */ - font-family: var(--font-labels); - text-transform: uppercase; + /* A step smaller than a plate's default label: this half is quiet, and it + carries a file name rather than an order. */ font-size: 0.75rem; - font-weight: 600; - letter-spacing: 0.1em; /* Tracked capitals are wide, and this half is a file name: broken over two lines it stops reading as a label on a plate. */ white-space: nowrap; @@ -2229,7 +2224,13 @@ button[disabled] { --notch is a property rather than a constant: a full-page button and a 0.7rem chip want the same shape at different sizes. --plate-ring is the colour of the inset ring, and a control that sets its own background sets - this with it. */ + this with it. + + The label is stencilled on: small tracked capitals in the label face, which + is what the bar's links, the daily card's two halves and the waiting + screen's way out already wore. The extra right padding pays back the + letter-spacing added after the last letter, which is otherwise trapped + inside the plate and pushes a centred label left of centre. */ button, .plate { --notch: 0.5rem; @@ -2243,6 +2244,10 @@ button, 0 100%, 0 var(--notch) ); + font-family: var(--font-labels); + font-weight: 600; + letter-spacing: 0.1em; + text-transform: uppercase; } /* A filled plate is accent on accent, and the only ring that shows against @@ -2257,7 +2262,8 @@ button:not(.secondary) { control does, any more than cutting one off a card would - and a Mode that is not built yet is a
beside one that is, so a shape only the button could wear would split the row in two. Each of these already sets its own - radius further down this file, so dropping the clip is the whole of it. */ + radius further down this file, so the clip and the stencilled label are the + whole of it. */ .camo-die, .camo-cat, .camo-pattern, @@ -2275,6 +2281,26 @@ button:not(.secondary) { clip-path: none; } +/* Most of them drop the stencilled label with the shape: a palette's name, a + Mode's heading and a row in a menu are words to read, not a part number. + The bar's own buttons are not in this list - they are chrome labels already, + and set the same capitals a plate does for themselves. */ +.camo-die, +.camo-cat, +.camo-pattern, +.camo-preset, +.camo-choice, +.camo-unit-btn, +.camo-bg-btn, +.camo-mm-tile, +.account-item, +.theme-choice, +.mode-card { + font-family: inherit; + letter-spacing: normal; + text-transform: none; +} + /* The way out for anything else: it gives back the site's radius as well, because a control that never had a shape of its own would otherwise be left with the square corners the plate rule sets. */ @@ -3756,11 +3782,8 @@ footer .debug { .waiting-cancel { --notch: 0.55rem; padding: 0.5rem 1.2rem 0.5rem 1.45rem; - font-family: var(--font-labels); font-size: 0.75rem; - font-weight: 600; letter-spacing: 0.12em; - text-transform: uppercase; white-space: nowrap; color: color-mix(in srgb, var(--ink) 80%, var(--panel)); background: color-mix(in srgb, var(--ink) 22%, var(--panel)); @@ -4749,9 +4772,11 @@ footer .debug { } /* Import, Download and Save share the swatch's width, so they are sized to sit - on one line rather than wrapping into an uneven stack. */ + on one line rather than wrapping into an uneven stack. They wrap rather than + run off the column when there is no room for the line: tracked capitals are + wide, and a button cannot shrink below its own label. */ .camo-aside .camo-actions { - flex-wrap: nowrap; + flex-wrap: wrap; } .camo-aside .camo-actions button { @@ -4771,8 +4796,12 @@ footer .debug { align-self: stretch; width: 100%; padding: 0.7rem 1rem; + /* The display face at the size the daily card's Play half uses: this is the + other control on the site that is an order rather than a link. */ + font-family: var(--font-display); font-size: 1rem; font-weight: 700; + letter-spacing: 0.12em; } .camo-randomize:hover { @@ -5481,7 +5510,6 @@ footer .debug { corner, so the word still sits centred inside the shape. */ padding: 0.5rem 1.15rem 0.5rem 1.35rem; font-family: var(--font-display); - text-transform: uppercase; font-size: 1rem; font-weight: 700; letter-spacing: 0.12em;