From ef4932b5532a4d9b84c44c0c9cfddd08442a6fea Mon Sep 17 00:00:00 2001 From: Tudor Date: Mon, 2 Feb 2026 21:39:40 +0000 Subject: [PATCH] Match original warm editorial design - Copy complete original styles.css (1900+ lines) to globals.css - Add Google Fonts (DM Sans and Playfair Display) via next/font - Use CSS variables for fonts - Restore warm color palette (#faf7f2 bg, coral/teal accents) - Restore noise overlay texture - Restore all original animations and transitions - Match original card styles, buttons, modals Co-Authored-By: Claude Sonnet 4.5 --- nextjs-app/app/globals.css | 2020 ++++++++++++++++++++++++++++++++---- nextjs-app/app/layout.tsx | 31 +- 2 files changed, 1845 insertions(+), 206 deletions(-) diff --git a/nextjs-app/app/globals.css b/nextjs-app/app/globals.css index 9796381..714ffaa 100644 --- a/nextjs-app/app/globals.css +++ b/nextjs-app/app/globals.css @@ -1,277 +1,1903 @@ -/* CSS Variables */ +/* + * SchoolCompare.co.uk + * A warm, editorial design inspired by quality publications + */ + :root { - --primary: #3b82f6; - --primary-dark: #2563eb; - --secondary: #6b7280; - --success: #22c55e; - --danger: #ef4444; - --warning: #f59e0b; - - --bg-primary: #ffffff; - --bg-secondary: #f9fafb; - --bg-tertiary: #f3f4f6; - - --text-primary: #1f2937; - --text-secondary: #6b7280; - --text-tertiary: #9ca3af; - - --border-light: #e5e7eb; - --border-medium: #d1d5db; - --border-dark: #9ca3af; - - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07); - --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); - - --radius-sm: 4px; - --radius-md: 6px; - --radius-lg: 8px; - --radius-xl: 12px; - - --transition: 0.2s ease; + /* Warm, sophisticated palette */ + --bg-primary: #faf7f2; + --bg-secondary: #f3ede4; + --bg-card: #ffffff; + --bg-accent: #1a1612; + + --text-primary: #1a1612; + --text-secondary: #5c564d; + --text-muted: #8a847a; + --text-inverse: #faf7f2; + + --accent-coral: #e07256; + --accent-coral-dark: #c45a3f; + --accent-teal: #2d7d7d; + --accent-teal-light: #3a9e9e; + --accent-gold: #c9a227; + --accent-navy: #2c3e50; + + /* Chart colors */ + --chart-1: #e07256; + --chart-2: #2d7d7d; + --chart-3: #c9a227; + --chart-4: #7b68a6; + --chart-5: #3498db; + + --border-color: #e5dfd5; + --shadow-soft: 0 2px 8px rgba(26, 22, 18, 0.06); + --shadow-medium: 0 4px 20px rgba(26, 22, 18, 0.1); + --shadow-strong: 0 8px 40px rgba(26, 22, 18, 0.15); + + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 16px; + --radius-xl: 24px; + + --transition: 0.2s ease; + --transition-slow: 0.4s ease; } -/* Reset and Base Styles */ * { - box-sizing: border-box; - padding: 0; - margin: 0; + margin: 0; + padding: 0; + box-sizing: border-box; } html { - scroll-behavior: smooth; -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; + scroll-behavior: smooth; } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - color: var(--text-primary); - background: var(--bg-secondary); - line-height: 1.6; -} - -a { - color: inherit; - text-decoration: none; -} - -/* App Container */ -.app-container { - display: flex; - flex-direction: column; - min-height: 100vh; - position: relative; + font-family: var(--font-dm-sans), 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif; + background: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; + min-height: 100vh; } +/* Subtle noise texture overlay */ .noise-overlay { - position: fixed; - inset: 0; - opacity: 0.03; - z-index: -1; - pointer-events: none; - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + opacity: 0.03; + z-index: 1000; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); } -.main-content { - flex: 1; - max-width: 1280px; - width: 100%; - margin: 0 auto; - padding: 2rem 1.5rem; +/* Header */ +.header { + background: var(--bg-card); + border-bottom: 1px solid var(--border-color); + position: sticky; + top: 0; + z-index: 100; } -/* Utility Classes */ -.container { - max-width: 1280px; - width: 100%; - margin: 0 auto; - padding: 0 1.5rem; +.header-content { + max-width: 1400px; + margin: 0 auto; + padding: 1rem 2rem; + display: flex; + justify-content: space-between; + align-items: center; } -.text-center { - text-align: center; +.logo { + display: flex; + align-items: center; + gap: 0.75rem; + text-decoration: none; + color: inherit; } -.mt-1 { margin-top: 0.5rem; } -.mt-2 { margin-top: 1rem; } -.mt-3 { margin-top: 1.5rem; } -.mt-4 { margin-top: 2rem; } - -.mb-1 { margin-bottom: 0.5rem; } -.mb-2 { margin-bottom: 1rem; } -.mb-3 { margin-bottom: 1.5rem; } -.mb-4 { margin-bottom: 2rem; } - -/* Grid Layouts */ -.grid { - display: grid; - gap: 1.5rem; +.logo-icon { + width: 40px; + height: 40px; + color: var(--accent-coral); } -.grid-1 { - grid-template-columns: 1fr; +.logo-text { + display: flex; + flex-direction: column; } -.grid-2 { - grid-template-columns: repeat(2, 1fr); +.logo-title { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 1.25rem; + font-weight: 700; + color: var(--text-primary); + line-height: 1.2; } -.grid-3 { - grid-template-columns: repeat(3, 1fr); +.logo-subtitle { + font-size: 0.7rem; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.1em; } -.grid-auto { - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); +.nav { + display: flex; + gap: 0.5rem; } -@media (max-width: 1024px) { - .grid-3 { - grid-template-columns: repeat(2, 1fr); - } +.nav-link { + padding: 0.6rem 1.2rem; + text-decoration: none; + color: var(--text-secondary); + font-weight: 500; + font-size: 0.9rem; + border-radius: var(--radius-md); + transition: var(--transition); +} + +.nav-link:hover { + color: var(--text-primary); + background: var(--bg-secondary); +} + +.nav-link.active { + background: var(--bg-accent); + color: var(--text-inverse); +} + +/* Main Content */ +.main { + max-width: 1400px; + margin: 0 auto; + padding: 2rem; +} + +.view { + display: none; + animation: fadeIn 0.3s ease; +} + +.view.active { + display: block; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Hero Section */ +.hero { + text-align: center; + padding: 3rem 0 2rem; +} + +.hero-title { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: clamp(2rem, 5vw, 3.5rem); + font-weight: 700; + color: var(--text-primary); + margin-bottom: 0.75rem; + line-height: 1.2; +} + +.hero-subtitle { + font-size: 1.1rem; + color: var(--text-secondary); + max-width: 600px; + margin: 0 auto; +} + +/* Search Section */ +.search-section { + max-width: 700px; + margin: 2rem auto 3rem; +} + +/* Search Mode Toggle */ +.search-mode-toggle { + display: flex; + justify-content: center; + gap: 0; + margin-bottom: 1.5rem; + background: var(--bg-card); + border: 2px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 4px; + max-width: 400px; + margin-left: auto; + margin-right: auto; +} + +.search-mode-btn { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.75rem 1.25rem; + font-size: 0.95rem; + font-family: inherit; + font-weight: 500; + border: none; + border-radius: var(--radius-md); + background: transparent; + color: var(--text-muted); + cursor: pointer; + transition: var(--transition); +} + +.search-mode-btn:hover { + color: var(--text-primary); +} + +.search-mode-btn.active { + background: var(--accent-coral); + color: white; + box-shadow: 0 2px 8px rgba(224, 114, 86, 0.3); +} + +.search-mode-btn svg { + flex-shrink: 0; +} + +/* Search Panels */ +.search-panel { + display: none; +} + +.search-panel.active { + display: block; +} + +.search-container { + position: relative; + margin-bottom: 1rem; +} + +.search-input { + width: 100%; + padding: 1rem 1.25rem 1rem 3.5rem; + font-size: 1rem; + font-family: inherit; + border: 2px solid var(--border-color); + border-radius: var(--radius-lg); + background: var(--bg-card); + color: var(--text-primary); + transition: var(--transition); +} + +.search-input:focus { + outline: none; + border-color: var(--accent-coral); + box-shadow: 0 0 0 4px rgba(224, 114, 86, 0.1); +} + +.search-input::placeholder { + color: var(--text-muted); +} + +.search-icon { + position: absolute; + left: 1.25rem; + top: 50%; + transform: translateY(-50%); + width: 20px; + height: 20px; + color: var(--text-muted); +} + +.filter-row { + display: flex; + gap: 1rem; + justify-content: center; +} + +.filter-select { + padding: 0.6rem 2rem 0.6rem 1rem; + font-size: 0.9rem; + font-family: inherit; + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + background: var(--bg-card); + color: var(--text-primary); + cursor: pointer; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%235c564d' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + transition: var(--transition); +} + +/* Location Search */ +.location-input-group { + margin-bottom: 1rem; + display: flex; + gap: 0.75rem; + align-items: center; + justify-content: center; + flex-wrap: nowrap; +} + +.postcode-input { + width: auto; + max-width: 180px; + padding: 0.6rem 1rem; + font-size: 0.95rem; +} + +.postcode-input::placeholder { + text-transform: none; +} + +.radius-select { + width: auto; + min-width: 100px; +} + +.location-btn { + padding: 0.6rem 1.25rem; + font-size: 0.9rem; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.location-clear-btn { + padding: 0.6rem 1rem; + font-size: 0.9rem; + background: var(--bg-secondary); + color: var(--text-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + cursor: pointer; + transition: var(--transition); +} + +.location-clear-btn:hover { + background: var(--border-color); + color: var(--text-primary); +} + +.location-info { + text-align: center; + margin-bottom: 1rem; + padding: 0.75rem 1.25rem; + background: var(--accent-teal); + color: var(--text-inverse); + border-radius: var(--radius-md); + font-size: 0.9rem; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +.location-info svg { + width: 16px; + height: 16px; +} + +.distance-badge { + display: inline-block; + padding: 0.25rem 0.5rem; + background: var(--accent-teal); + color: var(--text-inverse); + border-radius: var(--radius-sm); + font-size: 0.75rem; + font-weight: 600; + margin-left: 0.5rem; +} + +.filter-select:focus { + outline: none; + border-color: var(--accent-teal); +} + +/* View Toggle */ +.view-toggle { + display: flex; + gap: 0.5rem; + justify-content: center; + margin-bottom: 1.5rem; +} + +.view-toggle-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.6rem 1rem; + font-size: 0.9rem; + font-family: inherit; + font-weight: 500; + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + background: var(--bg-card); + color: var(--text-muted); + cursor: pointer; + transition: var(--transition); +} + +.view-toggle-btn:hover { + color: var(--text-primary); + border-color: var(--text-muted); +} + +.view-toggle-btn.active { + background: var(--accent-teal); + color: white; + border-color: var(--accent-teal); +} + +.view-toggle-btn svg { + flex-shrink: 0; +} + +/* Results Container */ +.results-container { + display: block; +} + +.results-container .results-map { + display: none; +} + +.results-container.map-view { + display: grid; + grid-template-columns: 1fr 400px; + gap: 1.5rem; + height: 600px; +} + +.results-container.map-view .results-map { + display: block; + border-radius: var(--radius-lg); + overflow: hidden; + border: 1px solid var(--border-color); + height: 100%; + position: relative; + z-index: 1; +} + +.results-container.map-view .schools-grid { + display: flex; + flex-direction: column; + gap: 0.75rem; + overflow-y: auto; + height: 100%; + padding-right: 0.5rem; +} + +.results-container.map-view .schools-grid::-webkit-scrollbar { + width: 6px; +} + +.results-container.map-view .schools-grid::-webkit-scrollbar-track { + background: var(--bg-main); + border-radius: 3px; +} + +.results-container.map-view .schools-grid::-webkit-scrollbar-thumb { + background: var(--border-color); + border-radius: 3px; +} + +.results-container.map-view .schools-grid::-webkit-scrollbar-thumb:hover { + background: var(--text-muted); +} + +/* Highlighted card in map view */ +.school-card.highlighted, +.school-list-item.highlighted { + border-color: var(--accent-teal); + box-shadow: 0 0 0 2px rgba(45, 125, 125, 0.2); +} + +/* Compact school list items for map view */ +.school-list-item { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.875rem 1rem; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + cursor: pointer; + transition: var(--transition); +} + +.school-list-item:hover { + border-color: var(--text-muted); +} + +.school-list-item-content { + flex: 1; + min-width: 0; +} + +.school-list-item-header { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.25rem; +} + +.school-list-item-name { + font-size: 0.95rem; + font-weight: 600; + color: var(--text-primary); + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.school-list-item-header .distance-badge { + flex-shrink: 0; + font-size: 0.75rem; + padding: 0.15rem 0.5rem; +} + +.school-list-item-meta { + display: flex; + gap: 0.5rem; + font-size: 0.8rem; + color: var(--text-muted); + margin-bottom: 0.375rem; +} + +.school-list-item-meta span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.school-list-item-stats { + display: flex; + gap: 1rem; + font-size: 0.8rem; + color: var(--text-secondary); +} + +.school-list-item-stat strong { + color: var(--text-primary); +} + +.school-list-item-actions { + display: flex; + flex-direction: column; + gap: 0.375rem; + flex-shrink: 0; +} + +.school-list-item-actions .btn { + padding: 0.4rem 0.75rem; + font-size: 0.75rem; + white-space: nowrap; +} + +.btn-compare { + background: var(--accent-coral); + color: white; + border: 1px solid var(--accent-coral); +} + +.btn-compare:hover { + background: #d4654a; + border-color: #d4654a; +} + +.btn-compare.active { + background: var(--text-muted); + border-color: var(--text-muted); +} + +/* Search location marker on map */ +.search-location-marker { + background: transparent; +} + +/* Schools Grid */ +.schools-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + gap: 1.5rem; +} + +/* Featured Schools Header */ +.featured-header { + grid-column: 1 / -1; + text-align: center; + padding: 1rem 0 2rem; +} + +.featured-header h3 { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 1.5rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 0.5rem; +} + +.featured-header p { + color: var(--text-muted); + font-size: 0.95rem; +} + +.school-card.featured { + border-color: var(--accent-coral); + border-width: 2px; +} + +.school-card { + display: flex; + flex-direction: column; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 1.5rem; + cursor: pointer; + transition: var(--transition); + position: relative; + overflow: hidden; + z-index: 0; +} + +.school-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 4px; + height: 100%; + background: var(--accent-coral); + transform: scaleY(0); + transition: var(--transition); +} + +.school-card:hover { + border-color: var(--accent-coral); + box-shadow: var(--shadow-medium); + transform: translateY(-2px); +} + +.school-card:hover::before { + transform: scaleY(1); +} + +.school-name { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 1.15rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 0.5rem; +} + +.school-meta { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1rem; +} + +.school-tag { + font-size: 0.75rem; + padding: 0.25rem 0.6rem; + background: var(--bg-secondary); + color: var(--text-secondary); + border-radius: var(--radius-sm); +} + +.school-tag.type { + background: rgba(45, 125, 125, 0.1); + color: var(--accent-teal); +} + +.school-tag.faith { + background: rgba(138, 43, 226, 0.1); + color: #8a2be2; +} + +.school-address { + font-size: 0.85rem; + color: var(--text-muted); + margin-bottom: 0.5rem; +} + +.school-details { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1rem; + flex-grow: 1; +} + +.age-range { + font-size: 0.75rem; + color: var(--text-secondary); + padding: 0.2rem 0.5rem; + background: var(--bg-secondary); + border-radius: var(--radius-sm); +} + +.school-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0.5rem; + padding-top: 1rem; + border-top: 1px solid var(--border-color); + margin-top: auto; +} + +.stat { + text-align: center; +} + +.stat-value { + font-size: 1.1rem; + font-weight: 700; + color: var(--text-primary); + display: flex; + align-items: center; + justify-content: center; + gap: 0.25rem; +} + +.stat-value.positive { + color: var(--accent-teal); +} + +.stat-value.negative { + color: var(--accent-coral); +} + +/* Trend indicators */ +.trend-indicator { + font-size: 0.75rem; + cursor: help; +} + +.trend-up { + color: var(--accent-teal); +} + +.trend-down { + color: var(--accent-coral); +} + +.trend-stable { + color: var(--text-muted); + font-size: 0.6rem; +} + +.stat-label { + font-size: 0.65rem; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.03em; +} + +/* School Card Map */ +.school-map { + height: 150px; + margin-top: 1rem; + border-radius: var(--radius-md); + overflow: hidden; + cursor: pointer; + border: 1px solid var(--border-color); + transition: var(--transition); +} + +.school-map:hover { + border-color: var(--accent-coral); + box-shadow: var(--shadow-small); +} + +/* Fullscreen Map Modal */ +.map-modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.8); + z-index: 2000; + display: flex; + align-items: center; + justify-content: center; + padding: 1rem; + animation: fadeIn 0.2s ease; +} + +.map-modal { + background: var(--bg-card); + border-radius: var(--radius-lg); + width: 100%; + max-width: 900px; + max-height: 90vh; + display: flex; + flex-direction: column; + overflow: hidden; + box-shadow: var(--shadow-large); + animation: slideUp 0.3s ease; +} + +.map-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 1.5rem; + border-bottom: 1px solid var(--border-color); +} + +.map-modal-header h3 { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); + margin: 0; +} + +.map-modal-close { + background: none; + border: none; + font-size: 1.75rem; + color: var(--text-muted); + cursor: pointer; + padding: 0.25rem 0.5rem; + line-height: 1; + transition: var(--transition); +} + +.map-modal-close:hover { + color: var(--accent-coral); +} + +.map-modal-content { + height: 500px; + width: 100%; } @media (max-width: 768px) { - .main-content { - padding: 1.5rem 1rem; - } + .map-modal { + max-height: 80vh; + } - .grid-2, - .grid-3 { - grid-template-columns: 1fr; - } + .map-modal-content { + height: 400px; + } + + .results-container.map-view { + grid-template-columns: 1fr; + grid-template-rows: 350px auto; + height: auto; + } + + .results-container.map-view .results-map { + height: 350px; + } + + .results-container.map-view .schools-grid { + height: auto; + max-height: 400px; + overflow-y: auto; + } } -/* Typography */ -h1, h2, h3, h4, h5, h6 { - font-weight: 600; - line-height: 1.3; - color: var(--text-primary); +/* Section Titles */ +.section-title { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 2rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 0.5rem; } -h1 { - font-size: 2.25rem; - margin-bottom: 1rem; +.section-subtitle { + font-size: 1rem; + color: var(--text-secondary); + margin-bottom: 2rem; } -h2 { - font-size: 1.875rem; - margin-bottom: 0.875rem; +/* Compare View */ +.compare-header { + text-align: center; + padding: 2rem 0; } -h3 { - font-size: 1.5rem; - margin-bottom: 0.75rem; +.selected-schools { + display: flex; + flex-wrap: wrap; + gap: 1rem; + margin-bottom: 2rem; + min-height: 100px; + padding: 1.5rem; + background: var(--bg-secondary); + border-radius: var(--radius-lg); + justify-content: center; + align-items: center; } -h4 { - font-size: 1.25rem; - margin-bottom: 0.625rem; +.empty-selection { + text-align: center; + color: var(--text-muted); } -p { - margin-bottom: 1rem; +.empty-icon { + width: 48px; + height: 48px; + margin: 0 auto 0.5rem; + color: var(--text-muted); } +.selected-school-tag { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.6rem 1rem; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + font-size: 0.9rem; + color: var(--text-primary); + animation: slideIn 0.2s ease; +} + +@keyframes slideIn { + from { opacity: 0; transform: scale(0.9); } + to { opacity: 1; transform: scale(1); } +} + +.selected-school-tag .remove { + width: 18px; + height: 18px; + border: none; + background: var(--bg-secondary); + border-radius: 50%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: var(--transition); +} + +.selected-school-tag .remove:hover { + background: var(--accent-coral); + color: white; +} + +.compare-search-section { + max-width: 500px; + margin: 0 auto 2rem; + position: relative; +} + +.compare-results { + position: absolute; + top: 100%; + left: 0; + right: 0; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + box-shadow: var(--shadow-medium); + max-height: 300px; + overflow-y: auto; + z-index: 50; + display: none; +} + +.compare-results.active { + display: block; +} + +.compare-results-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.6rem 1rem; + background: var(--bg-secondary); + border-bottom: 1px solid var(--border-color); + font-size: 0.8rem; + color: var(--text-muted); + position: sticky; + top: 0; +} + +.compare-results-close { + width: 24px; + height: 24px; + border: none; + background: transparent; + border-radius: var(--radius-sm); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-muted); + transition: var(--transition); +} + +.compare-results-close:hover { + background: var(--accent-coral); + color: white; +} + +.compare-result-item { + padding: 0.75rem 1rem; + cursor: pointer; + border-bottom: 1px solid var(--border-color); + transition: var(--transition); +} + +.compare-result-item:last-child { + border-bottom: none; +} + +.compare-result-item:hover { + background: var(--bg-secondary); +} + +.compare-result-item .name { + font-weight: 500; + color: var(--text-primary); +} + +.compare-result-item .location { + font-size: 0.8rem; + color: var(--text-muted); +} + +/* Charts Section */ +.charts-section { + margin-top: 2rem; +} + +.metric-selector { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1.5rem; +} + +.metric-selector label { + font-weight: 500; + color: var(--text-secondary); +} + +.chart-container { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 2rem; + margin-bottom: 2rem; +} + +/* Data Table */ +.data-table-container { + overflow-x: auto; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); +} + +.data-table { + width: 100%; + border-collapse: collapse; +} + +.data-table th, +.data-table td { + padding: 1rem; + text-align: left; + border-bottom: 1px solid var(--border-color); +} + +.data-table th { + background: var(--bg-secondary); + font-weight: 600; + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--text-secondary); +} + +.data-table tr:last-child td { + border-bottom: none; +} + +.data-table tr:hover td { + background: rgba(224, 114, 86, 0.03); +} + +/* Rankings View */ +.rankings-header { + text-align: center; + padding: 2rem 0; +} + +.rankings-controls { + display: flex; + justify-content: center; + gap: 1rem; + margin-bottom: 2rem; +} + +.rankings-list { + max-width: 800px; + margin: 0 auto; +} + +.ranking-item { + display: flex; + align-items: center; + gap: 1.5rem; + padding: 1.25rem 1.5rem; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + margin-bottom: 0.75rem; + transition: var(--transition); + cursor: pointer; +} + +.ranking-item:hover { + border-color: var(--accent-coral); + box-shadow: var(--shadow-soft); +} + +.ranking-position { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + font-weight: 700; + font-size: 1rem; +} + +.ranking-position.top-3 { + background: linear-gradient(135deg, var(--accent-gold), #d4af37); + color: white; +} + +.ranking-position:not(.top-3) { + background: var(--bg-secondary); + color: var(--text-secondary); +} + +.ranking-info { + flex: 1; +} + +.ranking-name { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 0.25rem; +} + +.ranking-location { + font-size: 0.85rem; + color: var(--text-muted); +} + +.ranking-score { + text-align: right; +} + +.ranking-score-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--accent-teal); +} + +.ranking-score-label { + font-size: 0.7rem; + color: var(--text-muted); + text-transform: uppercase; +} + +/* Modal */ +.modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 2000; + display: none; + align-items: center; + justify-content: center; + padding: 2rem; +} + +.modal.active { + display: flex; +} + +.modal-backdrop { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(26, 22, 18, 0.6); + backdrop-filter: blur(4px); +} + +.modal-content { + position: relative; + background: var(--bg-card); + border-radius: var(--radius-xl); + max-width: 800px; + width: 100%; + max-height: 90vh; + overflow-y: auto; + box-shadow: var(--shadow-strong); + animation: modalIn 0.3s ease; +} + +@keyframes modalIn { + from { opacity: 0; transform: scale(0.95) translateY(20px); } + to { opacity: 1; transform: scale(1) translateY(0); } +} + +.modal-close { + position: absolute; + top: 1rem; + right: 1rem; + width: 40px; + height: 40px; + border: none; + background: var(--bg-secondary); + border-radius: 50%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: var(--transition); + z-index: 10; +} + +.modal-close:hover { + background: var(--accent-coral); + color: white; +} + +.modal-close svg { + width: 20px; + height: 20px; +} + +.modal-header { + position: relative; + padding: 2rem 2rem 1rem; + border-bottom: 1px solid var(--border-color); +} + +.modal-header h2 { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 1.75rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 0.5rem; + padding-right: 10rem; +} + +.modal-meta { + display: flex; + gap: 0.75rem; + flex-wrap: wrap; +} + +.modal-details { + margin-top: 0.75rem; + font-size: 0.875rem; + color: var(--text-secondary); +} + +.modal-details .modal-address { + margin-bottom: 0.25rem; +} + +.modal-compare-btn { + position: absolute; + top: 1rem; + right: 4rem; +} + +.modal-details .modal-age-range { + color: var(--text-muted); +} + +.modal-body { + padding: 2rem; +} + +.modal-chart-container { + margin-bottom: 2rem; +} + +.modal-stats { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.modal-stats-section { + padding: 1rem; + background: var(--bg-secondary); + border-radius: var(--radius-md); +} + +.modal-stats-section h4 { + margin: 0 0 0.75rem 0; + font-size: 0.85rem; + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.modal-stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); + gap: 0.75rem; +} + +.modal-stat { + text-align: center; + padding: 1rem; + background: var(--bg-secondary); + border-radius: var(--radius-md); +} + +.modal-stat-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-primary); +} + +.modal-stat-label { + font-size: 0.75rem; + color: var(--text-muted); + text-transform: uppercase; + margin-top: 0.25rem; +} + +.modal-map-container { + margin-top: 2rem; +} + +.modal-map-container h4 { + font-size: 1rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 0.75rem; +} + +.modal-map { + height: 200px; + border-radius: var(--radius-md); + overflow: hidden; + cursor: pointer; +} + + /* Buttons */ -button { - font-family: inherit; -} - .btn { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0.625rem 1.25rem; - font-size: 0.9375rem; - font-weight: 500; - border: none; - border-radius: var(--radius-md); - cursor: pointer; - transition: all var(--transition); - text-decoration: none; + padding: 0.75rem 1.5rem; + font-size: 0.9rem; + font-family: inherit; + font-weight: 600; + border: none; + border-radius: var(--radius-md); + cursor: pointer; + transition: var(--transition); } .btn-primary { - background: var(--primary); - color: white; + background: var(--accent-coral); + color: white; } .btn-primary:hover { - background: var(--primary-dark); + background: var(--accent-coral-dark); + transform: translateY(-1px); } -.btn-secondary { - background: white; - color: var(--text-primary); - border: 1px solid var(--border-medium); +/* Footer */ +.footer { + margin-top: 3rem; + border-top: 1px solid var(--border-color); + color: var(--text-muted); + font-size: 0.85rem; } -.btn-secondary:hover { - background: var(--bg-tertiary); +.footer-content { + max-width: 600px; + margin: 0 auto; + padding: 2rem; } -/* Form Elements */ -input, -select, -textarea { - font-family: inherit; - font-size: 1rem; +.footer-contact { + margin-bottom: 1.5rem; + text-align: center; } -input:focus, -select:focus, -textarea:focus { - outline: none; +.footer-source { + text-align: center; + padding-top: 1.5rem; + border-top: 1px solid var(--border-color); } -/* Loading Spinner */ -.spinner { - display: inline-block; - width: 1.5rem; - height: 1.5rem; - border: 3px solid rgba(59, 130, 246, 0.3); - border-radius: 50%; - border-top-color: var(--primary); - animation: spin 0.8s linear infinite; +.footer a { + color: var(--accent-teal); + text-decoration: none; +} + +.footer a:hover { + text-decoration: underline; +} + +/* Loading State */ +.loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 3rem; + color: var(--text-muted); +} + +.loading-spinner { + width: 40px; + height: 40px; + border: 3px solid var(--border-color); + border-top-color: var(--accent-coral); + border-radius: 50%; + animation: spin 0.8s linear infinite; + margin-bottom: 1rem; } @keyframes spin { - to { - transform: rotate(360deg); - } + to { transform: rotate(360deg); } } -/* Scrollbar Styles */ -::-webkit-scrollbar { - width: 10px; - height: 10px; +/* Empty State */ +.empty-state { + text-align: center; + padding: 4rem 2rem; + color: var(--text-muted); } -::-webkit-scrollbar-track { - background: var(--bg-tertiary); +.empty-state svg { + width: 64px; + height: 64px; + margin-bottom: 1rem; + opacity: 0.5; } -::-webkit-scrollbar-thumb { - background: var(--border-dark); - border-radius: 5px; +/* Skeleton Loading */ +.skeleton { + pointer-events: none; } -::-webkit-scrollbar-thumb:hover { - background: var(--secondary); +.school-card.skeleton { + background: var(--bg-card); + padding: 1.5rem; } -/* Print Styles */ -@media print { - .no-print { - display: none !important; - } -} \ No newline at end of file +.skeleton-line { + height: 1rem; + background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--border-color) 50%, var(--bg-secondary) 75%); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; + border-radius: var(--radius-sm); + margin-bottom: 0.75rem; +} + +.skeleton-line.short { + height: 0.75rem; +} + +.ranking-item.skeleton { + background: var(--bg-card); +} + +.skeleton-circle { + width: 40px; + height: 40px; + border-radius: 50%; + background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--border-color) 50%, var(--bg-secondary) 75%); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; +} + +.skeleton-content { + flex: 1; + padding: 0 1rem; +} + +.skeleton-score { + width: 60px; + height: 40px; + background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--border-color) 50%, var(--bg-secondary) 75%); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; + border-radius: var(--radius-sm); +} + +@keyframes shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + +/* Pagination */ +.pagination-info { + grid-column: 1 / -1; + display: flex; + justify-content: center; + align-items: center; + gap: 1rem; + padding: 2rem; + color: var(--text-muted); + font-size: 0.9rem; +} + +.btn-load-more { + padding: 0.6rem 1.5rem; + font-size: 0.9rem; + font-family: inherit; + font-weight: 500; + border: 2px solid var(--accent-coral); + border-radius: var(--radius-md); + background: transparent; + color: var(--accent-coral); + cursor: pointer; + transition: var(--transition); +} + +.btn-load-more:hover { + background: var(--accent-coral); + color: white; +} + +/* Responsive */ +@media (max-width: 768px) { + .header-content { + flex-direction: column; + gap: 1rem; + } + + .nav { + width: 100%; + justify-content: center; + } + + .main { + padding: 1rem; + } + + .hero-title { + font-size: 1.75rem; + } + + .filter-row { + flex-direction: column; + } + + .location-input-group { + flex-direction: column; + width: 100%; + } + + .postcode-input { + max-width: 100%; + width: 100%; + } + + .radius-select { + width: 100%; + } + + .location-btn, + .location-clear-btn { + width: 100%; + justify-content: center; + } + + .schools-grid { + grid-template-columns: 1fr; + } + + .modal-content { + margin: 1rem; + max-height: calc(100vh - 2rem); + } + + .modal-header { + display: flex; + flex-direction: column; + } + + .modal-header h2 { + padding-right: 0; + order: 1; + } + + .modal-meta { + order: 2; + } + + .modal-details { + order: 3; + } + + .modal-compare-btn { + position: static; + order: 4; + margin-top: 1rem; + width: 100%; + } + + .modal-body { + padding: 1rem; + } + + .modal-chart-container { + margin-bottom: 1.5rem; + padding: 0.5rem; + background: var(--bg-secondary); + border-radius: var(--radius-md); + } + + .modal-chart-container canvas { + max-height: 280px; + } + + .modal-stats-grid { + grid-template-columns: repeat(2, 1fr); + gap: 0.5rem; + } + + .modal-stat { + padding: 0.75rem 0.5rem; + } + + .modal-stat-value { + font-size: 1.25rem; + } + + .modal-stat-label { + font-size: 0.65rem; + } + + .rankings-controls { + flex-direction: column; + align-items: stretch; + } +} + +/* Extra small screens */ +@media (max-width: 480px) { + .modal-content { + margin: 0.5rem; + max-height: calc(100vh - 1rem); + } + + .modal-header { + padding: 1rem; + } + + .modal-header h2 { + font-size: 1.25rem; + } + + .modal-chart-container canvas { + max-height: 260px; + } + + .modal-stats-grid { + grid-template-columns: repeat(2, 1fr); + } + + .modal-stat-value { + font-size: 1.1rem; + } + + .modal-map { + height: 160px; + } +} + +/* ============================================================================= + TOOLTIP SYSTEM + ============================================================================= */ + +/* Info Icon Trigger */ +.info-trigger { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; + margin-left: 0.25rem; + background: none; + border: none; + cursor: help; + color: var(--text-muted); + opacity: 0.6; + transition: var(--transition); + vertical-align: middle; + border-radius: 50%; +} + +.info-trigger:hover, +.info-trigger:focus { + color: var(--accent-teal); + opacity: 1; +} + +.info-trigger:focus { + outline: none; + box-shadow: 0 0 0 2px var(--accent-teal); +} + +.info-trigger:focus:not(:focus-visible) { + box-shadow: none; +} + +.info-trigger:focus-visible { + box-shadow: 0 0 0 2px var(--accent-teal); +} + +/* Info Icon SVG */ +.info-icon { + width: 10px; + height: 10px; + flex-shrink: 0; +} + +.modal-stat-label .info-icon { + width: 14px; + height: 14px; +} + +/* Tooltip Container */ +.tooltip { + position: absolute; + z-index: 3000; + min-width: 200px; + max-width: 280px; + padding: 0.75rem 1rem; + background: var(--bg-accent); + color: var(--text-inverse); + border-radius: var(--radius-md); + box-shadow: var(--shadow-medium); + font-family: var(--font-dm-sans), 'DM Sans', sans-serif; + font-size: 0.8125rem; + line-height: 1.5; + text-transform: none; + letter-spacing: normal; + text-align: left; + opacity: 0; + visibility: hidden; + transition: opacity 150ms ease, visibility 150ms ease; + pointer-events: none; +} + +.tooltip.visible { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +/* Tooltip Arrow - Top Placement (arrow points down) */ +.tooltip[data-placement="top"]::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); + border: 8px solid transparent; + border-top-color: var(--bg-accent); +} + +/* Tooltip Arrow - Bottom Placement (arrow points up) */ +.tooltip[data-placement="bottom"]::after { + content: ''; + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + border: 8px solid transparent; + border-bottom-color: var(--bg-accent); +} + +/* Tooltip Title */ +.tooltip-title { + font-weight: 600; + margin-bottom: 0.25rem; + font-size: 0.875rem; +} + +/* Tooltip Note (for context like national average) */ +.tooltip-note { + margin-top: 0.5rem; + padding-top: 0.5rem; + border-top: 1px solid rgba(250, 247, 242, 0.2); + font-size: 0.75rem; + opacity: 0.8; +} + +/* Warning Trigger Button */ +.warning-trigger { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; + margin-left: 0.5rem; + background: none; + border: none; + cursor: help; + color: var(--accent-coral); + opacity: 0.8; + transition: var(--transition); + vertical-align: middle; + border-radius: 4px; +} + +.warning-trigger:hover, +.warning-trigger:focus { + opacity: 1; +} + +.warning-trigger:focus { + outline: none; + box-shadow: 0 0 0 2px var(--accent-coral); +} + +.warning-trigger:focus:not(:focus-visible) { + box-shadow: none; +} + +.warning-trigger:focus-visible { + box-shadow: 0 0 0 2px var(--accent-coral); +} + +/* Warning Icon SVG */ +.warning-icon { + width: 14px; + height: 14px; + flex-shrink: 0; +} + +/* Warning Tooltip Styling */ +.tooltip.tooltip-warning { + background: #8b4513; + border-left: 3px solid var(--accent-coral); +} + +.tooltip.tooltip-warning[data-placement="top"]::after { + border-top-color: #8b4513; +} + +.tooltip.tooltip-warning[data-placement="bottom"]::after { + border-bottom-color: #8b4513; +} + +/* Label wrapper for inline icon */ +.stat-label-with-info { + display: inline-flex; + align-items: center; + justify-content: center; +} diff --git a/nextjs-app/app/layout.tsx b/nextjs-app/app/layout.tsx index 0a2077d..13109ec 100644 --- a/nextjs-app/app/layout.tsx +++ b/nextjs-app/app/layout.tsx @@ -1,9 +1,24 @@ import type { Metadata } from 'next'; +import { DM_Sans, Playfair_Display } from 'next/font/google'; import { Navigation } from '@/components/Navigation'; import { Footer } from '@/components/Footer'; import { ComparisonProvider } from '@/context/ComparisonProvider'; import './globals.css'; +const dmSans = DM_Sans({ + subsets: ['latin'], + weight: ['400', '500', '600', '700'], + variable: '--font-dm-sans', + display: 'swap', +}); + +const playfairDisplay = Playfair_Display({ + subsets: ['latin'], + weight: ['600', '700'], + variable: '--font-playfair', + display: 'swap', +}); + export const metadata: Metadata = { title: { default: 'SchoolCompare | Compare Primary School Performance', @@ -34,16 +49,14 @@ export default function RootLayout({ }>) { return ( - + +
-
-
- -
- {children} -
-
-
+ +
+ {children} +
+