PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m14s
PR Checks / Backend Smoke (pull_request) Successful in 9s
PR Checks / Build Backend (no push) (pull_request) Successful in 35s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m18s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m15s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 22s
On phones the results toolbar's filters were a sideways-scrolling row led by "More filters", so phase showed only in part and school type not at all, and the panel "More filters" opened held neither of them. Phones now get a single Filters button beside the folded search summary, counting every applied filter. It opens a bottom sheet with every filter: distance as five segments, then phase, school type, local authority and the secondary-only filters. Changes apply at once, as on desktop, so the footer's "Show N schools" only closes the sheet. Applied filters show as removable chips on a second line, which appears only when something is applied. Desktop and tablet are unchanged. Modal gains dialog semantics, a pinned footer and focus handling, and moves above the pinned toolbar, the floating List/Map button and the comparison toast, which its old z-index sat beneath. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
165 lines
3.0 KiB
CSS
165 lines
3.0 KiB
CSS
.overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(var(--shadow-rgb), 0.6);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
/* Above the pinned results toolbar (1001), the floating List/Map button
|
|
(1002) and the comparison toast (2000): a modal covers the page. */
|
|
z-index: 2100;
|
|
padding: 1rem;
|
|
animation: fadeIn 0.2s ease;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.modal {
|
|
background: var(--bg-card);
|
|
border-radius: 16px;
|
|
box-shadow: 0 20px 40px rgba(var(--shadow-rgb), 0.2);
|
|
max-height: 90vh;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
animation: slideIn 0.3s ease;
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
.modal:focus {
|
|
outline: none;
|
|
}
|
|
|
|
@keyframes slideIn {
|
|
from {
|
|
transform: translateY(-20px);
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.modal.small {
|
|
width: 100%;
|
|
max-width: 400px;
|
|
}
|
|
|
|
.modal.medium {
|
|
width: 100%;
|
|
max-width: 600px;
|
|
}
|
|
|
|
.modal.large {
|
|
width: 100%;
|
|
max-width: 900px;
|
|
}
|
|
|
|
.header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 1.5rem;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.title {
|
|
margin: 0;
|
|
font-size: 1.25rem;
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
font-family: var(--font-display);
|
|
}
|
|
|
|
.closeButton {
|
|
padding: 0.5rem;
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
border-radius: 8px;
|
|
transition: all 0.2s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.closeButton:hover {
|
|
background: var(--bg-secondary);
|
|
color: var(--brand);
|
|
}
|
|
|
|
.content {
|
|
overflow-y: auto;
|
|
flex: 1;
|
|
}
|
|
|
|
/* Clears the iPhone home indicator when the modal is a bottom sheet. */
|
|
.footer {
|
|
flex-shrink: 0;
|
|
padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
|
|
border-top: 1px solid var(--border);
|
|
background: var(--bg-card);
|
|
}
|
|
|
|
/* Scrollbar styles */
|
|
.content::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
.content::-webkit-scrollbar-track {
|
|
background: var(--bg-secondary);
|
|
}
|
|
|
|
.content::-webkit-scrollbar-thumb {
|
|
background: var(--border);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.content::-webkit-scrollbar-thumb:hover {
|
|
background: var(--text-muted);
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.overlay {
|
|
padding: 0;
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.modal {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
/* Bottom sheet sized against the overlay (which tracks the visual
|
|
viewport), NOT vh: when the keyboard is open the overlay is short, so
|
|
max-height:100% keeps the whole sheet — input and results — above the
|
|
keyboard. min-height gives a comfortable default without a tiny stub,
|
|
but is capped at 100% so it never exceeds the visible area. */
|
|
min-height: min(55vh, 100%);
|
|
max-height: 100%;
|
|
border-bottom-left-radius: 0;
|
|
border-bottom-right-radius: 0;
|
|
animation: slideUp 0.3s ease;
|
|
}
|
|
|
|
@keyframes slideUp {
|
|
from {
|
|
transform: translateY(100%);
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.header {
|
|
padding: 1rem;
|
|
}
|
|
}
|