[object Object]

← back to Wallco Ai

tokens: --eyebrow type token + .eyebrow utility class (4H Paper)

101b1fd7a6e2247ccd320c8771300203185ffd44 · 2026-05-12 16:15:52 -0700 · SteveStudio2

Four-horsemen Paper-horseman v1 review flagged ~15 ad-hoc copies of
the eyebrow pattern across the codebase (font:10-11px var(--sans);
text-transform:uppercase; letter-spacing:.06-.08em; color:#666-#999).
Standardized:

  --eyebrow-size:   11px
  --eyebrow-track:  0.08em
  --eyebrow-weight: 500
  --eyebrow-color:  var(--ink-faint)

  .eyebrow { /* composed from the vars */ }

Wired into /studio in the 4 highest-visibility spots:
  • Elements category labels (ANIMALS / ATMOSPHERE / BOTANICALS / …)
  • Payoff frame "Prompt" sidebar header
  • "Live tile preview · 10 ft wide wall"
  • "See it in a room · 3 categories"

The other ~11 ad-hoc copies are scattered across admin, hero, iso-modal,
and pair-card surfaces — left alone for a future global sweep so this
commit stays minimal/risk-bounded. Future eyebrows in new code should
use class="eyebrow" instead of inline styles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 101b1fd7a6e2247ccd320c8771300203185ffd44
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Tue May 12 16:15:52 2026 -0700

    tokens: --eyebrow type token + .eyebrow utility class (4H Paper)
    
    Four-horsemen Paper-horseman v1 review flagged ~15 ad-hoc copies of
    the eyebrow pattern across the codebase (font:10-11px var(--sans);
    text-transform:uppercase; letter-spacing:.06-.08em; color:#666-#999).
    Standardized:
    
      --eyebrow-size:   11px
      --eyebrow-track:  0.08em
      --eyebrow-weight: 500
      --eyebrow-color:  var(--ink-faint)
    
      .eyebrow { /* composed from the vars */ }
    
    Wired into /studio in the 4 highest-visibility spots:
      • Elements category labels (ANIMALS / ATMOSPHERE / BOTANICALS / …)
      • Payoff frame "Prompt" sidebar header
      • "Live tile preview · 10 ft wide wall"
      • "See it in a room · 3 categories"
    
    The other ~11 ad-hoc copies are scattered across admin, hero, iso-modal,
    and pair-card surfaces — left alone for a future global sweep so this
    commit stays minimal/risk-bounded. Future eyebrows in new code should
    use class="eyebrow" instead of inline styles.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 public/css/site.css | 17 +++++++++++++++++
 server.js           |  8 ++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/public/css/site.css b/public/css/site.css
index 2b4168f..d861265 100644
--- a/public/css/site.css
+++ b/public/css/site.css
@@ -24,10 +24,27 @@
   --serif: 'Cormorant Garamond', 'Playfair Display', Georgia, serif;
   --sans:  'Inter', -apple-system, system-ui, sans-serif;
 
+  /* ── Eyebrow type token — small tracked uppercase label.
+   *    Per four-horsemen Paper-horseman v1 review: studio was using
+   *    ad-hoc 11px/.06em/.08em variants in 15+ places. This is the
+   *    canonical version. Use class="eyebrow" or var(--eyebrow-*).
+   */
+  --eyebrow-size:   11px;
+  --eyebrow-track:  0.08em;
+  --eyebrow-weight: 500;
+  --eyebrow-color:  var(--ink-faint);
+
   --hero-h: clamp(560px, 72vh, 900px);
   --cols: 4;
 }
 
+.eyebrow {
+  font: var(--eyebrow-weight) var(--eyebrow-size) var(--sans);
+  letter-spacing: var(--eyebrow-track);
+  text-transform: uppercase;
+  color: var(--eyebrow-color);
+}
+
 /* ── DARK MODE */
 [data-theme="dark"] {
   --bg:         #0d0c0a;
diff --git a/server.js b/server.js
index 102aa0f..dee0180 100644
--- a/server.js
+++ b/server.js
@@ -8718,7 +8718,7 @@ async function loadRefs(){
 function renderElementsList() {
   var byCat = window._ELEMENTS_BY_CAT || {};
   document.getElementById('elements-list').innerHTML = Object.keys(byCat).sort().map(function(c){
-    return '<div style="margin-bottom:6px"><div style="font-weight:600;font-size:11px;color:#666;text-transform:uppercase;letter-spacing:.06em;margin-bottom:3px">'+c+'</div><div style="display:flex;flex-wrap:wrap">'+byCat[c].map(function(e){
+    return '<div style="margin-bottom:6px"><div class="eyebrow" style="margin-bottom:3px">'+c+'</div><div style="display:flex;flex-wrap:wrap">'+byCat[c].map(function(e){
       var on = EXTRA.has(e.name);
       var bg = on ? '#1a1a1a' : '#fff';
       var fg = on ? '#fff' : '#333';
@@ -8870,7 +8870,7 @@ document.getElementById('btn-compose').addEventListener('click', async function(
           // Sidebar (right) — prompt + actions
           '<div style="padding:18px;background:#fafafa;border-left:1px solid #eee;display:flex;flex-direction:column;gap:12px">'+
             '<div>'+
-              '<div style="font-size:10px;color:#999;letter-spacing:.06em;text-transform:uppercase;margin-bottom:4px">Prompt</div>'+
+              '<div class="eyebrow" style="margin-bottom:4px">Prompt</div>'+
               '<div style="font-size:11px;font-family:ui-monospace,Menlo,monospace;color:#333;line-height:1.45;max-height:140px;overflow-y:auto">'+safePrompt+'</div>'+
             '</div>'+
             '<div style="display:flex;flex-direction:column;gap:8px;margin-top:auto">'+
@@ -8897,13 +8897,13 @@ document.getElementById('btn-compose').addEventListener('click', async function(
         // proportional. Background-size in % maps slider inches → strip width:
         //   tile_pct = (slider_inches / 120) * 100  →  e.g. 72" → 60% wide tile.
         '<div style="padding:0 14px 12px;background:#fff;border-bottom:1px solid #eee">'+
-          '<div style="font-size:10px;color:#999;letter-spacing:.08em;text-transform:uppercase;margin:8px 0 6px">Live tile preview · 10 ft wide wall</div>'+
+          '<div class="eyebrow" style="margin:8px 0 6px">Live tile preview · 10 ft wide wall</div>'+
           '<div id="studio-tile-preview" data-pattern-url="'+imgUrl+'" '+
                'style="height:140px;border:1px solid #eee;border-radius:4px;background-image:url(\\''+imgUrl+'\\');background-repeat:repeat;background-position:center;background-size:60% auto"></div>'+
         '</div>'+
         // 3 room settings row — one per category, in parallel.
         '<div style="padding:14px 14px 12px;background:#fafafa">'+
-          '<div style="font-size:10px;color:#999;letter-spacing:.08em;text-transform:uppercase;margin-bottom:8px">See it in a room · 3 categories</div>'+
+          '<div class="eyebrow" style="margin-bottom:8px">See it in a room · 3 categories</div>'+
           '<div id="studio-rooms-grid" style="display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px">'+
             '<div class="studio-room-cell" data-room="bedroom"     data-label="Bedroom"      style="position:relative;border:1px solid #eee;border-radius:6px;aspect-ratio:4/3;background:#fafafa center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:#999;font-size:11px;overflow:hidden">Bedroom · loading…</div>'+
             '<div class="studio-room-cell" data-room="living_room" data-label="Living Room"  style="position:relative;border:1px solid #eee;border-radius:6px;aspect-ratio:4/3;background:#fafafa center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:#999;font-size:11px;overflow:hidden">Living Room · loading…</div>'+

← c68a4c1 studio: hard single-column mobile stack + trade-nav clip fix  ·  back to Wallco Ai  ·  wall-calc: surface pinned W×H chip in summary so collapsed P 47eb2ff →