/* ============================================================
   Kiddie Palace — design system
   Colours are the school's own, sampled from the logo artwork.
   Contrast on white is noted; only the values marked BODY-SAFE
   clear 4.5:1 and may be used for running text.
   ============================================================ */

:root{
  /* brand — measured from the logo, not guessed */
  --magenta:#DE057A;   /* 4.76  BODY-SAFE */
  --purple:#672464;    /* 10.43 BODY-SAFE */
  --purple-deep:#522362;/*11.83 BODY-SAFE */
  --green:#00693F;     /* 6.79  BODY-SAFE */
  --green-2:#007545;   /* 5.78  BODY-SAFE */
  --blue:#618DC7;      /* 3.42  large text and accents only */
  --red:#FF000C;       /* 3.99  large text and accents only */
  --orange:#F96730;    /* 3.00  accents only */
  --orange-2:#F46928;  /* 3.04  accents only */

  /* surfaces */
  --sky-top:#B9DEF2;
  --sky-mid:#D8EEF4;
  --sky-low:#F4F7E2;
  --cream:#FBF8EC;
  --paper:#FFFFFF;
  --ink:#2A2E33;
  --ink-soft:#5C6570;
  --line:#E3E6DC;
  --night:#0E1114;

  --wrap:min(92vw, 72rem);
  --wrap-narrow:min(92vw, 46rem);
  --r:14px;
  --shadow:0 6px 20px rgba(40,50,60,.13);
  --shadow-lg:0 14px 44px rgba(40,50,60,.18);

  --cam:0px; --mx:0; --my:0; --px:50%; --py:44%;

  --gut:calc((100vw - min(92vw, 72rem)) / 2);
  --sky-grad:linear-gradient(180deg,#D3EAF7 0%,#E5F2F5 26%,#F3F7E3 58%,#FBF8EC 100%);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;background:var(--cream)}
body{
  margin:0;background:transparent;color:var(--ink);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:clamp(1rem,.96rem + .2vw,1.08rem);line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%}
a{color:var(--purple);text-underline-offset:.18em}
a:hover{color:var(--magenta)}
:focus-visible{outline:3px solid var(--magenta);outline-offset:3px;border-radius:4px}

h1,h2,h3{line-height:1.1;letter-spacing:-.02em;margin:0 0 .6em}
h1{font-size:clamp(2rem,1.3rem + 3.4vw,3.8rem)}
h2{font-size:clamp(1.6rem,1.1rem + 2.2vw,2.7rem)}
h3{font-size:clamp(1.15rem,1rem + .8vw,1.5rem);letter-spacing:-.01em}
p{margin:0 0 1.1em}
.lede{font-size:clamp(1.08rem,1rem + .5vw,1.3rem);color:var(--ink-soft)}

.wrap{width:var(--wrap);margin-inline:auto}
.narrow{width:var(--wrap-narrow);margin-inline:auto}
.section{padding:clamp(3rem,7vw,6rem) 0;background:rgba(255,255,255,.20)}
.section--tint{background:rgba(255,255,255,.34)}
.section--paper{background:rgba(255,255,255,.86)}
.section--clear{background:transparent}
.skip{position:absolute;left:-9999px}
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip:focus{left:1rem;top:1rem;z-index:99;background:#fff;padding:.7rem 1rem;border-radius:8px}

/* ---------- header ---------- */
.site-head{
  position:sticky;top:0;z-index:40;background:rgba(255,255,255,.92);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
.site-head .bar{display:flex;align-items:center;gap:1rem;padding:.65rem 0;width:var(--wrap);margin-inline:auto}
.brand{display:flex;align-items:center;gap:.6rem;flex:none;text-decoration:none}
.brand img{width:clamp(120px,18vw,170px);display:block}
.nav{margin-left:auto;display:flex;gap:.15rem;flex-wrap:wrap}
.nav a{
  text-decoration:none;color:var(--ink);font-weight:600;font-size:.94rem;
  padding:.5rem .7rem;border-radius:999px;white-space:nowrap;
}
.nav a:hover{background:var(--sky-low);color:var(--purple)}
.nav a[aria-current="page"]{background:var(--magenta);color:#fff}
.navtoggle{display:none;margin-left:auto;border:0;background:var(--sky-low);color:var(--ink);
  font:inherit;font-weight:700;padding:.55rem .9rem;border-radius:999px;cursor:pointer}
.cta{
  display:inline-flex;align-items:center;gap:.5rem;text-decoration:none;
  background:var(--magenta);color:#fff;font-weight:700;
  padding:.7rem 1.2rem;border-radius:999px;box-shadow:var(--shadow);
  transition:transform .18s ease, background .18s ease;
}
.cta:hover{background:var(--purple);color:#fff;transform:translateY(-1px)}
.cta--ghost{background:transparent;color:var(--purple);box-shadow:none;border:2px solid var(--purple)}
.cta--ghost:hover{background:var(--purple);color:#fff}

@media (max-width:860px){
  .navtoggle{display:block}
  .nav{
    display:none;position:absolute;left:0;right:0;top:100%;
    background:#fff;border-bottom:1px solid var(--line);
    flex-direction:column;gap:0;padding:.5rem 4vw 1rem;
  }
  .nav.open{display:flex}
  .nav a{padding:.8rem .6rem;border-radius:10px}
}

/* ---------- hero ---------- */
.hero{height:340vh;position:relative}
.viewport{
  position:sticky;top:0;height:100vh;overflow:hidden;
  perspective:1400px;perspective-origin:var(--px) var(--py);
  background:radial-gradient(120% 90% at 50% 8%, var(--sky-top) 0%, var(--sky-mid) 46%, var(--sky-low) 100%);
}
.stage{
  position:absolute;left:50%;top:50%;width:min(94vw,162vh);aspect-ratio:2745/1534;
  transform-style:preserve-3d;
  transform:translate(-50%,-50%) translateZ(var(--cam))
            rotateY(calc(var(--mx) * 1.6deg)) rotateX(calc(var(--my) * -1deg));
}
.lyr{position:absolute;transform-style:preserve-3d}
.lyr img{display:block;width:100%;height:auto}
.wm{transition:opacity .1s linear}
.drift{}
/* figures share ONE depth plane — different planes tear their linked hands apart */
.sway{transform-origin:50% 96%}
.figsway{position:absolute;inset:0}
.part{position:absolute;display:block}
.head{transform-origin:var(--pvx) var(--pvy)}
.head img{display:block;width:100%;height:auto}
.head .blink{position:absolute;inset:0;opacity:0}

.hint{
  position:absolute;left:50%;bottom:3vh;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:.5rem;
  font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;color:#5B6470;
}
.hint span{width:1px;height:32px;background:linear-gradient(#5B6470,transparent);
  animation:drop 1.8s ease-in-out infinite}
@keyframes drop{0%,100%{opacity:.25;transform:scaleY(.6)}50%{opacity:.9;transform:scaleY(1)}}
.tagline{
  position:absolute;right:6vw;top:15vh;text-align:right;opacity:0;pointer-events:none;
  font-size:clamp(1.5rem,3.6vw,2.9rem);font-weight:800;line-height:1.15;color:#39414B;
  max-width:11ch;transform:translateY(14px);transition:transform .3s ease-out;
}
.tagline em{display:block;font-style:normal;font-weight:600;font-size:.4em;
  letter-spacing:.15em;text-transform:uppercase;color:#6C7681;margin-top:.9em}

/* ---------- page header (inner pages) ---------- */
.phead{
  background:rgba(255,255,255,.42);
  padding:clamp(2.5rem,6vw,4.5rem) 0 clamp(2rem,5vw,3.5rem);
  border-bottom:1px solid var(--line);
}
.phead p{max-width:52ch;margin-bottom:0}

/* ---------- cards & grids ---------- */
.grid{display:grid;gap:clamp(1rem,2.4vw,1.8rem)}
.g2{grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(min(100%,19rem),1fr))}
/* 19rem, not 16 — at the 72rem wrap 16rem fits four across, which leaves the
   six class cards and the six timetable cards sitting 4 + 2 with a hole. */
.g4{grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr))}

.card{
  background:var(--paper);border-radius:var(--r);padding:clamp(1.2rem,2.4vw,1.9rem);
  box-shadow:var(--shadow);border-top:6px solid var(--c,var(--blue));
}
.card h3{margin-bottom:.35em}
.age{
  display:inline-block;font-weight:700;font-size:.82rem;letter-spacing:.04em;
  color:#fff;background:var(--c,var(--blue));padding:.25rem .7rem;border-radius:999px;margin-bottom:.7rem;
}
.card p:last-child{margin-bottom:0}

.tile{
  background:var(--paper);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow);
  display:flex;flex-direction:column;
}
.tile img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block}
.tile .body{padding:1.1rem 1.2rem}
.tile h3{margin-bottom:.3em}
.tile p{margin-bottom:0;color:var(--ink-soft);font-size:.95rem}

.pill-list{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:.55rem}
.pill-list li{
  background:var(--paper);border:2px solid var(--c,var(--blue));color:var(--ink);
  border-radius:999px;padding:.45rem 1rem;font-weight:600;font-size:.95rem;
}

.facts{list-style:none;padding:0;margin:0;display:grid;gap:.7rem}
.facts li{display:flex;gap:.7rem;align-items:flex-start}
.facts b{flex:none;width:.7rem;height:.7rem;border-radius:50%;background:var(--c,var(--green));margin-top:.55em}

/* ---------- class rows ---------- */
.classrow{display:grid;gap:clamp(1.4rem,3.4vw,2.6rem);align-items:center;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,21rem),1fr))}
.classshot{margin:0}
.classshot img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;
  border-radius:16px;border:6px solid var(--c,var(--blue));box-shadow:var(--shadow)}
.classshot figcaption{margin:.7rem .2rem 0;font-size:.9rem;color:var(--ink-soft)}
@media (min-width:62rem){
  .classrow--flip .classshot{order:-1}
}

/* ---------- faces strip ---------- */
.faces{position:relative;overflow:hidden;background:linear-gradient(var(--sky-low),var(--cream) 55%,var(--sky-low));
  padding:clamp(3rem,7vw,5.5rem) 0}
.faces .head-txt{width:var(--wrap-narrow);margin:0 auto clamp(1.8rem,4vw,2.8rem);text-align:center}
.faces h2 b{color:var(--magenta);font-weight:inherit}
.strip{display:flex;gap:clamp(.7rem,1.6vw,1.2rem);width:max-content}
.strip + .strip{margin-top:clamp(.7rem,1.6vw,1.2rem)}
.photo-card{
  flex:none;width:clamp(150px,20vw,280px);background:#fff;padding:9px;border-radius:14px;
  box-shadow:var(--shadow);transform:rotate(var(--r2,0deg));
}
.photo-card img{display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;border-radius:8px;
  border:4px solid var(--c,var(--blue))}

/* ---------- video ---------- */
.vid{height:150vh;position:relative;background:var(--night)}
.vid .stick{position:sticky;top:0;height:100vh;overflow:hidden;background:var(--night)}
.vid video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background:var(--night)}
.vshade{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .5s ease;
  background:linear-gradient(to top, rgba(8,10,12,.55) 0%, rgba(8,10,12,0) 38%)}
.vid.playing .vshade{opacity:1}
.sound{
  position:absolute;right:clamp(1rem,3vw,2.5rem);bottom:clamp(1rem,3vw,2.5rem);
  display:inline-flex;align-items:center;gap:.6rem;padding:.7rem 1.15rem .7rem .95rem;
  border:0;border-radius:999px;background:rgba(14,17,20,.62);color:#fff;cursor:pointer;
  font:inherit;font-size:.9rem;font-weight:600;backdrop-filter:blur(8px);
  box-shadow:0 2px 14px rgba(0,0,0,.35), inset 0 0 0 1px rgba(255,255,255,.16);
}
.sound:hover{background:rgba(14,17,20,.85)}
.sound svg{width:19px;height:19px;flex:none}
.sound .on{display:none}
.vid.unmuted .sound .on{display:block}
.vid.unmuted .sound .off{display:none}
.vid.unmuted .sound .lbl{display:none}
.bigplay{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:none;
  align-items:center;gap:.7rem;padding:1rem 1.6rem;border:0;border-radius:999px;cursor:pointer;
  background:rgba(255,255,255,.94);color:#15181C;font:inherit;font-size:1rem;font-weight:700;
  box-shadow:0 6px 30px rgba(0,0,0,.4);
}
.vid.idle .bigplay{display:inline-flex}
.vfail{
  position:absolute;left:50%;top:calc(50% + 4.5rem);transform:translateX(-50%);display:none;
  max-width:min(90vw,34rem);text-align:center;padding:.9rem 1.2rem;border-radius:12px;
  background:rgba(255,255,255,.94);color:#8A2318;font-size:.92rem;line-height:1.5;
}
.vid.failed .vfail{display:block}
.vid.failed .bigplay{display:none}

/* ---------- gallery ---------- */
.gal{columns:4 15rem;column-gap:clamp(.6rem,1.4vw,1rem)}
.gal figure{break-inside:avoid;margin:0 0 clamp(.6rem,1.4vw,1rem)}
.gal img{width:100%;display:block;border-radius:10px;box-shadow:var(--shadow)}
.gal figcaption{font-size:.82rem;color:var(--ink-soft);padding:.4rem .2rem 0}

/* ---------- contact ---------- */
.contact-grid{display:grid;gap:clamp(1.4rem,3vw,2.4rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr))}
.field{display:block;margin-bottom:1rem}
.field span{display:block;font-weight:700;font-size:.92rem;margin-bottom:.3rem}
.field input,.field textarea,.field select{
  width:100%;font:inherit;padding:.75rem .9rem;border:2px solid var(--line);
  border-radius:10px;background:#fff;color:var(--ink);
}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--magenta);outline:none}
.note{
  padding:1rem 1.2rem;border-left:4px solid var(--blue);background:var(--paper);
  border-radius:0 10px 10px 0;font-size:.93rem;color:var(--ink-soft);
}
.note strong{color:var(--ink)}

/* ---------- footer ---------- */
.site-foot{background:var(--purple-deep);color:#EDE7F0;padding:clamp(2.5rem,6vw,4rem) 0 2rem;margin-top:0}
.site-foot a{color:#F7D9E9}
.site-foot a:hover{color:#fff}
.site-foot h3{color:#fff;font-size:1.05rem;margin-bottom:.6em}
.foot-grid{display:grid;gap:2rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,14rem),1fr))}
.foot-grid ul{list-style:none;padding:0;margin:0;display:grid;gap:.4rem;font-size:.95rem}
.legal{border-top:1px solid rgba(255,255,255,.18);margin-top:2.2rem;padding-top:1.2rem;
  font-size:.85rem;color:#CDBFD4;display:flex;flex-wrap:wrap;gap:.8rem 1.6rem}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .stage{transform:translate(-50%,-50%) !important}
  .sway,.head,.blink,.drift,.hint span{animation:none !important;transform:none !important}
  .blink{opacity:0 !important}
  .hero{height:100vh}
  .wm{opacity:1 !important}
  .tagline{display:none}
  .strip{flex-wrap:wrap;width:auto;justify-content:center;transform:none !important}
}

/* ---------- hero animation (generated) ----------
   One shared sway period with staggered delays: the motion travels down the
   chain like children actually swinging linked arms, so neighbours never fight
   each other and the joined hands stay together. */
.s-boy1{animation:sway-boy1 5.20s ease-in-out -0.00s infinite}
@keyframes sway-boy1{0%,100%{transform:rotate(-1.65deg) translateY(0)}50%{transform:rotate(1.65deg) translateY(-8px)}}
.s-girl1{animation:sway-girl1 5.20s ease-in-out -0.42s infinite}
@keyframes sway-girl1{0%,100%{transform:rotate(-1.55deg) translateY(0)}50%{transform:rotate(1.55deg) translateY(-8px)}}
.s-teacher{animation:sway-teacher 5.20s ease-in-out -0.84s infinite}
@keyframes sway-teacher{0%,100%{transform:rotate(-0.75deg) translateY(0)}50%{transform:rotate(0.75deg) translateY(-4px)}}
.s-boy2{animation:sway-boy2 5.20s ease-in-out -1.26s infinite}
@keyframes sway-boy2{0%,100%{transform:rotate(-1.60deg) translateY(0)}50%{transform:rotate(1.60deg) translateY(-8px)}}
.s-girl2{animation:sway-girl2 5.20s ease-in-out -1.68s infinite}
@keyframes sway-girl2{0%,100%{transform:rotate(-1.50deg) translateY(0)}50%{transform:rotate(1.50deg) translateY(-7px)}}
.s-kite{transform-origin:67.2% 90.3%;animation:sway-kite 7.80s ease-in-out -1.10s infinite}
@keyframes sway-kite{0%,100%{transform:rotate(-2.60deg)}50%{transform:rotate(2.60deg)}}
.t-boy1{animation:tilt-boy1 6.40s ease-in-out -0.90s infinite}
@keyframes tilt-boy1{0%,100%{transform:rotate(-2.60deg)}50%{transform:rotate(2.60deg)}}
.t-girl1{animation:tilt-girl1 7.10s ease-in-out -2.40s infinite}
@keyframes tilt-girl1{0%,100%{transform:rotate(-2.30deg)}50%{transform:rotate(2.30deg)}}
.t-teacher{animation:tilt-teacher 8.20s ease-in-out -1.30s infinite}
@keyframes tilt-teacher{0%,100%{transform:rotate(-1.50deg)}50%{transform:rotate(1.50deg)}}
.t-boy2{animation:tilt-boy2 6.00s ease-in-out -3.50s infinite}
@keyframes tilt-boy2{0%,100%{transform:rotate(-2.70deg)}50%{transform:rotate(2.70deg)}}
.t-girl2{animation:tilt-girl2 6.80s ease-in-out -4.60s infinite}
@keyframes tilt-girl2{0%,100%{transform:rotate(-2.40deg)}50%{transform:rotate(2.40deg)}}
.d-sun{animation:drift-sun 46.0s ease-in-out -0.0s infinite}
@keyframes drift-sun{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(2.20%,-5.7px,0)}}
.d-cloud3{animation:drift-cloud3 38.0s ease-in-out -9.0s infinite}
@keyframes drift-cloud3{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(3.40%,-8.8px,0)}}
.d-cloud1{animation:drift-cloud1 30.0s ease-in-out -4.5s infinite}
@keyframes drift-cloud1{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(3.40%,-8.8px,0)}}
.d-cloud2{animation:drift-cloud2 34.0s ease-in-out -14.0s infinite}
@keyframes drift-cloud2{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(3.40%,-8.8px,0)}}
.k-boy1{animation:blink-boy1 7.30s steps(1,end) -1.10s infinite}
@keyframes blink-boy1{0%,93.0%{opacity:0}93.4%,94.8%{opacity:1}95.2%,100%{opacity:0}}
.k-girl1{animation:blink-girl1 9.10s steps(1,end) -4.00s infinite}
@keyframes blink-girl1{0%,90.0%{opacity:0}90.4%,91.6%{opacity:1}92.0%,93.2%{opacity:0}93.6%,94.8%{opacity:1}95.2%,100%{opacity:0}}
.k-teacher{animation:blink-teacher 8.20s steps(1,end) -2.60s infinite}
@keyframes blink-teacher{0%,93.0%{opacity:0}93.4%,94.8%{opacity:1}95.2%,100%{opacity:0}}
.k-boy2{animation:blink-boy2 6.40s steps(1,end) -5.20s infinite}
@keyframes blink-boy2{0%,90.0%{opacity:0}90.4%,91.6%{opacity:1}92.0%,93.2%{opacity:0}93.6%,94.8%{opacity:1}95.2%,100%{opacity:0}}
.k-girl2{animation:blink-girl2 10.40s steps(1,end) -3.30s infinite}
@keyframes blink-girl2{0%,93.0%{opacity:0}93.4%,94.8%{opacity:1}95.2%,100%{opacity:0}}
@media (prefers-reduced-motion: reduce){.s-kite{animation:none!important;transform:none!important}}

/* ============================================================
   Sky backdrop — one fixed layer behind every page.
   Everything here is transform/opacity only, so the compositor
   does the work and the main thread stays free for scrolling.
   ============================================================ */
.sky{
  position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden;
  background:var(--sky-grad);
}
.sky > *{position:absolute;display:block}

.sky-move{position:absolute;inset:0}
.sky-move > *{position:absolute;display:block}

/* Nothing may drift at full strength straight through the column of body text.
   The obvious fix — masking .sky-move — makes the compositor re-rasterise the
   whole moving group every frame (measured: p90 33ms, half the frames dropped).
   So the fade is a still layer instead: a second copy of the sky gradient laid
   OVER the floaters, itself masked to be opaque down the middle and clear at
   the edges. It is painted once and never animates, so it costs nothing. */
.sky-veil{
  position:absolute;inset:0;background:var(--sky-grad);
  -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0%,rgba(0,0,0,0) 16%,
                      rgba(0,0,0,.70) 31%,rgba(0,0,0,.70) 69%,rgba(0,0,0,0) 84%,rgba(0,0,0,0) 100%);
          mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0%,rgba(0,0,0,0) 16%,
                      rgba(0,0,0,.70) 31%,rgba(0,0,0,.70) 69%,rgba(0,0,0,0) 84%,rgba(0,0,0,0) 100%);
}

/* ---- sun, top right, half off the edge ---- */
.sun{
  right:-6vw;top:-5vw;width:min(27vw,235px);aspect-ratio:1;
  background:url(../img/hero/sun.svg) no-repeat center/100% 100%;
  animation:sun-turn 34s ease-in-out infinite;
}
.sun-glow{
  right:-13vw;top:-13vw;width:min(54vw,450px);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(251,233,108,.50) 0%,rgba(251,233,108,.20) 44%,rgba(251,233,108,0) 70%);
  animation:sun-glow 9s ease-in-out infinite;
}
@keyframes sun-turn{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(6deg)}}
@keyframes sun-glow{0%,100%{opacity:.5}50%{opacity:1}}

/* ---- clouds: one path, five speeds, staggered by negative delay ---- */
.cl{left:0;aspect-ratio:2;background-repeat:no-repeat;background-size:100% 100%}
@keyframes sail{
  0%  {transform:translate3d(-44vw,0,0)}
  25% {transform:translate3d(-2vw,-9px,0)}
  50% {transform:translate3d(40vw,3px,0)}
  75% {transform:translate3d(83vw,-7px,0)}
  100%{transform:translate3d(126vw,0,0)}
}
.cl1{top:4%; width:min(21vw,155px);opacity:.34;background-image:url(../img/hero/cloud1.svg);animation:sail 300s linear  -30s infinite}
.cl2{top:12%;width:min(31vw,245px);opacity:.52;background-image:url(../img/hero/cloud2.svg);animation:sail 212s linear -142s infinite}
.cl3{top:27%;width:min(24vw,190px);opacity:.40;background-image:url(../img/hero/cloud3.svg);animation:sail 258s linear  -76s infinite}
.cl4{top:38%;width:min(35vw,290px);opacity:.55;background-image:url(../img/hero/cloud1.svg);animation:sail 176s linear -205s infinite}
.cl5{top:52%;width:min(18vw,140px);opacity:.28;background-image:url(../img/hero/cloud3.svg);animation:sail 336s linear -268s infinite}

/* ---- bubbles: the school's own video is full of them ---- */
.bub{
  bottom:-10vh;left:var(--x);width:var(--s);height:var(--s);border-radius:50%;
  background:radial-gradient(circle at 32% 27%,
    rgba(255,255,255,.95) 0 5%, rgba(255,255,255,.45) 15%,
    var(--t) 58%, rgba(255,255,255,.55) 84%, rgba(255,255,255,0) 86%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.55);
  animation:rise var(--d) linear var(--dl) infinite;
}
@keyframes rise{
  0%  {transform:translate3d(0,0,0) scale(.85);opacity:0}
  9%  {opacity:.9}
  35% {transform:translate3d(22px,-42vh,0) scale(1)}
  70% {transform:translate3d(-16px,-84vh,0) scale(1.02)}
  92% {opacity:.75}
  100%{transform:translate3d(10px,-122vh,0) scale(1.05);opacity:0}
}

/* ---- balloons ---- */
.bal{bottom:-26vh;left:var(--x);width:var(--s);animation:lift var(--d) linear var(--dl) infinite}
.bal i{display:block;width:100%;aspect-ratio:.82;border-radius:50% 50% 47% 47%;
  background:var(--c);position:relative;
  box-shadow:inset -7px -9px 0 rgba(0,0,0,.10), inset 9px 9px 0 rgba(255,255,255,.24);
  animation:tilt 7s ease-in-out infinite}
.bal i::after{content:"";position:absolute;left:50%;bottom:-5px;width:8px;height:7px;
  margin-left:-4px;background:var(--c);border-radius:2px 2px 4px 4px}
.bal b{display:block;width:11px;height:46px;margin:5px auto 0;
  border-left:1.5px solid rgba(60,50,60,.30);border-radius:0 0 0 70%}
@keyframes lift{
  0%  {transform:translate3d(0,0,0);opacity:0}
  10% {opacity:.95}
  50% {transform:translate3d(4vw,-70vh,0)}
  90% {opacity:.9}
  100%{transform:translate3d(-2vw,-142vh,0);opacity:0}
}
@keyframes tilt{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}

/* ---- the kite from the logo, crossing high up ---- */
.kite-fly{top:9%;left:0;width:min(14vw,110px);aspect-ratio:454/330;
  background:url(../img/hero/kite.webp) no-repeat center/contain;
  animation:kite-cross 82s linear -12s infinite}
@keyframes kite-cross{
  0%  {transform:translate3d(-25vw,0,0) rotate(-8deg)}
  30% {transform:translate3d(20vw,-26px,0) rotate(7deg)}
  62% {transform:translate3d(64vw,16px,0) rotate(-6deg)}
  100%{transform:translate3d(122vw,-10px,0) rotate(6deg)}
}

/* fewer moving parts where they cost the most */
@media (max-width:760px){
  .cl4,.cl5,.kite-fly{display:none}
  .sun{width:38vw}
}
@media print{ .sky{display:none} }

@media (prefers-reduced-motion: reduce){
  .sun,.sun-glow,.cl,.bub,.bal,.bal i,.kite-fly{animation:none !important}
  .sun-glow{opacity:.7}
  .bub,.bal{display:none}
  .cl1{transform:translate3d(9vw,0,0)}
  .cl2{transform:translate3d(58vw,0,0)}
  .cl3{transform:translate3d(31vw,0,0)}
  .cl4{transform:translate3d(72vw,0,0)}
  .cl5{transform:translate3d(6vw,0,0)}
  .kite-fly{transform:translate3d(46vw,0,0) rotate(-5deg)}
}

/* Below the mask breakpoint the text fills the screen, so instead of masking
   the middle we simply hold the strongest floaters back. */
@media (max-width:61.99rem){
  .bal i,.bal b{opacity:.45}
  .cl4{opacity:.34}
  .bub{opacity:.8}
}

/* ---------- class rows: the writing sits on its own colour ---------- */
.classrow{position:relative}
.classtext{position:relative;padding:clamp(1.3rem,3vw,2.1rem);border-radius:22px}
.classtext::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  background:var(--c-soft);box-shadow:inset 0 0 0 2px var(--c-line);
}
/* On a wide screen the colour runs off the side of the page, so it reads as
   half the background rather than a box. --gut is the distance from the edge
   of the content column to the edge of the window. */
@media (min-width:62rem){
  .classrow > .classtext::before{border-radius:26px}
  .classrow:not(.classrow--flip) > .classtext::before{
    left:calc(-1 * var(--gut));border-radius:0 26px 26px 0}
  .classrow--flip > .classtext::before{
    right:calc(-1 * var(--gut));border-radius:26px 0 0 26px}
}
.classshot img{transition:transform .5s ease}
.classshot:hover img{transform:scale(1.02)}

/* ---------- facilities tiles ---------- */
.hl{color:var(--magenta);font-weight:inherit}
.tile--pop{border-top:6px solid var(--c,var(--blue));overflow:hidden}
.tile--pop img{transition:transform .55s cubic-bezier(.2,.7,.3,1)}
.tile--pop:hover img{transform:scale(1.05)}
.tile--pop h3{color:var(--ct,var(--purple))}

/* ---------- blocks bounce in on first sight ----------
   The .rise class is added by site.js, never by the HTML, so a visitor with
   JavaScript off sees the page normally instead of a blank grid. */
.rise{opacity:0;transform:translateY(48px) scale(.84)}
.rise.in{animation:pop 1.05s cubic-bezier(.28,.72,.38,1) var(--d,0ms) both}
/* the big half-page class panels bounce without the tilt — a tilted slab of
   colour reads as crooked rather than springy */
.classrow > .rise.in{animation-name:pop-flat}

@keyframes pop{
  0%   {opacity:0; transform:translateY(48px) scale(.84) rotate(-1.4deg)}
  30%  {opacity:1}
  46%  {transform:translateY(-18px) scale(1.055) rotate(1.1deg)}
  62%  {transform:translateY(9px)   scale(.978)  rotate(-.6deg)}
  76%  {transform:translateY(-5px)  scale(1.018) rotate(.3deg)}
  88%  {transform:translateY(2px)   scale(.994)  rotate(-.12deg)}
  100% {opacity:1; transform:none}
}
@keyframes pop-flat{
  0%   {opacity:0; transform:translateY(48px) scale(.88)}
  30%  {opacity:1}
  46%  {transform:translateY(-16px) scale(1.035)}
  62%  {transform:translateY(8px)   scale(.985)}
  76%  {transform:translateY(-4px)  scale(1.012)}
  88%  {transform:translateY(2px)   scale(.996)}
  100% {opacity:1; transform:none}
}
@media (prefers-reduced-motion: reduce){
  .rise,.rise.in{opacity:1 !important;transform:none !important;animation:none !important}
  .classshot:hover img,.tile--pop:hover img{transform:none}
}

/* ---------- never animate two full scenes at once ----------
   On the home page the hero is a sticky, opaque, full-screen scene with its own
   sky, so the page backdrop behind it is invisible; and once you have scrolled
   past the hero, the hero's own twenty animations are off screen. Running both
   sets together was costing half the frames on the home page (measured: 33ms
   median, 30fps). Whichever one you cannot see is paused. */
.hero-in .sky-move *{animation-play-state:paused}
.hero-out .hero .sway,
.hero-out .hero .head,
.hero-out .hero .blink,
.hero-out .hero .drift,
.hero-out .hint span{animation-play-state:paused}

/* promote the hero's layers only while it is the thing on screen */
.hero-in .stage,.hero-in .lyr,.hero-in .drift,.hero-in .sway,.hero-in .head{will-change:transform}
/* and stop painting it altogether once it is behind you */
.hero-out .viewport{visibility:hidden}
.home .kite-fly{display:none}          /* the hero flies its own kite */
.home .cl5{display:none}

/* ---------- daily timetable ----------
   Two real timetables from the school, laid out in our own design rather
   than reproducing their Word artwork. One column per timetable on wide
   screens, stacked below 54rem, and the time column drops above the line
   on very narrow phones so nothing is squeezed. --c is the accent, --ct
   the text-safe variant of it (several brand colours cannot carry text). */
.tt-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(23rem,1fr));gap:clamp(1.2rem,2.6vw,2rem)}
.tt{
  background:var(--paper);border-radius:var(--r);box-shadow:var(--shadow);
  border-top:6px solid var(--c,var(--blue));padding:clamp(1.2rem,2.4vw,1.8rem);
}
.tt h3{margin:0 0 .15em}
.tt .tt-who{margin:0 0 1.1rem;font-size:.95rem;color:var(--ink-soft)}
.tt ol{list-style:none;margin:0;padding:0}
.tt li{
  display:grid;grid-template-columns:9.7rem 1fr;gap:.85rem;align-items:baseline;
  padding:.62rem 0;border-top:1px solid var(--line);
}
.tt li:first-child{border-top:0;padding-top:0}
.tt li:last-child{padding-bottom:0}
.tt time{
  font-variant-numeric:tabular-nums;font-weight:700;font-size:.95rem;
  white-space:nowrap;color:var(--ct,var(--c,var(--green)));
}
/* Below 34rem the time column is dropped above the line rather than squeezed.
   A wrapped time reads as two separate times, which is worse than a taller row. */
@media (max-width:34rem){
  .tt li{grid-template-columns:1fr;gap:.1rem}
}

/* ---------- long-form text (privacy policy) ----------
   Headings get room above them so the eye finds each section; lists keep
   real bullets because this is reference text people scan for their right. */
.prose h2{font-size:clamp(1.35rem,1.1rem + 1.2vw,1.85rem);margin:2.2em 0 .5em}
.prose h2:first-child{margin-top:0}
.prose ul{margin:0 0 1.1em;padding-left:1.3em}
.prose li{margin:.25em 0}
.prose li::marker{color:var(--magenta)}
.prose .updated{margin-top:2.4em;font-size:.9rem;color:var(--ink-soft)}

/* ---------- enquiry form: consent, honeypot, status ---------- */
.consent{display:flex;gap:.7rem;align-items:flex-start;margin:1.2rem 0 1.4rem;font-size:.95rem;line-height:1.5}
.consent input{flex:none;width:1.25rem;height:1.25rem;margin:.15rem 0 0;accent-color:var(--magenta)}
/* The honeypot is moved off-screen rather than display:none, because some
   bots skip fields that are display:none. It is also aria-hidden and out of
   the tab order, so no person using a keyboard or screen reader meets it. */
.hp{position:absolute!important;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}
.form-status{margin-top:1rem;padding:.9rem 1.1rem;border-radius:10px;font-size:.97rem;line-height:1.5}
.form-status[data-kind="ok"]{background:#E6F4EC;border-left:4px solid var(--green);color:#0B3D27}
.form-status[data-kind="err"]{background:#FDECEF;border-left:4px solid #B5122E;color:#5E0A18}
.form-status:empty{display:none}
#enquiry button[disabled]{opacity:.6;cursor:progress}

/* ---------- WhatsApp button, fixed on every page ---------- */
.wa-float{
  position:fixed;z-index:45;
  right:max(1rem,env(safe-area-inset-right));
  bottom:calc(1rem + env(safe-area-inset-bottom));
  display:inline-flex;align-items:center;gap:.55rem;
  padding:.7rem 1.15rem .7rem .85rem;border-radius:999px;
  background:var(--green);color:#fff;font-weight:800;line-height:1;text-decoration:none;
  box-shadow:0 6px 20px rgba(0,0,0,.22);
  transition:transform .2s ease,box-shadow .2s ease;
}
.wa-float:hover{color:#fff;transform:translateY(-2px);box-shadow:0 10px 26px rgba(0,0,0,.26)}
.wa-float:focus-visible{outline:3px solid #fff;outline-offset:2px;box-shadow:0 0 0 6px var(--green)}
.wa-float svg{width:28px;height:28px;flex:none}
.wa-float .dot{fill:var(--green)}
.site-foot{padding-bottom:5.5rem}
@media (max-width:34rem){
  .wa-float{padding:.85rem}
  .wa-float span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
}
@media (prefers-reduced-motion: reduce){.wa-float{transition:none}.wa-float:hover{transform:none}}
@media print{.wa-float{display:none}}
