@bongos/core 1.19.89 → 1.19.91

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.
@@ -0,0 +1,103 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Palette + hero options — cloudbongos.com/ (task 1002747)</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700&family=Quicksand:wght@400;500;600;700&family=Fira+Code:wght@400;500&display=swap">
10
+ <style>
11
+ :root{--ink:#12131c;--soft:#5d6070;--faint:#8b8fa3;--line:#dcdfe8;--bg:#f4f5f9;--card:#fff;}
12
+ @media(prefers-color-scheme:dark){:root{--ink:#f2f3f8;--soft:#a8adc0;--faint:#767b90;--line:#2b2f3d;--bg:#0d0f16;--card:#161a24;}}
13
+ *{box-sizing:border-box;margin:0;padding:0;}
14
+ body{background:var(--bg);color:var(--ink);font-family:"Quicksand",system-ui,sans-serif;
15
+ padding:clamp(20px,4vw,46px);-webkit-font-smoothing:antialiased;}
16
+ h1{font-family:"Baloo 2",sans-serif;font-weight:700;font-size:clamp(24px,3.4vw,34px);letter-spacing:-.7px;margin-bottom:8px;}
17
+ .sub{font-size:15px;font-weight:500;color:var(--soft);max-width:74ch;line-height:1.6;margin-bottom:10px;}
18
+ .sub b{color:var(--ink);}
19
+ .warn{border-left:3px solid #dc2626;background:color-mix(in srgb,#dc2626 8%,transparent);
20
+ border-radius:0 10px 10px 0;padding:12px 16px;font-size:14px;font-weight:600;line-height:1.6;
21
+ color:var(--ink);max-width:82ch;margin:16px 0 26px;}
22
+ .warn code{font-family:"Fira Code",monospace;font-size:12.5px;}
23
+ .bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:24px;}
24
+ .bar button{cursor:pointer;font-family:"Quicksand",sans-serif;font-weight:700;font-size:13.5px;
25
+ padding:8px 16px;border-radius:999px;border:2px solid var(--line);background:var(--card);color:var(--ink);}
26
+ .bar button[aria-pressed="true"]{border-color:var(--ink);background:var(--ink);color:var(--card);}
27
+ .bar span{font-family:"Fira Code",monospace;font-size:11px;color:var(--faint);letter-spacing:.5px;text-transform:uppercase;}
28
+ .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(430px,1fr));gap:clamp(16px,2.4vw,26px);}
29
+ .cell{background:var(--card);border:1.5px solid var(--line);border-radius:18px;overflow:hidden;}
30
+ .cellHead{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1.5px solid var(--line);}
31
+ .dot{width:16px;height:16px;border-radius:50%;flex:0 0 auto;box-shadow:0 0 0 1.5px rgba(128,128,128,.28) inset;}
32
+ .nm{font-family:"Baloo 2",sans-serif;font-weight:700;font-size:16px;letter-spacing:-.2px;}
33
+ .tag{font-size:12px;font-weight:600;color:var(--faint);margin-left:auto;font-family:"Fira Code",monospace;}
34
+ .frame{position:relative;width:100%;aspect-ratio:16/10;overflow:hidden;background:var(--bg);}
35
+ .frame iframe{position:absolute;top:0;left:0;width:1280px;height:800px;border:0;
36
+ transform:scale(.336);transform-origin:top left;}
37
+ .note{padding:11px 16px;font-size:13px;font-weight:500;color:var(--soft);line-height:1.55;border-top:1.5px solid var(--line);}
38
+ .note b{color:var(--ink);font-weight:700;}
39
+ a.open{display:inline-block;margin-top:6px;font-size:12.5px;font-weight:700;color:inherit;}
40
+ </style>
41
+ </head>
42
+ <body>
43
+
44
+ <h1>Seven palettes, two heroes</h1>
45
+ <p class="sub">The same landing page, re-themed. Each palette is exactly what a branding pack does — it
46
+ overrides the <b>cosmos.css</b> contract tier. On a real instance only one exists, injected by
47
+ <b>themeMarkup()</b>. Click any tile's <b>open full</b> to walk it at full size with the switcher.</p>
48
+
49
+ <div class="warn">
50
+ <b>Found while checking these:</b> the palette shipping <b>today</b> fails WCAG AA. White on
51
+ <code>--accent #f97316</code> is <b>2.80:1</b> where 4.5 is required, and <code>--accent-deep #ea580c</code>
52
+ as link text on a card is <b>3.56:1</b>. That affects every primary button and link on <code>/create</code>
53
+ and <code>/projects</code> right now — not just this page. All six candidates below were checked with a
54
+ contrast calculator across twelve pairs each and pass cleanly in both modes.
55
+ </div>
56
+
57
+ <div class="bar">
58
+ <span>hero</span>
59
+ <button data-m="bongos" aria-pressed="true">bongos</button>
60
+ <button data-m="buddha" aria-pressed="false">buddha</button>
61
+ <span style="margin-left:14px">mode</span>
62
+ <button data-md="light" aria-pressed="true">light</button>
63
+ <button data-md="dark" aria-pressed="false">dark</button>
64
+ </div>
65
+
66
+ <div class="grid" id="grid"></div>
67
+
68
+ <script>
69
+ var SCHEMES=[
70
+ {k:'', n:'shipped today', d:'#f97316', note:'The current tokens. <b>Fails contrast</b> on buttons and links — see above.'},
71
+ {k:'adobe-clay', n:'adobe clay', d:'#b8492c', note:'Fired terracotta, sand, a whisper of sage. The only warm option with a real <b>second hue</b>, so the dark band has somewhere to go. <b>Risk:</b> too much beige reads as tired.'},
72
+ {k:'ember-marigold', n:'ember marigold',d:'#ce4806', note:'Today’s sunrise with the milk taken out — a genuinely pigmented backdrop so cards lift off it. <b>Risk:</b> one hue plays every part.'},
73
+ {k:'letterpress', n:'letterpress', d:'#C22A12', note:'Warm paper, near-black type, one vermilion struck on the downbeat. Most trustworthy. <b>Risk:</b> austerity fights the rounded type.'},
74
+ {k:'deep-water', n:'deep water', d:'#0d7f97', note:'Promotes the unused <code>--sea</code> token to the lead. Calm and coherent. <b>Risk:</b> reads as generic cloud-vendor SaaS.'},
75
+ {k:'sapwood', n:'sapwood', d:'#3d7a33', note:'Oat paper and pigment greens, dodging both eco-brand and terminal-green. <b>Risk:</b> green says gardening, not build platform.'},
76
+ {k:'plumfield', n:'plumfield', d:'#932bcf', note:'Leans hardest into the space metaphor; best dark mode of the set. <b>Risk:</b> violet+magenta is the uniform of crypto — bad for a capture-resistance pitch.'}
77
+ ];
78
+ var mascot='bongos', mode='light';
79
+ function render(){
80
+ document.getElementById('grid').innerHTML = SCHEMES.map(function(s){
81
+ var src='landing-page-mock.html?rail=0&mascot='+mascot+'&mode='+mode+'&scheme='+encodeURIComponent(s.k);
82
+ return '<div class="cell">'+
83
+ '<div class="cellHead"><span class="dot" style="background:'+s.d+'"></span>'+
84
+ '<span class="nm">'+s.n+'</span><span class="tag">'+(s.k||'current')+'</span></div>'+
85
+ '<div class="frame"><iframe loading="lazy" src="'+src+'" title="'+s.n+'"></iframe></div>'+
86
+ '<div class="note">'+s.note+'<br><a class="open" href="'+src.replace('rail=0','rail=1')+'" target="_blank">open full →</a></div>'+
87
+ '</div>';
88
+ }).join('');
89
+ }
90
+ document.querySelectorAll('[data-m]').forEach(function(b){
91
+ b.onclick=function(){ mascot=b.dataset.m;
92
+ document.querySelectorAll('[data-m]').forEach(function(x){x.setAttribute('aria-pressed',String(x===b));});
93
+ render(); };
94
+ });
95
+ document.querySelectorAll('[data-md]').forEach(function(b){
96
+ b.onclick=function(){ mode=b.dataset.md;
97
+ document.querySelectorAll('[data-md]').forEach(function(x){x.setAttribute('aria-pressed',String(x===b));});
98
+ render(); };
99
+ });
100
+ render();
101
+ </script>
102
+ </body>
103
+ </html>
@@ -1,16 +1,16 @@
1
1
  /* GENERATED by scripts/gen-brand.js from config/branding.json — do not edit by hand. */
2
2
  :root {
3
- --bg: #fff7ed;
4
- --bg-card: #ffffff;
5
- --bg-deep: #ffedd5;
6
- --ink: #2a1f17;
7
- --ink-soft: #6b5d52;
8
- --ink-faint: #857567;
9
- --rule: #fdba74;
10
- --rule-soft: #fed7aa;
11
- --accent: #f97316;
12
- --accent-deep: #ea580c;
13
- --terracotta: #fb7185;
3
+ --bg: #f9d9a8;
4
+ --bg-card: #fffaf2;
5
+ --bg-deep: #f6d8ae;
6
+ --ink: #2b170e;
7
+ --ink-soft: #6d4a33;
8
+ --ink-faint: #785a41;
9
+ --rule: #e8a463;
10
+ --rule-soft: #f6d8ae;
11
+ --accent: #ce4806;
12
+ --accent-deep: #9e3406;
13
+ --terracotta: #855b3d;
14
14
  --font-display: "Baloo 2", "Quicksand", system-ui, sans-serif;
15
15
  --font-body: "Quicksand", system-ui, -apple-system, "Segoe UI", sans-serif;
16
16
  }
@@ -73,7 +73,7 @@ function buildBrand(branding) {
73
73
  // Panel header epigraph (branding copy.tagline).
74
74
  TAGLINE: (branding.copy && branding.copy.tagline) || '',
75
75
  // Pre-CSS window background (main.js) — the theme bg so first paint is on-brand.
76
- BG_COLOR: colors.bg || '#ffffff',
76
+ BG_COLOR: colors.bg || '#fffaf2',
77
77
  };
78
78
  }
79
79
 
@@ -85,17 +85,17 @@ function buildThemeCss(branding) {
85
85
  const v = (x, fb) => x || fb;
86
86
  return `/* GENERATED by scripts/gen-brand.js from config/branding.json — do not edit by hand. */
87
87
  :root {
88
- --bg: ${v(c.bg, '#fff7ed')};
89
- --bg-card: ${v(c.bgCard, '#ffffff')};
90
- --bg-deep: ${v(c.bgDeep, '#ffedd5')};
91
- --ink: ${v(c.ink, '#2a1f17')};
92
- --ink-soft: ${v(c.inkSoft, '#6b5d52')};
93
- --ink-faint: ${v(c.inkFaint, '#857567')};
94
- --rule: ${v(c.rule, '#fdba74')};
95
- --rule-soft: ${v(c.ruleSoft, '#fed7aa')};
96
- --accent: ${v(c.accent, '#f97316')};
97
- --accent-deep: ${v(c.accentDeep, '#ea580c')};
98
- --terracotta: ${v(c.terracotta, '#fb7185')};
88
+ --bg: ${v(c.bg, '#f9d9a8')};
89
+ --bg-card: ${v(c.bgCard, '#fffaf2')};
90
+ --bg-deep: ${v(c.bgDeep, '#f6d8ae')};
91
+ --ink: ${v(c.ink, '#2b170e')};
92
+ --ink-soft: ${v(c.inkSoft, '#6d4a33')};
93
+ --ink-faint: ${v(c.inkFaint, '#785a41')};
94
+ --rule: ${v(c.rule, '#e8a463')};
95
+ --rule-soft: ${v(c.ruleSoft, '#f6d8ae')};
96
+ --accent: ${v(c.accent, '#ce4806')};
97
+ --accent-deep: ${v(c.accentDeep, '#9e3406')};
98
+ --terracotta: ${v(c.terracotta, '#855b3d')};
99
99
  --font-display: ${v(fonts.display, '"Baloo 2", "Quicksand", system-ui, sans-serif')};
100
100
  --font-body: ${v(fonts.body, '"Quicksand", system-ui, -apple-system, "Segoe UI", sans-serif')};
101
101
  }
@@ -68,9 +68,9 @@ ICON = 100 # dmg.iconSize
68
68
  # it, so its "fallback" would paint a Cloud Bongos colour into a fully-specified
69
69
  # host build. That is exactly what `sea` did to the Applications-well rim.
70
70
  COLOR_ROLES = {
71
- "bg": "#fff7ed", "bgDeep": "#ffedd5", "bgCard": "#ffffff",
72
- "ink": "#2a1f17", "inkSoft": "#6b5d52", "ruleSoft": "#fed7aa",
73
- "accent": "#f97316", "accentDeep": "#ea580c", "terracotta": "#fb7185",
71
+ "bg": "#f9d9a8", "bgDeep": "#f6d8ae", "bgCard": "#fffaf2",
72
+ "ink": "#2b170e", "inkSoft": "#6d4a33", "ruleSoft": "#f6d8ae",
73
+ "accent": "#ce4806", "accentDeep": "#9e3406", "terracotta": "#855b3d",
74
74
  }
75
75
 
76
76
  FONT_DIRS = (
@@ -62,9 +62,9 @@ const OUT_BUILD = path.join(APP_DIR, 'build-resources');
62
62
  // it has nothing prompting a host to define it, so its "fallback" would paint a
63
63
  // Cloud Bongos colour into a fully-specified host build.
64
64
  const COLOR_ROLES = {
65
- bgCard: '#ffffff', bgDeep: '#ffedd5', ink: '#2a1f17',
66
- rule: '#fdba74', ruleSoft: '#fed7aa',
67
- accent: '#f97316', accentDeep: '#ea580c', terracotta: '#fb7185',
65
+ bgCard: '#fffaf2', bgDeep: '#f6d8ae', ink: '#2b170e',
66
+ rule: '#e8a463', ruleSoft: '#f6d8ae',
67
+ accent: '#ce4806', accentDeep: '#9e3406', terracotta: '#855b3d',
68
68
  };
69
69
 
70
70
  // The pack, resolved exactly as gen-brand.js resolves it (env → instance → neutral).
@@ -9,5 +9,5 @@
9
9
  "COPYRIGHT": "© Cloud Bongos",
10
10
  "CONFIG_DIR": "cloudbongos",
11
11
  "TAGLINE": "Building software is laying down a beat.",
12
- "BG_COLOR": "#fff7ed"
12
+ "BG_COLOR": "#f9d9a8"
13
13
  }
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.89",
3
+ "version": "1.19.91",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.89",
9
+ "version": "1.19.91",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.89",
3
+ "version": "1.19.91",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -3,12 +3,15 @@
3
3
  The shared token + component layer for the owner-facing project surfaces
4
4
  (/create, /projects).
5
5
 
6
- THE LOOK (owner decisions 2026-08-12, Loop 2): a LIGHT/DARK mode flips
7
- the WHOLE WORLD, not just the cards:
6
+ THE LOOK — ember marigold (owner, 2026-08-13; task 1002748, and before it
7
+ the 2026-08-12 Loop 2 decisions). A LIGHT/DARK mode flips the WHOLE WORLD,
8
+ not just the cards, and BOTH grounds are warm — dark is not an inversion:
8
9
 
9
- · light mode — the sunrise white/orange page: dawn sky, cream cards
10
- · dark mode — the gate's deep space (public-landing/gate/space.css):
11
- night sky, stars, deep-navy cards, warm-white ink
10
+ · light mode — pigmented marigold air, ivory cards, an ember accent fired
11
+ down from SaaS-bright into something with heat behind it
12
+ · dark mode — a warm umber night: deep-brown cards, cream ink, and the
13
+ accent pair flipping direction so the link tone goes BRIGHTER, which is
14
+ how warm schemes actually behave on a dark ground
12
15
 
13
16
  Mode resolution: prefers-color-scheme by default; an explicit choice
14
17
  sets data-mode="light|dark" on <html> (persisted by the page script).
@@ -25,11 +28,18 @@
25
28
  ═══════════════════════════════════════════════════════════════════════ */
26
29
 
27
30
  :root{
28
- /* contract tier (light mode) */
29
- --bg:#fff7ed; --bg-card:#ffffff; --bg-deep:#ffedd5;
30
- --ink:#2a1f17; --ink-soft:#6b5d52; --ink-faint:#9c8d80;
31
- --rule:#fdba74; --rule-soft:#fed7aa;
32
- --accent:#f97316; --accent-deep:#ea580c; --sea:#38bdf8; --terracotta:#fb7185;
31
+ /* contract tier (light mode) — ember marigold (task 1002748, direction §3):
32
+ the same sunrise with the milk taken out. The page stays PIGMENTED all the
33
+ way to the footer and the cards are the only near-white surfaces, so every
34
+ panel lifts; before this, page/sky/card sat within a few points of white and
35
+ the whole surface read as fog with no figure/ground at all.
36
+ KEEP IN LOCKSTEP with config/branding.neutral.json theme.ui.colors —
37
+ tests/cosmos_token_contrast.mjs fails on any drift, because the pack is what
38
+ actually paints (its :root is spliced AFTER this file). */
39
+ --bg:#f9d9a8; --bg-card:#fffaf2; --bg-deep:#f6d8ae;
40
+ --ink:#2b170e; --ink-soft:#6d4a33; --ink-faint:#785a41;
41
+ --rule:#e8a463; --rule-soft:#f6d8ae;
42
+ --accent:#ce4806; --accent-deep:#9e3406; --sea:#0f7a96; --terracotta:#855b3d;
33
43
  --font-display:"Baloo 2","Quicksand",system-ui,"Arial Rounded MT Bold",sans-serif;
34
44
  --font-body:"Quicksand",system-ui,-apple-system,"Segoe UI",sans-serif;
35
45
  --font-mono:"Fira Code",ui-monospace,SFMono-Regular,Menlo,monospace;
@@ -38,80 +48,94 @@
38
48
  --space-deep:#05060f; --space-mid:#0a0c20; --space-high:#0d0f28; --nebula:#2b2456;
39
49
  --sun-lit:#fb923c; --gold:#ffd98a; --gold-soft:#f6c976;
40
50
 
41
- /* semantic state tier */
42
- --ok:#16a34a; --warn:#d97706; --err:#dc2626;
51
+ /* semantic state tier — each is painted as 12px/700 chip TEXT on its own
52
+ -soft tint, so each must clear 4.5:1 against that tint AND the plain card. */
53
+ --ok:#0e6b31; --warn:#8b4d03; --err:#bb1f1f;
43
54
 
44
55
  /* chrome tier — the WHOLE WORLD flips with the mode (owner, 2026-08-12,
45
56
  Loop 2: light = the sunrise white/orange page, dark = the gate's space).
46
57
  Light values here; the dark blocks below swap all of them. */
47
- --page-bg:#fff7ed;
48
- --sky-bg:linear-gradient(180deg,#e9f5fd 0%,#fde8c8 34%,#fff4e6 62%,#fffdfa 100%);
58
+ --page-bg:#f9d9a8;
59
+ /* flat, not a gradient to white: the golden ground IS the marigold decision.
60
+ A gradient that faded out at the footer would reintroduce the fog. */
61
+ --sky-bg:#f9d9a8;
49
62
  --star-display:none;
50
- --chrome-ink:#2a1f17;
51
- --chrome-ink-dim:#6b5d52;
52
- --chrome-accent:#f97316;
63
+ --chrome-ink:#2b170e;
64
+ --chrome-ink-dim:#6d4a33;
65
+ --chrome-accent:var(--accent-deep);
53
66
  --chrome-glow:none;
54
- --glass-ink:#6b5d52;
55
- --glass-bg:rgba(255,255,255,0.65);
56
- --glass-border:rgba(249,115,22,0.4);
57
- --ava-shadow:0 2px 8px rgba(42,31,23,0.12);
58
- --hero-lede:#6b5d52;
59
- --hero-b:#ea580c;
60
- --foot-ink:#9c8d80;
61
- --foot-code:#ea580c;
67
+ --glass-ink:#6d4a33;
68
+ --glass-bg:rgba(255,255,255,0.62);
69
+ --glass-border:color-mix(in srgb, var(--accent) 42%, transparent);
70
+ --ava-shadow:0 2px 8px rgba(0,0,0,0.14);
71
+ --hero-lede:#6d4a33;
72
+ --hero-b:var(--accent-deep);
73
+ --foot-ink:var(--ink-faint);
74
+ --foot-code:var(--accent-deep);
62
75
  color-scheme:light;
63
76
  }
64
- /* dark tier — space sky + dark cards. Two hooks so an explicit choice beats
65
- the OS preference. */
77
+ /* dark tier — ember marigold's night: a WARM umber world, not an inversion of
78
+ the light one and no longer the gate's blue-violet space (task 1002748,
79
+ direction §3). Two hooks so an explicit choice beats the OS preference; keep
80
+ the two blocks in lockstep (tests/cosmos_token_contrast.mjs).
81
+
82
+ A declaration here is PERMANENT for every instance: these selectors are (0,2,0)
83
+ and the branding pack injects a plain :root at (0,1,0), so it can never override
84
+ them. --accent, --sea and --terracotta are therefore deliberately absent — that
85
+ omission is the only reason a re-themed instance's accent reaches dark mode at all.
86
+ --accent-deep is the exception: it is text, and a hex tuned to 4.5:1 on a near-white
87
+ card cannot also clear it on a #2c1710 one. It is DERIVED from --accent (a different
88
+ property, so no cycle) and so still follows the pack. Every chrome token that wants
89
+ the warm highlight takes var(--accent-deep) for the same reason: marigold's own
90
+ #ffab63 is what that derivation yields, so writing the literal would have frozen
91
+ one pack's colour into every instance's dark mode. */
66
92
  :root[data-mode="dark"]{
67
- --bg:#0d0f28; --bg-card:#12142e; --bg-deep:#1d2046;
68
- --ink:#f4eee7; --ink-soft:#c9bfb2; --ink-faint:#93897d;
69
- --rule:#5a4a7a; --rule-soft:#3a3560;
93
+ --bg:#150c06; --bg-card:#2c1710; --bg-deep:#3f2317;
94
+ --ink:#fdeedd; --ink-soft:#dcb693; --ink-faint:#b89272;
95
+ --rule:#5e3521; --rule-soft:#3f2317;
96
+ --accent-deep:color-mix(in srgb, var(--accent) 45%, #ffffff);
70
97
  --ok:#4ade80; --warn:#fbbf24; --err:#f87171;
71
- --page-bg:#05060f;
72
- --sky-bg:radial-gradient(120% 85% at 50% -12%, #2b2456 0%, rgba(43,36,86,0) 55%),
73
- radial-gradient(70% 55% at 82% 112%, rgba(56,120,200,.16), transparent 62%),
74
- radial-gradient(58% 48% at 12% 6%, rgba(120,70,160,.14), transparent 60%),
75
- linear-gradient(180deg, #05060f 0%, #0a0c20 48%, #0d0f28 100%);
98
+ --page-bg:#150c06;
99
+ --sky-bg:#150c06;
76
100
  --star-display:block;
77
- --chrome-ink:#ffffff;
78
- --chrome-ink-dim:rgba(255,255,255,0.85);
79
- --chrome-accent:#fb923c;
80
- --chrome-glow:0 2px 12px rgba(20,12,30,.7);
81
- --glass-ink:#ffd98a;
82
- --glass-bg:rgba(255,255,255,0.06);
83
- --glass-border:rgba(255,217,138,0.45);
84
- --ava-shadow:0 0 14px rgba(251,146,60,.45);
85
- --hero-lede:rgba(255,255,255,0.82);
86
- --hero-b:#ffd98a;
87
- --foot-ink:rgba(255,255,255,0.55);
88
- --foot-code:#ffd98a;
101
+ --chrome-ink:#fdeedd;
102
+ --chrome-ink-dim:#dcb693;
103
+ --chrome-accent:var(--accent-deep);
104
+ --chrome-glow:0 2px 12px rgba(0,0,0,.65);
105
+ --glass-ink:var(--accent-deep);
106
+ --glass-bg:rgba(255,255,255,0.07);
107
+ --glass-border:color-mix(in srgb, var(--accent) 42%, transparent);
108
+ --ava-shadow:0 0 14px color-mix(in srgb, var(--accent) 45%, transparent);
109
+ --hero-lede:#dcb693;
110
+ --hero-b:var(--accent-deep);
111
+ --foot-ink:#b89272;
112
+ --foot-code:var(--accent-deep);
113
+ --shadow-card:0 24px 60px -24px rgba(0,0,0,.6), 0 6px 22px -8px rgba(0,0,0,.4);
89
114
  color-scheme:dark;
90
115
  }
91
116
  @media (prefers-color-scheme: dark){
92
117
  :root:not([data-mode="light"]){
93
- --bg:#0d0f28; --bg-card:#12142e; --bg-deep:#1d2046;
94
- --ink:#f4eee7; --ink-soft:#c9bfb2; --ink-faint:#93897d;
95
- --rule:#5a4a7a; --rule-soft:#3a3560;
118
+ --bg:#150c06; --bg-card:#2c1710; --bg-deep:#3f2317;
119
+ --ink:#fdeedd; --ink-soft:#dcb693; --ink-faint:#b89272;
120
+ --rule:#5e3521; --rule-soft:#3f2317;
121
+ --accent-deep:color-mix(in srgb, var(--accent) 45%, #ffffff);
96
122
  --ok:#4ade80; --warn:#fbbf24; --err:#f87171;
97
- --page-bg:#05060f;
98
- --sky-bg:radial-gradient(120% 85% at 50% -12%, #2b2456 0%, rgba(43,36,86,0) 55%),
99
- radial-gradient(70% 55% at 82% 112%, rgba(56,120,200,.16), transparent 62%),
100
- radial-gradient(58% 48% at 12% 6%, rgba(120,70,160,.14), transparent 60%),
101
- linear-gradient(180deg, #05060f 0%, #0a0c20 48%, #0d0f28 100%);
123
+ --page-bg:#150c06;
124
+ --sky-bg:#150c06;
102
125
  --star-display:block;
103
- --chrome-ink:#ffffff;
104
- --chrome-ink-dim:rgba(255,255,255,0.85);
105
- --chrome-accent:#fb923c;
106
- --chrome-glow:0 2px 12px rgba(20,12,30,.7);
107
- --glass-ink:#ffd98a;
108
- --glass-bg:rgba(255,255,255,0.06);
109
- --glass-border:rgba(255,217,138,0.45);
110
- --ava-shadow:0 0 14px rgba(251,146,60,.45);
111
- --hero-lede:rgba(255,255,255,0.82);
112
- --hero-b:#ffd98a;
113
- --foot-ink:rgba(255,255,255,0.55);
114
- --foot-code:#ffd98a;
126
+ --chrome-ink:#fdeedd;
127
+ --chrome-ink-dim:#dcb693;
128
+ --chrome-accent:var(--accent-deep);
129
+ --chrome-glow:0 2px 12px rgba(0,0,0,.65);
130
+ --glass-ink:var(--accent-deep);
131
+ --glass-bg:rgba(255,255,255,0.07);
132
+ --glass-border:color-mix(in srgb, var(--accent) 42%, transparent);
133
+ --ava-shadow:0 0 14px color-mix(in srgb, var(--accent) 45%, transparent);
134
+ --hero-lede:#dcb693;
135
+ --hero-b:var(--accent-deep);
136
+ --foot-ink:#b89272;
137
+ --foot-code:var(--accent-deep);
138
+ --shadow-card:0 24px 60px -24px rgba(0,0,0,.6), 0 6px 22px -8px rgba(0,0,0,.4);
115
139
  color-scheme:dark;
116
140
  }
117
141
  }
@@ -125,7 +149,19 @@
125
149
  --accent-soft:color-mix(in srgb, var(--accent) 15%, var(--bg-card));
126
150
  --sea-soft:color-mix(in srgb, var(--sea) 16%, var(--bg-card));
127
151
  --neutral-soft:color-mix(in srgb, var(--ink) 8%, var(--bg-card));
128
- --shadow-card:0 24px 60px -24px rgba(5,6,15,.55), 0 6px 22px -8px rgba(5,6,15,.35);
152
+ /* ink-derived so the shadow is a WARM brown on the marigold ground instead of
153
+ the cold navy it used to cast. The dark blocks override it with a plain black
154
+ — in dark, --ink is near-white and this formula would glow, not shade. */
155
+ --shadow-card:0 18px 44px -22px color-mix(in srgb, var(--ink) 42%, transparent), 0 4px 14px -6px color-mix(in srgb, var(--ink) 20%, transparent);
156
+
157
+ /* layout tier (task 1002748) — mode-independent, so it lives with the derived
158
+ tier and not in the light/dark blocks. Named "pad"/"fs" rather than "space"
159
+ because --space-deep/mid/high above are the gate's SKY palette. */
160
+ --pad-xs:8px; --pad-sm:14px;
161
+ --pad-md:clamp(15px,2.2vw,22px); /* gutter between grid cells */
162
+ --pad-lg:clamp(19px,2.6vw,28px); /* padding inside a marketing panel */
163
+ --pad-xl:clamp(38px,6vw,78px); /* rhythm between sections */
164
+ --fs-h2:clamp(22px,3vw,29px); --fs-h3:17.5px; --fs-lede:15.5px; --fs-body:14.5px;
129
165
  }
130
166
 
131
167
  *{box-sizing:border-box;margin:0;padding:0;}
@@ -241,7 +277,7 @@ h1{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32
241
277
  @media (prefers-color-scheme: dark){:root:not([data-mode="light"]) .addr code{color:var(--sun-lit);}}
242
278
  .attach{display:flex;gap:10px;margin-top:10px;flex-wrap:wrap;}
243
279
  .attach input[type=text]{flex:1;min-width:220px;font-family:var(--font-body);font-size:15px;font-weight:600;color:var(--ink);background:var(--bg-card);border:2px solid var(--line);border-radius:12px;padding:9px 14px;outline:none;transition:border-color .15s ease, box-shadow .15s ease;}
244
- .attach input[type=text]::placeholder{color:color-mix(in srgb,var(--ink-faint) 70%,var(--bg-card));font-weight:500;}
280
+ .attach input[type=text]::placeholder{color:var(--ink-faint);font-weight:500;}
245
281
  .attach input[type=text]:focus{border-color:var(--accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 13%,transparent);}
246
282
  .projMsg{font-size:13.5px;font-weight:600;margin-top:10px;min-height:18px;color:var(--ink-soft);line-height:1.5;}
247
283
  .projMsg.ok{color:var(--ok);}
@@ -272,7 +308,7 @@ h1{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32
272
308
  .strip .stages li.now .sdot{border-color:var(--sea);}
273
309
  .strip .stages li.now .sdot::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--sea);animation:beatPulse 1.2s ease-in-out infinite;}
274
310
  @keyframes beatPulse{0%,100%{transform:scale(.7);opacity:.6}50%{transform:scale(1.15);opacity:1}}
275
- .strip .slbl{font-size:12px;font-weight:700;color:color-mix(in srgb,var(--sea) 55%,var(--ink-faint));}
311
+ .strip .slbl{font-size:12px;font-weight:700;color:var(--ink-faint);}
276
312
  .strip .stages li.now .slbl,.strip .stages li.done .slbl{color:color-mix(in srgb,var(--sea) 40%,var(--ink));}
277
313
  .strip .pnote{text-align:center;font-size:13px;font-weight:600;color:var(--ink-soft);min-height:18px;line-height:1.5;}
278
314
  .strip .pnote a{color:var(--accent-deep);font-weight:700;text-decoration:none;}
@@ -291,6 +327,29 @@ h1{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32
291
327
  .strip.flowDown .slbl{color:var(--ink-faint);}
292
328
  .strip.flowDown .stages li.now .slbl,.strip.flowDown .stages li.done .slbl{color:var(--ink-soft);}
293
329
 
330
+ /* ── layout primitives (task 1002748, direction §6). cosmos.css was built for
331
+ /create and /projects — two single-column forms — so it had no page container,
332
+ no type scale below h1, no section rhythm and no grid. The landing page needed
333
+ all five; they live HERE rather than page-locally so the marketing surface and
334
+ the working surfaces stay one system instead of two that merely resemble each
335
+ other. `.hero` above is the /create + /projects page-title block and is a
336
+ different thing from a landing hero — both are kept. ── */
337
+ .wrap{position:relative;z-index:1;max-width:1060px;margin:0 auto;padding:0 clamp(16px,4vw,40px);}
338
+ .sec{margin-bottom:var(--pad-xl);}
339
+ h2.sec-h{font-family:var(--font-display);font-weight:700;font-size:var(--fs-h2);letter-spacing:-0.6px;line-height:1.15;margin-bottom:10px;}
340
+ h3.sec-h3{font-family:var(--font-display);font-weight:700;font-size:var(--fs-h3);letter-spacing:-0.3px;line-height:1.25;margin-bottom:8px;}
341
+ p.sec-p{font-size:var(--fs-lede);font-weight:500;color:var(--ink-soft);line-height:1.6;max-width:60ch;}
342
+ /* the one grid primitive: cells never narrower than --col, gutter from the
343
+ spacing scale. `.pair` is the two-up variant that collapses at the mid
344
+ breakpoint — the shape a doors/split row wants. */
345
+ .grid{display:grid;gap:var(--pad-md);grid-template-columns:repeat(auto-fit,minmax(var(--col,238px),1fr));}
346
+ .grid.pair{grid-template-columns:1fr 1fr;}
347
+
348
+ /* ── the mid breakpoint: where a two-up layout stops fitting a tablet. ── */
349
+ @media (max-width:900px){
350
+ .grid.pair{grid-template-columns:1fr;}
351
+ }
352
+
294
353
  /* ── page-level bits ── */
295
354
  .alert{display:none;background:var(--err-soft);border:2px solid color-mix(in srgb,var(--err) 25%,transparent);color:var(--err);font-weight:600;font-size:14px;border-radius:14px;padding:12px 16px;margin-bottom:18px;}
296
355
  .alert.on{display:block;}
@@ -131,7 +131,8 @@ input[type=text]{
131
131
  background:var(--bg-card);border:2px solid var(--line);border-radius:14px;padding:13px 16px;outline:none;
132
132
  transition:border-color .15s ease, box-shadow .15s ease;
133
133
  }
134
- input[type=text]::placeholder{color:color-mix(in srgb,var(--ink-faint) 70%,var(--bg-card));font-weight:500;}
134
+ /* no fade toward the card — a 70% mix washed placeholders to 2.89:1 (task 1002749) */
135
+ input[type=text]::placeholder{color:var(--ink-faint);font-weight:500;}
135
136
  input[type=text]:focus{border-color:var(--accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 13%,transparent);}
136
137
  input[type=text].bad{border-color:var(--err);}
137
138
  .hint{font-size:13px;font-weight:600;color:var(--ink-faint);margin-top:7px;min-height:18px;}
@@ -328,7 +329,9 @@ input[type=text].bad{border-color:var(--err);}
328
329
  .ghrow:last-child{border-bottom:0;}
329
330
  .ghrow:hover{background:color-mix(in srgb,var(--accent) 6%,var(--bg-deep));}
330
331
  .ghrow[aria-selected=true]{background:color-mix(in srgb,var(--accent) 12%,var(--bg-deep));box-shadow:inset 3px 0 0 var(--accent);font-weight:600;}
331
- .ghrow .priv{margin-left:auto;font-size:11px;font-weight:600;color:var(--ink-faint);background:color-mix(in srgb,var(--ink) 8%,transparent);border-radius:5px;padding:1px 6px;}
332
+ /* --ink-soft, not --ink-faint: the badge tint is the darkest ground on the page,
333
+ and faint ink only reaches 3.96:1 on it (task 1002749). */
334
+ .ghrow .priv{margin-left:auto;font-size:11px;font-weight:600;color:var(--ink-soft);background:color-mix(in srgb,var(--ink) 8%,transparent);border-radius:5px;padding:1px 6px;}
332
335
  </style>
333
336
  </head>
334
337
  <body>