apply Court Tech brand design across app
Switch from Outfit/red accent to Inter/Electric Blue (Court Tech Proposal 1). Updates Pico CSS overrides, planner CSS variables, Chart.js colors, and Google Fonts. Deep Navy #0F172A backgrounds, Electric Blue #3B82F6 accent, Vibrant Green #10B981 success, Soft White #F8FAFC headings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,12 +9,12 @@
|
||||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||||
<div class="scenario-item__name">{{ s.name }}</div>
|
||||
<div style="display:flex;gap:6px">
|
||||
{% if s.is_default %}<span style="font-size:10px;color:var(--gn,#3dba78)">default</span>{% endif %}
|
||||
<button onclick="loadScenario({{ s.id }})" style="background:none;border:none;color:var(--bl,#4a90d9);cursor:pointer;font-size:11px;padding:0">Load</button>
|
||||
{% if s.is_default %}<span style="font-size:10px;color:var(--gn,#10B981)">default</span>{% endif %}
|
||||
<button onclick="loadScenario({{ s.id }})" style="background:none;border:none;color:var(--bl,#3B82F6);cursor:pointer;font-size:11px;padding:0">Load</button>
|
||||
<button hx-delete="{{ url_for('planner.delete_scenario', scenario_id=s.id) }}"
|
||||
hx-target="#scenario-drawer" hx-swap="innerHTML"
|
||||
hx-confirm="Delete this scenario?"
|
||||
style="background:none;border:none;color:var(--rd,#d94f4f);cursor:pointer;font-size:11px;padding:0">Del</button>
|
||||
style="background:none;border:none;color:var(--rd,#3B82F6);cursor:pointer;font-size:11px;padding:0">Del</button>
|
||||
</div>
|
||||
</div>
|
||||
{% if s.location %}<div class="scenario-item__meta">{{ s.location }}</div>{% endif %}
|
||||
@@ -22,5 +22,5 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p style="color:var(--txt-3,#4d6278);font-size:13px">No saved scenarios yet. Use the Save button to store your current plan.</p>
|
||||
<p style="color:var(--txt-3,#64748B);font-size:13px">No saved scenarios yet. Use the Save button to store your current plan.</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,39 +1,55 @@
|
||||
/* Padelnomics — Pico CSS brand overrides */
|
||||
/* Padelnomics — Court Tech brand overrides for Pico CSS */
|
||||
|
||||
:root[data-theme="dark"] {
|
||||
/* Background layers */
|
||||
--pico-background-color: #0b0f14;
|
||||
--pico-card-background-color: #111820;
|
||||
--pico-card-sectioning-background-color: #171f2a;
|
||||
/* Background layers — Deep Navy family */
|
||||
--pico-background-color: #0F172A;
|
||||
--pico-card-background-color: #1E293B;
|
||||
--pico-card-sectioning-background-color: #253347;
|
||||
|
||||
/* Text */
|
||||
--pico-color: #b8c9da;
|
||||
--pico-muted-color: #7a8fa3;
|
||||
--pico-muted-border-color: rgba(255,255,255,0.06);
|
||||
/* Text — Soft White / Slate */
|
||||
--pico-color: #CBD5E1;
|
||||
--pico-muted-color: #94A3B8;
|
||||
--pico-muted-border-color: rgba(255,255,255,0.08);
|
||||
|
||||
/* Primary accent (red) */
|
||||
--pico-primary: #d94f4f;
|
||||
--pico-primary-hover: #c94545;
|
||||
--pico-primary-focus: rgba(217,79,79,0.25);
|
||||
/* Primary accent — Electric Blue */
|
||||
--pico-primary: #3B82F6;
|
||||
--pico-primary-hover: #2563EB;
|
||||
--pico-primary-focus: rgba(59,130,246,0.25);
|
||||
--pico-primary-inverse: #fff;
|
||||
|
||||
/* Typography */
|
||||
--pico-font-family: 'Outfit', system-ui, sans-serif;
|
||||
/* Secondary — Charcoal */
|
||||
--pico-secondary: #94A3B8;
|
||||
--pico-secondary-hover: #CBD5E1;
|
||||
--pico-secondary-focus: rgba(148,163,184,0.25);
|
||||
--pico-secondary-inverse: #0F172A;
|
||||
|
||||
/* Typography — Inter */
|
||||
--pico-font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
--pico-font-family-monospace: 'JetBrains Mono', monospace;
|
||||
|
||||
/* Borders */
|
||||
--pico-border-color: rgba(255,255,255,0.06);
|
||||
--pico-border-color: #334155;
|
||||
|
||||
/* Form styling */
|
||||
--pico-form-element-background-color: #171f2a;
|
||||
--pico-form-element-border-color: rgba(255,255,255,0.1);
|
||||
--pico-form-element-focus-color: #d94f4f;
|
||||
--pico-form-element-background-color: #1E293B;
|
||||
--pico-form-element-border-color: #334155;
|
||||
--pico-form-element-focus-color: #3B82F6;
|
||||
}
|
||||
|
||||
/* Headings use warm cream */
|
||||
/* Headings — Soft White, Inter */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #e8dcc8;
|
||||
font-family: 'Outfit', system-ui, sans-serif;
|
||||
color: #F8FAFC;
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
/* Data & metrics use monospace */
|
||||
.metric, .mono, [data-mono] {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* Success states — Vibrant Green */
|
||||
.success, [data-success] {
|
||||
color: #10B981;
|
||||
}
|
||||
|
||||
article {
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
/* Padelnomics Planner — scoped under .planner-app */
|
||||
/* Isolates planner from Pico CSS resets */
|
||||
/* Court Tech brand — Deep Navy + Electric Blue */
|
||||
|
||||
.planner-app {
|
||||
--bg: #0b0f14;
|
||||
--bg-2: #111820;
|
||||
--bg-3: #171f2a;
|
||||
--bg-4: #1d2733;
|
||||
--border: rgba(255,255,255,0.06);
|
||||
--border-2: rgba(255,255,255,0.1);
|
||||
--txt: #b8c9da;
|
||||
--txt-2: #7a8fa3;
|
||||
--txt-3: #4d6278;
|
||||
--head: #e8dcc8;
|
||||
--wht: #f5f0e8;
|
||||
--rd: #d94f4f;
|
||||
--rd-bg: rgba(217,79,79,0.08);
|
||||
--gn: #3dba78;
|
||||
--gn-bg: rgba(61,186,120,0.08);
|
||||
--bl: #4a90d9;
|
||||
--bl-bg: rgba(74,144,217,0.08);
|
||||
--am: #d4a03c;
|
||||
--am-bg: rgba(212,160,60,0.08);
|
||||
--bg: #0F172A;
|
||||
--bg-2: #1E293B;
|
||||
--bg-3: #253347;
|
||||
--bg-4: #2D3F54;
|
||||
--border: rgba(255,255,255,0.08);
|
||||
--border-2: rgba(255,255,255,0.12);
|
||||
--txt: #CBD5E1;
|
||||
--txt-2: #94A3B8;
|
||||
--txt-3: #64748B;
|
||||
--head: #F8FAFC;
|
||||
--wht: #F8FAFC;
|
||||
--rd: #3B82F6;
|
||||
--rd-bg: rgba(59,130,246,0.08);
|
||||
--gn: #10B981;
|
||||
--gn-bg: rgba(16,185,129,0.08);
|
||||
--bl: #3B82F6;
|
||||
--bl-bg: rgba(59,130,246,0.08);
|
||||
--am: #F59E0B;
|
||||
--am-bg: rgba(245,158,11,0.08);
|
||||
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 14px;
|
||||
color: var(--txt);
|
||||
background: var(--bg);
|
||||
@@ -81,7 +81,7 @@
|
||||
background: transparent;
|
||||
color: var(--txt-2);
|
||||
cursor: pointer;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 500;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
@@ -109,7 +109,7 @@
|
||||
color: var(--txt-3);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: 'Inter', sans-serif;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
@@ -267,7 +267,7 @@
|
||||
outline: none;
|
||||
}
|
||||
.slider-combo input[type=number]:focus {
|
||||
border-color: rgba(217,79,79,0.5);
|
||||
border-color: rgba(59,130,246,0.5);
|
||||
}
|
||||
/* Hide number spinners */
|
||||
.slider-combo input[type=number]::-webkit-outer-spin-button,
|
||||
@@ -295,7 +295,7 @@
|
||||
color: var(--txt-3);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: 'Inter', sans-serif;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.toggle-btn--active {
|
||||
@@ -325,7 +325,7 @@
|
||||
}
|
||||
.data-table td {
|
||||
padding: 6px 8px;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: var(--txt);
|
||||
}
|
||||
.data-table td.mono {
|
||||
@@ -383,7 +383,7 @@
|
||||
margin-left: 4px;
|
||||
flex-shrink: 0;
|
||||
font-style: italic;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: 'Inter', sans-serif;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ti .tp {
|
||||
@@ -465,7 +465,7 @@
|
||||
color: #fff;
|
||||
}
|
||||
.lead-cta-bar a:first-of-type:hover {
|
||||
background: #c94545;
|
||||
background: #2563EB;
|
||||
}
|
||||
.lead-cta-bar a:last-of-type {
|
||||
background: transparent;
|
||||
@@ -505,7 +505,7 @@
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.lead-cta__btn:hover {
|
||||
background: #c94545;
|
||||
background: #2563EB;
|
||||
}
|
||||
|
||||
/* ── Exit waterfall ── */
|
||||
|
||||
@@ -462,9 +462,9 @@ function renderCapex(d){
|
||||
renderChart('chartCapex','doughnut',{
|
||||
labels:d.capexItems.filter(i=>i.amount>0).map(i=>i.name),
|
||||
datasets:[{data:d.capexItems.filter(i=>i.amount>0).map(i=>i.amount),
|
||||
backgroundColor:['#d94f4f','#4a90d9','#3dba78','#d4a03c','#8b5cf6','#ec4899','#06b6d4','#84cc16','#f97316','#6366f1','#14b8a6','#a855f7','#ef4444','#22c55e','#eab308'],
|
||||
backgroundColor:['#3B82F6','#10B981','#F59E0B','#8B5CF6','#EC4899','#06B6D4','#84CC16','#F97316','#6366F1','#14B8A6','#A855F7','#EF4444','#22C55E','#EAB308','#2563EB'],
|
||||
borderWidth:0}]
|
||||
},{plugins:{legend:{position:'right',labels:{color:'#7a8fa3',font:{size:10,family:'Outfit'},boxWidth:10,padding:6}}}});
|
||||
},{plugins:{legend:{position:'right',labels:{color:'#94A3B8',font:{size:10,family:'Inter'},boxWidth:10,padding:6}}}});
|
||||
}
|
||||
|
||||
function renderOperating(d){
|
||||
@@ -499,10 +499,10 @@ function renderOperating(d){
|
||||
renderChart('chartRevRamp','bar',{
|
||||
labels:rampData.map(m=>'M'+m.m),
|
||||
datasets:[
|
||||
{label:'Revenue',data:rampData.map(m=>Math.round(m.totalRev)),backgroundColor:'rgba(61,186,120,0.5)',borderRadius:3},
|
||||
{label:'OpEx+Debt',data:rampData.map(m=>Math.round(Math.abs(m.opex)+Math.abs(m.loan))),backgroundColor:'rgba(217,79,79,0.4)',borderRadius:3},
|
||||
{label:'Revenue',data:rampData.map(m=>Math.round(m.totalRev)),backgroundColor:'rgba(16,185,129,0.5)',borderRadius:3},
|
||||
{label:'OpEx+Debt',data:rampData.map(m=>Math.round(Math.abs(m.opex)+Math.abs(m.loan))),backgroundColor:'rgba(239,68,68,0.4)',borderRadius:3},
|
||||
]
|
||||
},{scales:{x:{ticks:{maxTicksLimit:12,color:'#4d6278',font:{size:9}}},y:{ticks:{color:'#4d6278',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{labels:{color:'#7a8fa3',font:{size:10}}}}});
|
||||
},{scales:{x:{ticks:{maxTicksLimit:12,color:'#64748B',font:{size:9}}},y:{ticks:{color:'#64748B',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{labels:{color:'#94A3B8',font:{size:10}}}}});
|
||||
|
||||
const plData = [
|
||||
{label:'Court Rev',val:Math.round(d.courtRevMonth)},
|
||||
@@ -513,8 +513,8 @@ function renderOperating(d){
|
||||
];
|
||||
renderChart('chartPL','bar',{
|
||||
labels:plData.map(p=>p.label),
|
||||
datasets:[{data:plData.map(p=>p.val),backgroundColor:plData.map(p=>p.val>=0?'rgba(61,186,120,0.6)':'rgba(217,79,79,0.5)'),borderRadius:4}]
|
||||
},{indexAxis:'y',scales:{x:{ticks:{color:'#4d6278',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}},y:{ticks:{color:'#7a8fa3',font:{size:10}}}},plugins:{legend:{display:false}}});
|
||||
datasets:[{data:plData.map(p=>p.val),backgroundColor:plData.map(p=>p.val>=0?'rgba(16,185,129,0.6)':'rgba(239,68,68,0.5)'),borderRadius:4}]
|
||||
},{indexAxis:'y',scales:{x:{ticks:{color:'#64748B',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}},y:{ticks:{color:'#94A3B8',font:{size:10}}}},plugins:{legend:{display:false}}});
|
||||
}
|
||||
|
||||
function renderCashflow(d){
|
||||
@@ -530,13 +530,13 @@ function renderCashflow(d){
|
||||
renderChart('chartCF','bar',{
|
||||
labels:d.months.map(m=>m.m%12===1?'Y'+m.yr:''),
|
||||
datasets:[{data:d.months.map(m=>Math.round(m.ncf)),
|
||||
backgroundColor:d.months.map(m=>m.ncf>=0?'rgba(61,186,120,0.5)':'rgba(217,79,79,0.4)'),borderRadius:2}]
|
||||
},{scales:{x:{ticks:{color:'#4d6278',font:{size:9}}},y:{ticks:{color:'#4d6278',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
backgroundColor:d.months.map(m=>m.ncf>=0?'rgba(16,185,129,0.5)':'rgba(239,68,68,0.4)'),borderRadius:2}]
|
||||
},{scales:{x:{ticks:{color:'#64748B',font:{size:9}}},y:{ticks:{color:'#64748B',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
|
||||
renderChart('chartCum','line',{
|
||||
labels:d.months.map(m=>m.m%6===1?'M'+m.m:''),
|
||||
datasets:[{data:d.months.map(m=>Math.round(m.cum)),borderColor:'#4a90d9',backgroundColor:'rgba(74,144,217,0.08)',fill:true,pointRadius:0,tension:0.3}]
|
||||
},{scales:{x:{ticks:{color:'#4d6278',font:{size:9}}},y:{ticks:{color:'#4d6278',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
datasets:[{data:d.months.map(m=>Math.round(m.cum)),borderColor:'#3B82F6',backgroundColor:'rgba(59,130,246,0.08)',fill:true,pointRadius:0,tension:0.3}]
|
||||
},{scales:{x:{ticks:{color:'#64748B',font:{size:9}}},y:{ticks:{color:'#64748B',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
|
||||
let rows = d.annuals.map(y=>{
|
||||
const dscr = y.ds>0?y.ebitda/y.ds:999;
|
||||
@@ -577,8 +577,8 @@ function renderReturns(d){
|
||||
|
||||
renderChart('chartDSCR','bar',{
|
||||
labels:d.dscr.map(x=>'Y'+x.year),
|
||||
datasets:[{data:d.dscr.map(x=>Math.min(x.dscr,10)),backgroundColor:d.dscr.map(x=>x.dscr>=1.2?'rgba(61,186,120,0.5)':'rgba(217,79,79,0.5)'),borderRadius:4}]
|
||||
},{scales:{x:{ticks:{color:'#7a8fa3'}},y:{ticks:{color:'#4d6278',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
datasets:[{data:d.dscr.map(x=>Math.min(x.dscr,10)),backgroundColor:d.dscr.map(x=>x.dscr>=1.2?'rgba(16,185,129,0.5)':'rgba(239,68,68,0.5)'),borderRadius:4}]
|
||||
},{scales:{x:{ticks:{color:'#94A3B8'}},y:{ticks:{color:'#64748B',font:{size:9}},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
|
||||
const utils = [15,20,25,30,35,40,45,50,55,60,65,70];
|
||||
const isIn = S.venue==='indoor';
|
||||
@@ -655,8 +655,8 @@ function renderSeasonChart(){
|
||||
const months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
||||
renderChart('chartSeason','bar',{
|
||||
labels:months,
|
||||
datasets:[{data:S.season.map(s=>s*100),backgroundColor:S.season.map(s=>s>0?'rgba(61,186,120,0.5)':'rgba(217,79,79,0.2)'),borderRadius:4}]
|
||||
},{scales:{x:{ticks:{color:'#7a8fa3'}},y:{max:110,ticks:{color:'#4d6278'},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
datasets:[{data:S.season.map(s=>s*100),backgroundColor:S.season.map(s=>s>0?'rgba(16,185,129,0.5)':'rgba(239,68,68,0.2)'),borderRadius:4}]
|
||||
},{scales:{x:{ticks:{color:'#94A3B8'}},y:{max:110,ticks:{color:'#64748B'},grid:{color:'rgba(255,255,255,0.03)'}}},plugins:{legend:{display:false}}});
|
||||
}
|
||||
|
||||
// ── Chart Helper ──────────────────────────────────────────
|
||||
@@ -667,15 +667,15 @@ function renderChart(canvasId,type,data,opts={}){
|
||||
const defaults = {
|
||||
responsive:true, maintainAspectRatio:false, animation:{duration:0},
|
||||
scales:{},
|
||||
plugins:{legend:{labels:{color:'#7a8fa3',font:{family:'Outfit',size:10}}}},
|
||||
plugins:{legend:{labels:{color:'#94A3B8',font:{family:'Inter',size:10}}}},
|
||||
};
|
||||
if(type==='doughnut'||type==='pie'){
|
||||
delete defaults.scales;
|
||||
defaults.cutout = '55%';
|
||||
} else {
|
||||
defaults.scales = {
|
||||
x:{ticks:{color:'#4d6278',font:{size:9,family:'Outfit'}},grid:{display:false},border:{color:'rgba(255,255,255,0.06)'}},
|
||||
y:{ticks:{color:'#4d6278',font:{size:9,family:'JetBrains Mono'}},grid:{color:'rgba(255,255,255,0.03)'},border:{color:'rgba(255,255,255,0.06)'}},
|
||||
x:{ticks:{color:'#64748B',font:{size:9,family:'Inter'}},grid:{display:false},border:{color:'rgba(255,255,255,0.08)'}},
|
||||
y:{ticks:{color:'#64748B',font:{size:9,family:'JetBrains Mono'}},grid:{color:'rgba(255,255,255,0.03)'},border:{color:'rgba(255,255,255,0.06)'}},
|
||||
};
|
||||
}
|
||||
charts[canvasId] = new Chart(ctx,{type,data,options:deepMerge(defaults,opts)});
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Outfit:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Brand overrides -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/custom.css') }}">
|
||||
|
||||
Reference in New Issue
Block a user