/* One With Water — brand stylesheet
   Colours and fonts taken from the school's existing brand system
   (assets/css/style.css in their design project) so the new site matches
   what's already established. */

:root {
  --ocean: #1a5276;
  --reef: #2e86c1;
  --aqua: #5dade2;
  --foam: #d6eaf8;
  --sand: #ebf5fb;
  --bg: #f4f9fd;
  --text: #154360;
  --mid: #5d9ec4;
  --gold: #c8914a;
  --danger: #c0392b;
  --warn: #d68910;
  --ok: #1e8449;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  color: var(--text);
  background: var(--bg);
  line-height: 1.6;
}

h1, h2, h3, h4 {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-weight: 500;
  color: var(--ocean);
  line-height: 1.2;
}

h1 { font-size: 2.8rem; }
h2 { font-size: 2.1rem; }
h3 { font-size: 1.5rem; }

a { color: var(--reef); }

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* Wider than the standard .container — used only for the header banner
   rows, so the nav links and the Book/Enquire + Parent Login + Staff
   Login button group have enough room to sit on one line at typical
   desktop widths, without widening the page's actual content sections. */
.container-header {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* ---- Header / nav ---- */
header.site-header {
  background: var(--ocean);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 50;
}

/* Top row: logo + brand name, left-aligned so the logo sits directly above
   the "Home" nav item below it, sized generously so the header reads as a
   proper banner rather than a thin utility bar. Padding is kept tight
   (rather than the full logo height's worth of breathing room) so the
   banner doesn't run taller than it needs to. */
.header-brand-row {
  display: flex;
  justify-content: flex-start;
  padding: 0.7rem 1.25rem 0.4rem;
}

.brand-lockup {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  color: #fff;
  text-decoration: none;
}

.brand-logo-img {
  height: 92px;
  width: auto;
  display: block;
}

/* The full corporate logo lockup (icon + "ONE WITH WATER" wordmark,
   replacing the old round icon + separate <span> site name, at Ant's
   request, 2026-08-17) is a much wider image than the round icon it
   replaced — sized by height, same as the round icon was, so it scales
   down cleanly on narrow screens via the max-width media query below
   rather than needing its own separate breakpoint logic. */
.brand-logo-img-full {
  height: 68px;
}

/* Second row: page links on the left (lined up under the logo), and the
   Book/Enquire + Parent Login + Staff Login buttons grouped together on
   the right — kept as their own flex group so they stay clustered next to
   each other rather than mixed in with the page links. Padding is tighter
   than before, to match the brand row above. */
.header-nav-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  padding: 0.3rem 1.25rem 0.75rem;
}

nav.main-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 1.1rem;
  align-items: center;
}

nav.main-nav a {
  color: #eaf4fb;
  text-decoration: none;
  font-size: 0.95rem;
}

nav.main-nav a:hover { color: #fff; text-decoration: underline; }

.header-auth-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  /* Guarantees a bit of breathing room after "Contact", on top of
     whatever justify-content: space-between on the row above already
     adds — without this, the two could end up touching right at the
     point where the row is about to wrap onto two lines. */
  margin-left: 1rem;
}

/* Book/Enquire, Parent Login and Staff Login specifically — a bit
   shorter and narrower than the site's standard .btn size (used for
   bigger calls-to-action elsewhere), since these three are menu items
   that happen to be styled as buttons, not the main event on the page.
   Sized down further still (Ant's request, 2026-08-17) on every screen
   size, and shrunk again specifically below 640px so all three fit on
   one line on a phone instead of wrapping onto two. */
.header-auth-row .btn {
  padding: 0.4rem 0.85rem;
  font-size: 0.82rem;
}

@media (max-width: 640px) {
  .brand-logo-img { height: 48px; }
  .brand-logo-img-full { height: 40px; }
  nav.main-nav { width: 100%; }
  .header-auth-row {
    width: 100%;
    margin-left: 0;
    justify-content: space-between;
    gap: 0.35rem;
  }
  .header-auth-row .btn {
    padding: 0.32rem 0.55rem;
    font-size: 0.72rem;
  }
}

/* Compact single-row header for the staff-only scheduling tools (kept
   small and utilitarian, unlike the public site's big banner). */
.staff-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.7rem 1.25rem;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.staff-brand-lockup { display: flex; align-items: center; gap: 0.6rem; color: #fff; text-decoration: none; }
.staff-brand-logo-img { height: 34px; width: auto; }
.staff-brand-name {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.3rem;
  font-weight: 600;
  color: #fff;
}
.staff-brand-name small {
  display: block;
  font-family: 'DM Sans', sans-serif;
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  font-weight: 400;
  color: var(--foam);
  text-transform: uppercase;
}

.btn {
  display: inline-block;
  padding: 0.6rem 1.3rem;
  border-radius: 999px;
  text-decoration: none;
  font-weight: 500;
  font-size: 0.95rem;
  border: 2px solid transparent;
  cursor: pointer;
}

.btn-primary { background: var(--gold); color: #fff; }
.btn-primary:hover { background: #b57e3c; }

.btn-outline { border-color: #fff; color: #fff; background: transparent; }
.btn-outline:hover { background: rgba(255,255,255,0.12); }

.btn-secondary { background: var(--reef); color: #fff; }
.btn-secondary:hover { background: var(--ocean); }

/* ---- Hero ---- */
.hero {
  background: linear-gradient(135deg, var(--ocean), var(--reef));
  color: #fff;
  padding: 2.5rem 0 2.25rem;
}

.hero .eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.8rem;
  color: var(--foam);
}

.hero h1 { color: #fff; margin: 0.5rem 0 1rem; }
.hero p.lead { font-size: 1.15rem; max-width: 640px; color: #eaf4fb; }
.hero .cta-row { margin-top: 1.75rem; display: flex; gap: 1rem; flex-wrap: wrap; }

/* Small "Version X · Last updated: ..." line shown under the main lead
   paragraph on each legal document page (terms.html, indemnity.html,
   privacy.html) — see LegalDocumentVersions in core/models.py for how the
   version number and date are tracked. */
.hero .version-note { font-size: 0.85rem; color: #eaf4fb; opacity: 0.75; margin-top: 0.35rem; }

/* ---- Sections ---- */
section { padding: 3rem 0; }
section.alt { background: var(--sand); }

.eyebrow-dark { color: var(--reef); text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.8rem; font-weight: 600; }

.grid {
  display: grid;
  gap: 1.5rem;
}

.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

.card {
  background: #fff;
  border-radius: 14px;
  padding: 1.6rem;
  box-shadow: 0 2px 14px rgba(26, 82, 118, 0.08);
  border: 1px solid var(--foam);
}

.card.featured { border-color: var(--gold); border-width: 2px; position: relative; }

/* ---- Gallery ---- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}
.gallery-tile {
  background: #fff;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 2px 14px rgba(26, 82, 118, 0.08);
  border: 1px solid var(--foam);
}
.gallery-tile img,
.gallery-tile video {
  width: 100%;
  height: 260px;
  object-fit: cover;
  display: block;
  background: #000;
}
.gallery-caption {
  padding: 0.7rem 1rem;
  font-size: 0.9rem;
  color: var(--text);
}

.badge {
  display: inline-block;
  background: var(--gold);
  color: #fff;
  font-size: 0.7rem;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.5rem;
}

.price {
  font-family: 'Cormorant Garamond', serif;
  font-size: 2.1rem;
  color: var(--ocean);
  font-weight: 600;
}

.price small { font-size: 1rem; font-weight: 400; color: var(--mid); }

.coach-card { display: flex; gap: 1.2rem; align-items: flex-start; }
.coach-photo-placeholder {
  width: 90px; height: 90px; border-radius: 50%;
  background: var(--foam); color: var(--ocean);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Cormorant Garamond', serif; font-size: 1.8rem; flex-shrink: 0;
}

/* ---- Calendar screens (staff-only) ---- */
/* Print-only masthead — see the @media print rules further down for
   how this actually looks on paper; on screen it's simply not shown. */
.print-header { display: none; }

.cal-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}
.cal-nav { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.cal-nav .btn { padding: 0.5rem 1rem; font-size: 0.85rem; }

/* ---- Week calendar: time grid (rewritten 2026-08-27, at Ant's request)
   ----
   Previously a CSS grid of 7 independent day columns, each just a
   stacked list of that day's lessons — nothing tied one day's 11:00
   lesson to the same row as another day's 11:00 lesson. Replaced with a
   plain HTML <table>: one row per half-hour slot (see
   scheduling/views.py's calendar_week()), so every day column shares the
   same vertical timeline. A <table> row's height is automatically the
   tallest cell in that row, which is what keeps every column aligned
   even when one day's lesson card is taller than its neighbours that
   same hour — no manual height/position math needed, unlike an
   absolutely-positioned "real" calendar grid would require. */
.week-time-grid-scroll {
  /* 7 day columns plus a time column don't comfortably fit a narrow
     screen — scroll horizontally there rather than squeezing text
     illegibly small (see the max-width:640px rule further down, which
     sets a sensible min-width on the table itself to trigger this).

     overflow-y: auto + a max-height (added 2026-08-27, at Ant's request
     for frozen day headers) turns this box into its own internal
     scroll region for a busy week, rather than relying on the whole
     page scrolling — that's what lets the day-header row below stick
     to the TOP OF THIS BOX via plain "position: sticky; top: 0" without
     needing to know the site header's own (responsive, variable)
     height in JS. max() keeps a sensible floor on very short screens
     rather than the box collapsing to almost nothing. */
  overflow-x: auto;
  overflow-y: auto;
  max-height: max(320px, calc(100vh - 260px));
  border: 1px solid var(--foam);
  border-radius: 12px;
  background: #fff;
}
/* Freezes the Mon-Sun day-header row in place while the time slots below
   it scroll — each header cell already has a solid background colour
   (ocean blue / gold for today / grey for a holiday), so nothing shows
   through underneath it, and the small shadow gives a visual "it's
   floating above the content now" cue once something has scrolled
   beneath it. */
.week-time-grid thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
.week-time-grid {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.week-time-col {
  width: 64px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ocean);
  background: var(--sand);
  text-align: right;
  padding: 0.3rem 0.5rem;
  vertical-align: top;
  border-right: 1px solid var(--foam);
  white-space: nowrap;
}
.week-day-header-cell {
  background: var(--ocean);
  color: #fff;
  padding: 0.5rem 0.4rem;
  font-weight: 500;
  text-align: center;
  border-left: 1px solid rgba(255, 255, 255, 0.25);
}
.week-day-header-cell:first-of-type { border-left: none; }
.week-day-header-cell .week-day-label { display: block; font-weight: 700; color: #fff; }
.week-day-header-cell .week-day-date { display: block; font-size: 0.75rem; color: rgba(255, 255, 255, 0.8); }
.week-day-header-cell.week-day-today { background: var(--gold); }
.week-day-header-cell.week-day-today .week-day-date { color: rgba(0, 0, 0, 0.6); }
.week-day-header-cell.week-day-holiday { background: var(--mid); }
.cal-holiday-note-sm { font-size: 0.65rem; margin-top: 0.15rem; color: #fff; }
.cal-holiday-note-sm-open { color: #fff6e9; }

/* Every row gets a thin separator; a row starting exactly on the hour
   (e.g. 09:00, 10:00, 11:00 — see is_hour in calendar_week()) gets a
   visibly stronger one, per Ant's explicit request, so the hour marks
   read clearly at a glance even in a busy week. */
.week-time-row td { border-top: 1px solid var(--foam); }
.week-time-row-hour td { border-top: 2px solid var(--ocean); }
.week-time-cell {
  vertical-align: top;
  padding: 0.15rem;
  border-left: 1px solid var(--foam);
  min-height: 2.4rem;
}
.week-time-cell:first-of-type { border-left: none; }

/* The Week grid's own lesson cards are deliberately more compact than
   the Day Calendar's (narrower columns, one per weekday) — same
   approach the old per-day-column layout used, just renamed from
   ".week-day .lesson-card" now that ".week-day" no longer exists. */
.week-time-cell .lesson-card { font-size: 0.72rem; padding: 0.25rem 0.35rem; margin-bottom: 0.2rem; }
.week-time-cell .lesson-programme { font-size: 0.85rem; }
.week-time-cell .lesson-students { font-size: 0.7rem; }
.week-time-cell .lesson-meta { font-size: 0.65rem; }
.week-time-cell .lesson-capacity { font-size: 0.65rem; }

/* ---- Week Calendar drag-and-drop (added 2026-08-28, at Ant's request)
   ----
   A draggable card gets a grab cursor and a subtle lift on hover, purely
   as a visual hint that it can be picked up at all — otherwise nothing
   on a plain lesson card looks interactive. While actually being
   dragged, it's faded rather than hidden, so the staff member dragging
   it can still see where it came from. A drop target (any grid cell)
   highlights only while something is being dragged directly over it,
   never just on ordinary hover, so browsing the calendar normally still
   feels exactly like it did before this feature existed. */
.dnd-draggable { cursor: grab; transition: box-shadow 0.12s ease, transform 0.12s ease; }
.dnd-draggable:hover { box-shadow: 0 2px 6px rgba(21, 67, 96, 0.25); }
.dnd-draggable.dnd-dragging { opacity: 0.4; cursor: grabbing; }
.dnd-drop-target { transition: background-color 0.1s ease; }
.dnd-drop-target.dnd-drop-hover {
  background-color: var(--foam);
  outline: 2px dashed var(--reef);
  outline-offset: -2px;
}
@media print {
  .dnd-draggable { cursor: default; }
}

/* Confirm dialog shown on drop, before anything actually changes — same
   overlay/box visual language as the Contact page's map popup
   (.map-modal-* above) but under its own class names, since this one
   has form fields (and a footer with two buttons) the map popup never
   needed. */
.dnd-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(21, 67, 96, 0.55);
}
.dnd-modal-overlay[hidden] { display: none; }
.dnd-modal {
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 12px 40px rgba(21, 67, 96, 0.35);
  width: min(440px, 100%);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.dnd-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.2rem;
  background: var(--ocean);
  color: #fff;
  font-weight: 600;
}
.dnd-modal-close {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  color: #fff;
  width: 1.8rem;
  height: 1.8rem;
  line-height: 1;
  font-size: 0.9rem;
  cursor: pointer;
}
.dnd-modal-close:hover { background: rgba(255, 255, 255, 0.15); }
.dnd-modal-body { padding: 1rem 1.2rem; overflow-y: auto; }
.dnd-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  padding: 0.8rem 1.2rem;
  border-top: 1px solid var(--foam);
}
@media (max-width: 480px) {
  .dnd-modal-overlay { padding: 0; }
  .dnd-modal { border-radius: 0; width: 100%; height: 100%; max-height: 100vh; }
}

/* Line-height/spacing tightened 2026-08-27, at Ant's request, so a
   lesson card takes up noticeably less vertical room on the Day/Week
   calendars (a busier day now shows more of the grid on screen at
   once without scrolling as much) — font sizes are unchanged, only the
   padding/margins/line-height around the text. */
.lesson-card {
  border-radius: 8px;
  padding: 0.35rem 0.5rem;
  margin-bottom: 0.3rem;
  font-size: 0.82rem;
  line-height: 1.2;
  border-left: 4px solid var(--reef);
  background: var(--sand);
}
.lesson-card.lesson-private { border-left-color: var(--gold); }
.lesson-card.lesson-group { border-left-color: var(--reef); }
.lesson-card.lesson-full { background: #fdecea; }
.lesson-time { font-weight: 700; color: var(--ocean); }
.lesson-programme { font-family: 'Cormorant Garamond', serif; font-size: 1.05rem; color: var(--text); line-height: 1.15; }
.lesson-students { font-weight: 600; font-size: 0.8rem; color: var(--ocean); margin-top: 0.05rem; line-height: 1.2; }
.lesson-students-empty { font-weight: 400; font-style: italic; color: var(--mid); }
.lesson-meta { color: var(--mid); font-size: 0.75rem; margin: 0.08rem 0; line-height: 1.2; }
.lesson-capacity { font-size: 0.75rem; display: flex; align-items: center; gap: 0.4rem; }

/* A student's name inside a Day/Week calendar lesson card (added
   2026-08-19) — clicking it opens "Move to another class" for that
   specific student's enrolment. The dotted underline is deliberately
   subtler than a normal link so a card full of names doesn't look like a
   wall of blue links; the .lesson-card's own click-through to the raw
   admin was removed at the same time (see calendar_day.html/
   calendar_week.html) so this can't end up nested inside another link. */
.lesson-student-link {
  color: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  cursor: pointer;
}
.lesson-student-link:hover {
  color: var(--ocean);
  text-decoration-style: solid;
}

/* Small "Manage this class" link at the bottom of a lesson card — the
   old way in (the whole card used to be one big link to the admin) still
   needs a way in for anything that isn't a per-student move: changing
   the instructor, capacity, time, etc. */
.lesson-admin-link {
  display: inline-block;
  margin-top: 0.2rem;
  font-size: 0.72rem;
  color: var(--mid);
  text-decoration: none;
}
.lesson-admin-link:hover {
  color: var(--ocean);
  text-decoration: underline;
}

.cal-empty-note, .cal-holiday-note { color: var(--mid); font-size: 0.8rem; font-style: italic; }
.cal-holiday-note { color: var(--danger); font-style: normal; font-weight: 600; }

/* Parent portal — Upcoming Lessons / Lesson History & Attendance lists
   (My Account page and the "View Full History" page), added 2026-07-28. */
.portal-lesson-list { list-style: none; margin: 0; padding: 0; font-size: 0.85rem; }
.portal-lesson-list li { padding: 0.3rem 0; border-bottom: 1px solid var(--foam); }
.portal-lesson-list li:last-child { border-bottom: none; }

.portal-status-pill {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  background: var(--sand);
  color: var(--ocean);
}
.portal-status-attended { background: #e6f4ea; color: #1e7e34; }
.portal-status-absent { background: #fdecea; color: var(--danger); }
.portal-status-excused { background: #fdf3e3; color: var(--gold); }
.portal-status-trial { background: var(--sand); color: var(--reef); }
.portal-status-makeup { background: var(--sand); color: var(--reef); }
.portal-status-none { background: #f1f1f1; color: var(--mid); font-weight: 400; font-style: italic; }
/* "Catch-Up Lessons Due" block (added 2026-08-27) — reuses the same
   attended-green for a credit with plenty of time left, and the same
   excused-gold for one nearing its expiry, rather than inventing new
   colours for this one block. */
.portal-status-available { background: #e6f4ea; color: #1e7e34; }
.portal-status-expiring { background: #fdf3e3; color: var(--gold); }

.oww-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.oww-table th, .oww-table td { text-align: left; padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--foam); }
.oww-table th { color: var(--ocean); font-weight: 700; }

.month-grid {
  width: 100%;
  border-collapse: collapse;
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 14px rgba(26, 82, 118, 0.08);
}
.month-grid th {
  background: var(--ocean);
  color: #fff;
  padding: 0.6rem;
  font-weight: 500;
  font-size: 0.85rem;
}
.month-grid td.month-cell {
  border: 1px solid var(--foam);
  vertical-align: top;
  height: 90px;
  width: 14.28%;
}
.month-grid td.month-cell a { display: block; height: 100%; padding: 0.5rem; text-decoration: none; color: inherit; }
.month-cell-outside { background: #fafcfe; color: var(--mid); }
.month-cell-today { background: #fff6e9; }
.month-cell-holiday { background: var(--sand); }
.month-cell-date { font-weight: 700; color: var(--ocean); margin-bottom: 0.3rem; }
.month-cell-note { font-size: 0.72rem; color: var(--reef); }

@media (max-width: 900px) {
  /* Below 900px, 7 day columns + a time column get too narrow to read
     comfortably — set a firm min-width on the table so the surrounding
     .week-time-grid-scroll wrapper scrolls horizontally instead of
     squeezing every column illegibly thin. */
  .week-time-grid { min-width: 760px; }
}
@media (max-width: 640px) {
  .month-grid { font-size: 0.75rem; }
  .month-grid td.month-cell { height: 60px; }
}

/* ---- Day calendar (08:00-18:00 half-hour slots) ---- */
.day-slot-list {
  border: 1px solid var(--foam);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
}
.day-slot {
  display: flex;
  border-bottom: 1px solid var(--foam);
  min-height: 56px;
}
/* A strong line at each whole hour (2026-08-27, at Ant's request), to
   match the same treatment on the Week Calendar's grid — is_hour is set
   in scheduling/views.py's calendar_day() for any slot starting exactly
   on the hour (09:00, 10:00, 11:00, ...). border-top rather than a
   heavier border-bottom on the PRECEDING slot, so it reads as "the line
   marking this hour starts here" consistently with the Week grid's own
   .week-time-row-hour rule. */
.day-slot-hour { border-top: 2px solid var(--ocean); }
.day-slot:last-child { border-bottom: none; }
.day-slot-time {
  flex: 0 0 110px;
  padding: 0.6rem 0.8rem;
  font-weight: 600;
  color: var(--ocean);
  font-size: 0.85rem;
  background: var(--sand);
  border-right: 1px solid var(--foam);
}
.day-slot-body { flex: 1; padding: 0.5rem 0.8rem; display: flex; flex-direction: column; gap: 0.4rem; justify-content: center; }
.day-slot-open .day-slot-body { padding: 0; }
.day-slot-add {
  display: block;
  padding: 0.6rem 0.8rem;
  color: var(--mid);
  text-decoration: none;
  font-size: 0.85rem;
}
.day-slot-add:hover { background: var(--sand); color: var(--reef); font-weight: 600; }
.day-lesson-link { display: block; text-decoration: none; color: inherit; }
.day-lesson-link:hover { filter: brightness(0.97); }

.holiday-toggle-banner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1rem 1.25rem;
  border-radius: 10px;
  margin-bottom: 1.5rem;
  color: #fff;
}
.holiday-toggle-closed { background: var(--danger); }
.holiday-toggle-open { background: var(--gold); }
.holiday-toggle-buttons { display: flex; gap: 0.6rem; }
.holiday-toggle-buttons form { margin: 0; }
.holiday-toggle-buttons button { cursor: pointer; }
.holiday-toggle-buttons button[disabled] {
  background: #fff;
  font-weight: 700;
  cursor: default;
  opacity: 1;
}
.holiday-toggle-closed button[disabled] { color: var(--danger); }
.holiday-toggle-open button[disabled] { color: var(--gold); }
.holiday-toggle-btn-outline { border-color: #fff; color: #fff; background: transparent; }
.holiday-toggle-btn-outline:hover { background: rgba(255,255,255,0.15); }

.holiday-add-banner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.85rem 1.25rem;
  border-radius: 10px;
  margin-bottom: 1.5rem;
  background: var(--sand);
  color: var(--text);
  font-size: 0.9rem;
}
.holiday-add-form { display: flex; gap: 0.6rem; flex-wrap: wrap; margin: 0; }
.holiday-add-input {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--foam);
  border-radius: 8px;
  font-size: 0.85rem;
  min-width: 220px;
}

.student-picker {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--foam);
  border-radius: 8px;
  padding: 0.5rem;
}
.student-option {
  display: block;
  padding: 0.35rem 0.4rem;
  font-size: 0.9rem;
  border-radius: 6px;
  cursor: pointer;
}
.student-option:hover { background: var(--sand); }
.student-option input { margin-right: 0.5rem; }
.student-family { color: var(--mid); font-size: 0.8rem; }

/* ---- Footer ---- */
footer.site-footer {
  background: var(--ocean);
  color: var(--foam);
  padding: 2.5rem 0 1.5rem;
  margin-top: 2rem;
  font-size: 0.9rem;
}

footer.site-footer a { color: #fff; }
footer.site-footer .footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem; }
footer.site-footer .fine-print { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid rgba(255,255,255,0.15); font-size: 0.8rem; color: var(--aqua); display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 0.4rem 1.5rem; }
footer.site-footer .fine-print-credit { text-align: right; white-space: nowrap; }

/* ---- Forms ---- */
/* Widened from the original 720px (Ant's request, 2026-08-23
   registration-form redesign). The 6-section layout below pairs fields
   two at a time per line (.grid-2 — minmax(300px, 1fr), see above) rather
   than three (Ant asked, later the same day, to drop the form back down
   from 3 columns to 2 — a lone third field on some lines, e.g. Preferred
   Venue, now sits on its own full-width row instead). 960px still gives
   each of the two fields on a paired row comfortable width without
   feeling cramped; below this width .grid-2's auto-fit still stacks
   fields into a single column automatically — no extra CSS needed for
   responsive stacking on a phone. Only affects the booking/registration
   form (grep confirms "oww-form" is used nowhere else), so this doesn't
   change any other page's layout. */
form.oww-form { max-width: 960px; }
.form-row { margin-bottom: 1.1rem; }
.form-row label { display: block; font-weight: 500; margin-bottom: 0.35rem; }
.form-row input[type=text],
.form-row input[type=email],
.form-row input[type=tel],
.form-row input[type=date],
.form-row select,
.form-row textarea {
  width: 100%;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--mid);
  border-radius: 8px;
  font-family: inherit;
  font-size: 1rem;
  background: #fff;
  color: var(--text);
}
.form-row textarea { min-height: 100px; }
.form-row textarea.textarea-compact { min-height: 50px; }
.form-row .helptext { font-size: 0.8rem; color: var(--mid); margin-top: 0.3rem; }
.form-row .errorlist { color: var(--danger); font-size: 0.85rem; margin: 0.3rem 0 0; padding: 0; list-style: none; }
.checkbox-row { display: flex; align-items: flex-start; gap: 0.6rem; }
.checkbox-row input { margin-top: 0.3rem; }
fieldset { border: 1px solid var(--foam); border-radius: 10px; padding: 1.2rem 1.4rem; margin-bottom: 1.5rem; }
legend { font-family: 'Cormorant Garamond', serif; color: var(--ocean); font-size: 1.3rem; padding: 0 0.4rem; }

/* Tighter vertical rhythm on the registration form specifically (Ant's
   request, 2026-08-23 — the 6-section layout above reads as too "deep"/
   tall). These rules only apply inside form.oww-form (they're more
   specific than the plain ".form-row"/"fieldset"/".grid" rules above, so
   they win there without changing spacing anywhere else those classes are
   used — amend_class_session.html, add_lesson_slot.html, the marketing
   pages' card grids, etc. all keep their original, roomier spacing).
   Each value is shrunk, not removed, so fields still read as clearly
   separated — just closer together than before. */
form.oww-form .form-row { margin-bottom: 0.6rem; }
form.oww-form .grid { gap: 0.9rem; }
form.oww-form fieldset { padding: 0.8rem 1.4rem; margin-bottom: 0.9rem; }

/* ---- Preferred-days dropdown checklist (booking form) ---- */
.dropdown-select { position: relative; }
.dropdown-select-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--mid);
  border-radius: 8px;
  background: #fff;
  font-family: inherit;
  font-size: 1rem;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.dropdown-select-toggle:hover { border-color: var(--ocean); }
.dropdown-select-open .dropdown-select-toggle { border-color: var(--ocean); }
.dropdown-select-caret { color: var(--mid); }
.dropdown-select-panel {
  display: none;
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid var(--mid);
  border-radius: 8px;
  box-shadow: 0 8px 20px rgba(0,0,0,0.14);
  padding: 0.6rem 0.5rem;
  max-height: 340px;
  overflow-y: auto;
}
.dropdown-select-open .dropdown-select-panel { display: block; }
.dropdown-select-panel label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.5rem;
  border-radius: 6px;
  font-weight: 400;
  margin-bottom: 0;
  cursor: pointer;
}
.dropdown-select-panel label:hover { background: var(--sand); }
.dropdown-select-panel input[type=checkbox] { width: auto; margin: 0; }

.alert { padding: 1rem 1.2rem; border-radius: 10px; margin-bottom: 1.5rem; }
.alert-success { background: #eafaf1; border: 1px solid var(--ok); color: #145a32; }
.alert-info { background: var(--sand); border: 1px solid var(--aqua); }

/* Bold banner shown at the very top of a public-facing registration form
   (Book/Enquire and the portal's Register Another Child) when it's
   re-rendered after a failed submission (Ant's request, 2026-08-19). The
   red text under each individual field (.form-row .errorlist below) is
   easy to miss, especially on a long form — once the page reloads back
   at the top after pressing submit, a visitor can easily not realise
   anything went wrong at all. This gives one unmissable "something needs
   fixing" signal right where they're already looking, with a heavier
   border and bigger, bolder text than the everyday .alert boxes above. */
.form-error-banner {
  background: #fdecea;
  border: 2px solid var(--danger);
  color: #7a1a12;
  padding: 1.1rem 1.3rem;
  border-radius: 10px;
  margin-bottom: 1.5rem;
  font-size: 1.05rem;
}
.form-error-banner strong { display: block; font-size: 1.15rem; margin-bottom: 0.25rem; }

.faq-item { border-bottom: 1px solid var(--foam); padding: 1.2rem 0; }
.faq-item h3 { margin: 0 0 0.5rem; font-size: 1.15rem; }

.legal-doc h2 { margin-top: 2rem; }
.legal-doc ol { padding-left: 1.2rem; }
.legal-doc section { padding: 0.5rem 0; }

@media (max-width: 640px) {
  nav.main-nav { width: 100%; justify-content: flex-start; }
  .hero { padding: 2rem 0 1.75rem; }
  h1 { font-size: 2.1rem; }
}


/* ---- Print (staff scheduling Day/Week calendars) ----
   Ant's request, 2026-08-22: a "Print Page" button on the Day and Week
   calendars, reformatted so the printed page fits on one A4 sheet.
   Hides the staff header, toolbar navigation (the Print button included
   — it's a screen-only control), holiday-management buttons/prompts and
   on-screen-only helper text; keeps card colours (private/group/full)
   since colour is how those are told apart at a glance.
   The Week calendar's 7-column grid is tuned to fit A4 in the normal
   portrait orientation — tested against a full, tightly-booked week it
   still reads cleanly (running onto a second sheet only for an unusually
   packed day). For an especially busy week, choosing "Landscape" in the
   browser's print dialog gives each day extra width — a CSS-only way to
   force that switch automatically isn't reliably supported across
   browsers, so this is left as a manual option rather than one that
   might silently fail. */
@page {
  size: A4;
  margin: 12mm;
}
@media print {
  .no-print,
  .staff-header,
  .cal-nav,
  .holiday-toggle-banner,
  .holiday-add-banner,
  .day-slot-add,
  .lesson-admin-link,
  .lesson-capacity,
  .cal-help-text {
    display: none !important;
  }

  body { background: #fff; }
  .container { max-width: none; padding: 0; }
  main .container { padding-top: 0; padding-bottom: 0.5rem; }

  * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Print-only masthead (Ant's request, 2026-08-22) — replaces the
     on-screen staff header/logo (hidden above) with a plain text line
     since the printed sheet still needs to say whose calendar this is.
     Hidden on screen by default; see .print-header below and the
     Day/Week calendar templates for the markup. */
  .print-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    border-bottom: 2px solid var(--ocean);
    padding-bottom: 0.4rem;
    margin-bottom: 0.6rem;
  }
  .print-header .print-brand {
    font-family: 'Cormorant Garamond', serif;
    font-size: 1.3rem;
    font-weight: 600;
    color: var(--ocean);
  }
  .print-header .print-page-title {
    font-size: 0.8rem;
    color: var(--mid);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .cal-toolbar { margin-bottom: 0.75rem; }
  .cal-toolbar h1 { font-size: 1.4rem; }

  .lesson-card {
    padding: 0.3rem 0.45rem;
    margin-bottom: 0.3rem;
    font-size: 0.72rem;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .lesson-programme { font-size: 0.85rem; }
  .lesson-meta { font-size: 0.68rem; }

  .day-slot-list { border-radius: 0; }
  .day-slot {
    min-height: 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .day-slot-time { font-size: 0.75rem; padding: 0.4rem 0.5rem; flex: 0 0 90px; }
  .day-slot-body { padding: 0.35rem 0.5rem; }

  /* Week calendar's time-grid table (rewritten 2026-08-27 — was a CSS
     grid of independent day columns, see the screen-styles comment above
     .week-time-grid-scroll for the full history). The horizontal-scroll
     wrapper and any min-width from the responsive rules above would
     otherwise force the printed table wider than the page or clip it —
     neither makes sense on paper, where there's no scrolling. */
  .week-time-grid-scroll { overflow: visible; border: none; max-height: none; }
  .week-time-grid { min-width: 0 !important; }
  /* Sticky positioning is a screen-only, scrolling-page concept — printed
     pages have no scroll position for it to react to, and leaving it on
     risks a header row being pinned to the top of every physical page
     it happens to be re-laid-out onto. Turned off explicitly for print. */
  .week-time-grid thead th { position: static; box-shadow: none; }
  .week-time-col { font-size: 0.68rem; padding: 0.2rem 0.3rem; width: 44px; }
  .week-day-header-cell { padding: 0.3rem 0.2rem; font-size: 0.72rem; }
  .week-day-header-cell .week-day-date { font-size: 0.62rem; }
  .cal-holiday-note-sm { font-size: 0.55rem; }

  /* No break-inside:avoid on the row itself (unlike .lesson-card below)
     — a busy hour's row can run taller than convenient near a page
     break, and asking the browser to avoid breaking inside it in that
     case just pushes the whole row to the next page, leaving the
     previous page nearly blank. Individual lesson cards still avoid
     breaking mid-card via the .lesson-card rule above. */
  .week-time-cell { padding: 0.1rem; }

  /* Tighter than the general .lesson-card print rule above — the Week
     calendar's columns are much narrower than the Day calendar's single
     column, so programme/student names wrap onto extra lines more
     easily; a slightly smaller size here keeps that wrapping (and the
     page count it drives) to a minimum. */
  .week-time-cell .lesson-card { padding: 0.18rem 0.28rem; margin-bottom: 0.18rem; font-size: 0.58rem; }
  .week-time-cell .lesson-programme { font-size: 0.68rem; }
  .week-time-cell .lesson-students { font-size: 0.58rem; }
  .week-time-cell .lesson-meta { font-size: 0.54rem; }
}

/* ---- Contact page: "Click to view on map" popup (fixed 2026-08-24) ----
   The modal markup/JS (templates/core/contact.html) has existed since
   the Contact page was built, but no CSS for it was ever written — the
   overlay div just rendered as a plain, unstyled block with no
   backdrop/centering/sizing, so clicking "Click to view on map" never
   actually looked or acted like a popup. Ant reported this as broken;
   confirmed via a headless-browser click test that the JS itself (the
   [hidden] attribute toggle) was working correctly all along — this was
   purely a missing-CSS problem, not a JS bug. */
.map-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(21, 67, 96, 0.55);
}
.map-modal-overlay[hidden] { display: none; }
.map-modal {
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 12px 40px rgba(21, 67, 96, 0.35);
  width: min(640px, 100%);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.map-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.2rem;
  background: var(--ocean);
  color: #fff;
  font-weight: 600;
}
.map-modal-close {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  color: #fff;
  padding: 0.3rem 0.8rem;
  font-size: 0.85rem;
  cursor: pointer;
}
.map-modal-close:hover { background: rgba(255, 255, 255, 0.15); }
.map-modal-iframe {
  display: block;
  width: 100%;
  height: min(70vh, 480px);
  border: 0;
}
@media (max-width: 480px) {
  .map-modal-overlay { padding: 0; }
  .map-modal { border-radius: 0; width: 100%; height: 100%; max-height: 100vh; }
  .map-modal-iframe { height: auto; flex: 1; }
}
