diff --git a/src/App.css b/src/App.css index 53e7b79..ba4e807 100644 --- a/src/App.css +++ b/src/App.css @@ -2440,6 +2440,190 @@ html[dir="rtl"] .exportable-chart-wrapper .chart-export-btn.visible { .controls-reset:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } .alt-filter-reset:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +/* ======================================== + Alt-page components (Dashboard + Comparison) + Font vars are set via style prop on .alt-page: + --alt-body-font, --alt-display-font, --alt-mono-font + ======================================== */ + +:root { + --alt-body-font: 'Outfit', sans-serif; + --alt-display-font: 'DM Serif Display', serif; + --alt-mono-font: ui-monospace, 'Cascadia Code', monospace; +} + +/* ── page shell ── */ +.alt-page { max-width:1400px; margin:0 auto; padding:48px 24px 80px; font-family:var(--alt-body-font); width:100%; box-sizing:border-box; } + +/* ── header ── */ +.alt-back { display:inline-flex; align-items:center; gap:6px; font-size:.8125rem; color:var(--text-muted); text-decoration:none; margin-bottom:28px; transition:color .15s; } +.alt-back:hover { color:var(--accent); } +.alt-page-title { font-family:var(--alt-display-font); font-size:2.25rem; font-weight:400; color:var(--text-primary); margin:0 0 6px; letter-spacing:-.03em; line-height:1.15; } +.alt-page-sub { font-size:.9375rem; color:var(--text-muted); margin:0 0 40px; font-weight:300; } + +/* ── hero (Dashboard) ── */ +.dalt-hero { border:1px solid var(--border); border-radius:var(--radius); background:var(--surface); overflow:hidden; margin-bottom:24px; } +.dalt-hero-inner { display:flex; align-items:center; justify-content:space-between; padding:24px 28px; gap:16px; flex-wrap:wrap; } +.dalt-hero-name { font-family:var(--alt-display-font); font-size:2.5rem; font-weight:400; color:var(--text-primary); line-height:1; letter-spacing:-.025em; margin-bottom:6px; } +.dalt-hero-range { font-family:var(--alt-mono-font); font-size:.875rem; color:var(--text-muted); letter-spacing:.01em; } +.dalt-hero-btn { display:inline-flex; align-items:center; gap:5px; font-family:var(--alt-body-font); font-size:.8125rem; font-weight:500; color:var(--text-muted); background:none; border:1px solid var(--border); border-radius:8px; padding:7px 12px; cursor:pointer; transition:color .15s,border-color .15s; white-space:nowrap; } +.dalt-hero-btn:hover { color:var(--accent); border-color:var(--accent); } +.dalt-hero-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } + +/* ── period row (Comparison) ── */ +.alt-period-row { display:grid; grid-template-columns:1fr auto 1fr; align-items:stretch; margin-bottom:32px; } +.alt-vs { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:0 20px; position:relative; } +.alt-vs-line { position:absolute; top:0; bottom:0; left:50%; width:1px; background:var(--border); } +.alt-vs-badge { font-family:var(--alt-display-font); font-size:.9rem; font-style:italic; color:var(--text-muted); background:var(--bg); padding:6px 10px; border:1px solid var(--border); border-radius:20px; position:relative; z-index:1; } + +/* ── period card (Comparison) ── */ +.alt-card { border:1px solid var(--border); border-radius:var(--radius); background:var(--surface); overflow:hidden; transition:border-color .2s,box-shadow .2s; display:flex; flex-direction:column; } +.alt-card--current { border-radius:var(--radius) 0 0 var(--radius); } +.alt-card--previous { border-radius:0 var(--radius) var(--radius) 0; } +[dir="rtl"] .alt-card--current { border-radius:0 var(--radius) var(--radius) 0; } +[dir="rtl"] .alt-card--previous { border-radius:var(--radius) 0 0 var(--radius); } +.alt-card:hover { box-shadow:var(--shadow); } +.alt-card--current:hover,.alt-card--current.alt-card--open { border-color:var(--accent); } +.alt-card--previous:hover,.alt-card--previous.alt-card--open { border-color:#94a3b8; } +.alt-card-bar { height:3px; width:100%; } +.alt-card--current .alt-card-bar { background:var(--accent); } +.alt-card--previous .alt-card-bar { background:#94a3b8; } +.alt-card-body { padding:24px 28px 20px; flex:1; } +.alt-role-row { display:flex; align-items:baseline; gap:8px; margin-bottom:12px; } +.alt-role { font-size:.6875rem; font-weight:700; text-transform:uppercase; letter-spacing:.1em; } +.alt-card--current .alt-role { color:var(--accent); } +.alt-card--previous .alt-role { color:#64748b; } +.alt-role-hint { font-size:.75rem; color:var(--text-muted); font-weight:300; } +.alt-period-name { font-family:var(--alt-display-font); font-size:2.25rem; font-weight:400; color:var(--text-primary); line-height:1.1; letter-spacing:-.02em; margin-bottom:8px; } +.alt-date-range { font-family:var(--alt-mono-font); font-size:.8125rem; color:var(--text-muted); letter-spacing:.01em; margin-bottom:20px; } +.alt-change-btn { display:inline-flex; align-items:center; gap:5px; font-family:var(--alt-body-font); font-size:.8125rem; font-weight:500; color:var(--text-muted); background:none; border:none; padding:0; cursor:pointer; transition:color .15s; } +.alt-card--current .alt-change-btn:hover { color:var(--accent); } +.alt-card--previous .alt-change-btn:hover { color:var(--text-primary); } + +/* ── picker ── */ +@keyframes altPickIn { from{opacity:0;transform:translateY(-8px)} to{opacity:1;transform:translateY(0)} } +.alt-picker { border-top:1px solid var(--border); padding:16px 24px 20px; background:var(--bg); animation:altPickIn 180ms cubic-bezier(.16,1,.3,1); } +.alt-picker-year { display:flex; align-items:center; gap:16px; margin-bottom:16px; padding-bottom:12px; border-bottom:1px solid var(--border); } +.alt-yr-val { font-family:var(--alt-display-font); font-size:1.25rem; color:var(--text-primary); min-width:50px; text-align:center; } +.alt-yr-btn { width:28px; height:28px; display:flex; align-items:center; justify-content:center; border:1px solid var(--border); border-radius:7px; background:var(--surface); color:var(--text-secondary); cursor:pointer; transition:background .12s,border-color .12s,color .12s; } +.alt-yr-btn:hover:not(:disabled) { background:var(--accent); border-color:var(--accent); color:var(--text-inverse); } +.alt-yr-btn:disabled { opacity:.3; cursor:not-allowed; } +.alt-yr-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.alt-picker-section { font-size:.625rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); margin:10px 0 6px; } +.alt-chips { display:flex; flex-wrap:wrap; gap:5px; margin-bottom:4px; } +.alt-chip { font-family:var(--alt-body-font); padding:4px 9px; border:1px solid var(--border); border-radius:6px; background:var(--surface); color:var(--text-secondary); font-size:.8rem; font-weight:500; cursor:pointer; transition:background .1s,border-color .1s,color .1s; } +.alt-chip:hover { border-color:var(--accent); color:var(--accent); background:var(--accent-light); } +.alt-chip-on { background:var(--accent)!important; border-color:var(--accent)!important; color:var(--text-inverse)!important; font-weight:600!important; } +.alt-chip-wide { padding-left:14px; padding-right:14px; } +.alt-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.alt-picker-div { height:1px; background:var(--border); margin:12px 0 10px; } +.alt-custom { display:flex; align-items:flex-end; gap:8px; } +.alt-custom-f { flex:1; display:flex; flex-direction:column; gap:4px; } +.alt-custom-f label { font-size:.625rem; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:var(--text-muted); } +.alt-custom-f input[type="date"] { padding:7px 9px; border:1px solid var(--border); border-radius:7px; font-size:.825rem; background:var(--surface); color:var(--text-primary); width:100%; } +.alt-custom-f input[type="date"]:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 2px rgba(37,99,235,.12); } +.alt-custom-arrow { font-size:.75rem; color:var(--text-muted); padding-bottom:9px; flex-shrink:0; } +.alt-footer { display:flex; justify-content:flex-end; gap:8px; } +.alt-cancel,.alt-apply { padding:7px 16px; border-radius:7px; font-size:.825rem; font-weight:600; cursor:pointer; font-family:var(--alt-body-font); transition:background .12s,color .12s; } +.alt-cancel { background:transparent; border:1px solid var(--border); color:var(--text-secondary); } +.alt-cancel:hover { background:var(--bg-secondary); } +.alt-apply { background:var(--accent); border:1px solid transparent; color:#fff; } +.alt-apply:hover { opacity:.88; } +.alt-cancel:focus-visible, .alt-apply:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } + +/* ── multi-select ── */ +.altms { position:relative; } +.altms-trigger { display:inline-flex; align-items:center; gap:6px; padding:6px 10px; border:1px solid var(--border); border-radius:8px; background:var(--surface); color:var(--text-secondary); font-family:var(--alt-body-font); font-size:.875rem; cursor:pointer; transition:border-color .15s,color .15s,background .15s; white-space:nowrap; } +.altms-trigger:hover { border-color:var(--accent); color:var(--accent); } +.altms-trigger--active { border-color:var(--accent); color:var(--accent); background:var(--accent-light); } +.altms-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.altms-label { max-width:140px; overflow:hidden; text-overflow:ellipsis; } +.altms-chevron { transition:transform .18s; flex-shrink:0; color:currentColor; } +.altms-chevron--open { transform:rotate(180deg); } +.altms-dropdown { position:absolute; top:calc(100% + 6px); left:0; z-index:200; min-width:200px; background:var(--surface); border:1px solid var(--border); border-radius:10px; box-shadow:0 8px 24px rgba(0,0,0,.12); overflow:hidden; animation:altPickIn 140ms cubic-bezier(.16,1,.3,1); } +[dir="rtl"] .altms-dropdown { left:auto; right:0; } +.altms-list { max-height:220px; overflow-y:auto; padding:6px; display:flex; flex-direction:column; gap:2px; } +.altms-option { display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:6px; cursor:pointer; transition:background .1s; } +.altms-option:hover { background:var(--bg); } +.altms-option--checked { background:var(--accent-light); } +.altms-check { position:absolute; opacity:0; width:0; height:0; pointer-events:none; } +.altms-check-box { width:16px; height:16px; border:1.5px solid var(--border); border-radius:4px; display:flex; align-items:center; justify-content:center; flex-shrink:0; transition:background .1s,border-color .1s; } +.altms-option--checked .altms-check-box { background:var(--accent); border-color:var(--accent); color:var(--text-inverse); } +.altms-opt-label { font-family:var(--alt-body-font); font-size:.875rem; color:var(--text-primary); } +.altms-clear { width:100%; padding:8px 14px; border-top:1px solid var(--border); background:none; border-left:none; border-right:none; border-bottom:none; font-family:var(--alt-body-font); font-size:.8125rem; color:var(--danger); cursor:pointer; text-align:start; transition:background .1s; } +.altms-clear:hover { background:var(--danger-light); } +.altms-clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } + +/* ── filter bar ── */ +.alt-filter-bar { display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:32px; padding:14px 20px; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); } +.alt-filter-label { font-size:.6875rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); white-space:nowrap; } +.alt-filter-sep { width:1px; height:20px; background:var(--border); flex-shrink:0; } +.alt-filter-spacer { flex:1; min-width:0; } +.alt-vat-toggle { display:flex; align-items:center; border:1px solid var(--border); border-radius:8px; overflow:hidden; } +.alt-vat-opt { font-family:var(--alt-body-font); font-size:.75rem; font-weight:500; padding:5px 10px; background:var(--surface); color:var(--text-muted); cursor:pointer; border:none; transition:background .1s,color .1s; } +.alt-vat-opt--on { background:var(--accent); color:var(--text-inverse); } +.alt-filter-reset { font-size:.8125rem; color:var(--text-muted); background:none; border:none; cursor:pointer; padding:4px 6px; transition:color .15s; font-family:var(--alt-body-font); } +.alt-filter-reset:hover { color:var(--danger); } + +/* ── metrics ── */ +.alt-metrics { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; margin-bottom:40px; } +.alt-metric { background:var(--surface); padding:24px 22px; } +.alt-metric-title { font-size:.6875rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); margin:0 0 12px; } +.alt-metric-value { font-family:var(--alt-display-font); font-size:1.875rem; font-weight:400; color:var(--text-primary); line-height:1; margin-bottom:10px; letter-spacing:-.02em; } +.alt-metric-footer { display:flex; align-items:center; gap:8px; flex-wrap:wrap; } +.alt-change { font-size:.75rem; font-weight:600; padding:2px 8px; border-radius:20px; white-space:nowrap; font-family:var(--alt-body-font); } +.alt-change--up { background:var(--success-light); color:var(--success); } +.alt-change--down { background:var(--danger-light); color:var(--danger); } +.alt-change--flat { background:var(--muted-light); color:var(--text-muted); } +.alt-metric-prev { font-size:.75rem; color:var(--text-muted); font-family:var(--alt-mono-font); } + +/* ── section heading ── */ +.alt-section-heading { display:flex; align-items:center; gap:12px; margin:0 0 20px; } +.alt-section-heading h2 { font-family:var(--alt-display-font); font-size:1.375rem; font-weight:400; color:var(--text-primary); margin:0; letter-spacing:-.02em; } +.alt-section-heading::after { content:''; flex:1; height:1px; background:var(--border); } + +/* ── charts (Dashboard) ── */ +.dalt-charts-grid { display:grid; grid-template-columns:1fr 1fr; gap:20px; } +.dalt-chart-full { grid-column:1/-1; } +.alt-chart-card { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:24px 24px 20px; min-width:0; overflow:hidden; } +.alt-chart-header { display:flex; align-items:flex-start; justify-content:space-between; margin-bottom:20px; gap:12px; flex-wrap:wrap; } +.alt-chart-title { font-family:var(--alt-display-font); font-size:1.25rem; font-weight:400; color:var(--text-primary); margin:0; letter-spacing:-.02em; font-style:italic; } +.alt-chart-controls { display:flex; gap:5px; flex-wrap:wrap; } +.alt-ctrl { font-family:var(--alt-body-font); font-size:.75rem; font-weight:500; padding:4px 10px; border:1px solid var(--border); border-radius:6px; background:var(--bg); color:var(--text-secondary); cursor:pointer; transition:background .1s,border-color .1s,color .1s; } +.alt-ctrl:hover { border-color:var(--accent); color:var(--accent); } +.alt-ctrl-on { background:var(--accent)!important; border-color:var(--accent)!important; color:var(--text-inverse)!important; } +.alt-ctrl-sep { width:1px; height:20px; background:var(--border); align-self:center; } +.alt-ctrl:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.alt-chart-wrap { position:relative; height:260px; overflow:hidden; direction:ltr; width:100%; } +.alt-chart-wrap--tall { height:320px; } + +/* ── charts (Comparison) — single-column grid, taller wrap ── */ +.alt-charts { display:grid; grid-template-columns:1fr; gap:24px; } + +/* ── responsive (Dashboard) ── */ +@media (max-width:700px) { + .dalt-hero-name { font-size:1.875rem; } + .dalt-charts-grid { grid-template-columns:1fr; } + .dalt-chart-full { grid-column:auto; } + .alt-metrics { grid-template-columns:1fr 1fr; } + .alt-page-title { font-size:1.75rem; } + .altms-label { max-width:100px; } + .alt-filter-bar { overflow-x:auto; flex-wrap:nowrap; padding-inline:12px; -webkit-overflow-scrolling:touch; } + .altms-trigger { flex-shrink:0; } + .alt-vat-toggle { flex-shrink:0; } + .alt-filter-spacer { display:none; } +} + +/* ── responsive (Comparison) ── */ +@media (max-width:680px) { + .alt-period-row { grid-template-columns:1fr; } + .alt-card--current,.alt-card--previous { border-radius:var(--radius); } + .alt-vs { flex-direction:row; padding:10px 0; } + .alt-vs-line { position:static; width:100%; height:1px; } + .alt-period-name { font-size:1.75rem; } + .alt-chart-header { flex-direction:column; } +} + /* ======================================== Reduced Motion ======================================== */ diff --git a/src/components/Comparison.tsx b/src/components/Comparison.tsx index 2b153a4..d819b9a 100644 --- a/src/components/Comparison.tsx +++ b/src/components/Comparison.tsx @@ -476,162 +476,15 @@ export default function PeriodSelectorDemo({ data, seasons, includeVAT, allowedM const hasFilters = selDistricts.length>0 || selChannels.length>0 || selMuseums.length>0; return ( -