/* ==========================================================================
   KPJ Cares Junior — page overrides.

   Loaded only on the page-cares-junior.php template, after junior-playful.css
   (the shared Junior design system) which it depends on. Ported verbatim from
   the approved static draft kpj-cares-junior-draft-a.html; the WordPress
   integration block at the foot is the only addition.

   Dual-audience hero: parent copy keeps the left, the right is a vivid Junior
   panel.
   ========================================================================== */
.jrp-hero-a{background:linear-gradient(120deg,#fdfbf8 0%,#f7f3ee 60%,#f1f4f7 100%);
  padding-bottom:calc(clamp(36px,6vw,60px) + 44px)}
.jrp-hero-a .jr-split{align-items:stretch}
.jrp-hero-a .jr-b{display:flex}
/* Copy is shorter than the panel, so centre it rather than let it hang at the top */
.jrp-hero-a .jr-a{justify-content:center}

.jrp-panel{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:22px;
  padding:34px 26px 0;min-height:440px;overflow:clip;
  background:linear-gradient(150deg,#32b6b2 0%,#0f6e6b 100%);
  border-radius:42px 0 0 42px;
  /* True bleed to the viewport edge at any width: the gap from .jr-in's right
     edge to the viewport is (100vw - wrap)/2 once the wrap is capped, and
     --jr-pad-x below that. max() picks the right one; .jr-page's overflow-x:clip
     absorbs the scrollbar overshoot in 100vw. */
  margin-right:calc(-1 * max(var(--jr-pad-x),(100vw - var(--jr-wrap)) / 2));
  box-shadow:0 26px 60px rgba(10,79,77,.28)}
/* The phone runs past the panel's bottom edge and is cut by its overflow:clip —
   deliberate, and it keeps the panel from towering over the copy column. */
.jrp-panel .jr-phone{position:relative;z-index:1;width:min(100%,238px);margin-bottom:-84px}
.jrp-panel .jrp-logo-card{position:relative;z-index:1}

/* The wireframe's two callout labels, kept word for word. They live inside
   .jr-phone and are positioned against it, not the panel: the panel bleeds to the
   viewport edge and grows with the screen, so panel-anchored labels drifted from
   156px clear of the phone at 1920 to overlapping it by 96px at 1024. Anchored
   here they hold the same offset at every width. The 16px pull-in overlaps the
   phone's dark bezel slightly, which reads as a tag attached to the device. */
/* width:max-content is required. These are absolutely positioned with left:auto
   and a right offset, so their shrink-to-fit width is measured against the space
   left inside .jr-phone — only 238px wide — and the cards collapsed to 70px.
   max-content sizes them from their own text instead, then max-width caps it. */
.jrp-panel .jr-float{z-index:2;width:max-content;max-width:172px;font-size:11.5px;padding:10px 13px}
.jrp-panel .jr-float--a{top:22%;right:calc(100% - 16px);left:auto;bottom:auto}
.jrp-panel .jr-float--b{top:52%;left:calc(100% - 16px);right:auto;bottom:auto}

@media(max-width:800px){
  .jrp-panel{margin-right:0;border-radius:32px;min-height:0;padding:30px 22px 0}
}
/* Below this the gap between the phone and the panel edge is narrower than a
   label, so the right-hand one is clipped by the panel's overflow. Measured:
   it runs out of clearance at about 1277px. */
@media(max-width:1320px){.jrp-panel .jr-float{display:none}}

/* ── Hero bubble tiers, back to front ──────────────────────────────────────
   blurred blobs → translucent bubbles → small solid stars.

   The bubbles are faint enough to pass behind the copy without reading as a
   defect, which is what lets them be large and placed freely instead of being
   squeezed into the narrow gutters beside the text. Keep --o at or below .22:
   past roughly .25 the slate lede stops clearing 4.5:1 on the tinted ground.

   .jrp-blob is declared here because draft A originally had confetti only
   inside the teal panel — without it these spans are unstyled inline boxes and
   never render. */
.jrp-blob{position:absolute;border-radius:50%;pointer-events:none;z-index:0;filter:blur(2px)}
.jrp-c--soft{border-radius:50%;background:var(--c,var(--jrp-amber));opacity:var(--o,.16)}
.jrp-c--softring{border-radius:50%;border:var(--bw,6px) solid var(--c,var(--jrp-coral));opacity:var(--o,.2)}

/* Composes a scale into the drift transform the shared sheet sets on .jrp-c, so
   the whole decorative layer can be resized from one variable rather than every
   inline width/height being restated. */
.jr-hero>.jrp-confetti .jrp-c{transform:translateY(calc(var(--jrp-scroll) * var(--f,1))) scale(var(--s,1))}

/* Sized for the desktop hero, where the bubbles have a 1280px stage. On the
   stacked layout the same circles crowd a 390px column, so scale them down —
   stars less than bubbles, since they are already small. */
@media(max-width:730px){
  .jr-hero>.jrp-confetti .jrp-c--soft,
  .jr-hero>.jrp-confetti .jrp-c--softring{--s:.58}
  .jr-hero>.jrp-confetti .jrp-c--star{--s:.8}
  .jr-hero>.jrp-confetti .jrp-blob{transform:scale(.64)}
}

/* The eyebrow pill's tint is 15% hue over *transparent*, so a bubble drifting
   behind it darkens the ground and drags the taupe ink under 4.5:1. Compositing
   the same tint over white instead makes the pill opaque — visually identical on
   the near-white hero, but its contrast can no longer be moved by what is behind. */
.jrp-hero-a .jr-eyebrow{background:color-mix(in srgb,var(--jrp-hue,var(--jrp-teal)) 15%,#fff)}

/* The shared sheet hides every section-level piece below 730px, because small
   solid ones land on the copy once the hero stacks. There are no small solid
   pieces over the copy here — the bubbles are meant to pass behind it and the
   stars sit in the hero's own padding bands — so opt back in. Same specificity
   as the shared rule, and this block is later in the cascade. */
@media(max-width:730px){.jr-hero>.jrp-confetti .jrp-c{display:block}}

/* Align the sub-nav with the chrome header. kpj-chrome.js lays its header out on
   the Bootstrap .container ladder with .75rem inline padding, whereas this ul used
   a 1280px wrap with --jr-pad-x (48px at desktop) — which put the first item 70px
   to the right of the KPJ logo at >=1400px. Match the ladder, and drop the first
   link's own left padding so its text starts on the container edge rather than
   14px inside it. */
.jr-subnav ul{max-width:none;padding-inline:.75rem}
@media(min-width:576px){.jr-subnav ul{max-width:540px}}
@media(min-width:768px){.jr-subnav ul{max-width:720px}}
@media(min-width:992px){.jr-subnav ul{max-width:960px}}
@media(min-width:1200px){.jr-subnav ul{max-width:1140px}}
@media(min-width:1400px){.jr-subnav ul{max-width:1320px}}
.jr-subnav li:first-child a{padding-left:0}

/* Anchor targets must clear the sticky chrome. The taupe header bar is fixed at
   65px and the sub-nav sticks directly below it at 46px, so the top 111px of the
   viewport is always covered; without this an anchor scrolls its section to y=0
   and drops the heading behind them. --wp-admin-offset adds the admin bar for a
   logged-in editor; it resolves to 0 for everyone else. */
main section[id]{scroll-margin-top:calc(124px + var(--wp-admin-offset,0px))}

/* Real QR artwork replaces the dashed placeholder box. height:auto is required —
   the width/height attributes are presentational hints that would otherwise beat
   the CSS width and squash the code, and a distorted QR will not scan. */
.jrp-qr-img{display:block;width:100%;height:auto;border-radius:8px}

/* ── Little Heroes side tab ────────────────────────────────────────────────
   Docked to the viewport edge rather than placed in the sub-nav. Two earlier
   attempts put it inside .jr-subnav ul, which scrolls horizontally below 730px —
   pinning an opaque item over a scroller always hides whatever passes beneath it
   (measured: it covered "Junior Benefits" and "How to Enrol" at 390px).

   z-index 70 is deliberate: the chrome header is 9999 and the bottom nav 2, and
   .jr-subnav is 60 — so this sits above page content and the sub-nav, but can
   never cover the KPJ chrome. */
/* right:-4px + 4px extra right padding bleed the element itself past the screen
   edge, so the extreme edge pixels — the natural place to click or tap an
   edge-flush target — always land on the anchor. Hover changes colour only:
   an earlier hover slide moved the tab out from under a cursor parked at the
   edge and swallowed the first click, so nothing moves on hover any more. */
.jr-lh-tab{position:fixed;right:-4px;top:50%;translate:0 -50%;z-index:70;
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:15px 11px 15px 7px;border-radius:10px 0 0 10px;
  background:#c81a10;color:#fff;
  box-shadow:-3px 0 14px rgba(0,31,63,.26);
  transition:background .2s var(--jr-ease);
  /* overflow:hidden clips the sheen to the rounded shape. The focus ring uses a
     negative outline-offset so it is drawn inside and survives the clip. */
  overflow:hidden}

/* A light band passes down the face. Chosen over a nudge because it moves no
   geometry — the tab already sits a few px over the right edge of the content
   cards on narrow screens, and anything that travels leftwards deepens that.
   Three passes, then it settles; change the count to `infinite` to keep it going.
   At rest the band parks below the visible area, so with animations disabled
   (junior-playful.js injects animation:none for prefers-reduced-motion) nothing
   shows at all. */
.jr-lh-tab::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 40%,rgba(255,255,255,.5) 50%,transparent 60%);
  background-size:100% 300%;background-position:0 130%;
  animation:jrLhSheen 4.5s ease-in-out 3}
@keyframes jrLhSheen{0%,70%{background-position:0 130%}100%{background-position:0 -30%}}
/* Needed explicitly: junior-playful.js kills motion with `*{animation:none}`, and
   the universal selector does not match pseudo-elements, so the sheen would keep
   running for anyone who asked it not to. CSS also means this holds without JS. */
@media(prefers-reduced-motion:reduce){.jr-lh-tab::after{animation:none}}
/* #c81a10, not the brighter #e62117: white on it is 5.8:1 versus 4.6:1, and this
   label is 11px. */
.jr-lh-tab:hover{background:#e62117;color:#fff}
.jr-lh-tab:focus-visible{outline:3px solid #fff;outline-offset:-6px}
.jr-lh-tab-label{writing-mode:vertical-rl;transform:rotate(180deg);
  font:700 11px var(--jr-font);letter-spacing:1px;text-transform:uppercase;white-space:nowrap}
.jr-lh-tab-web{width:15px;height:15px;opacity:.55;flex:none}
.jr-lh-tab .jr-ico{font-size:12px;flex:none}
/* Narrower on small screens, where it shares the edge with the chrome's fixed
   90px bottom nav. At top:50% it clears that by roughly 240px at 390x844. */
@media(max-width:730px){
  .jr-lh-tab{padding:13px 9px 13px 5px;gap:6px}
  .jr-lh-tab .jr-ico{display:none}
  /* The enrol steps are a horizontal snap carousel here. Extra right gutter so
     the last card can clear the tab once scrolled to the end. Note this does not
     move the peeking card at rest, which still passes ~9px under the tab — a
     swipe begun in that 25px strip taps the link instead of scrolling. Judged
     acceptable: it is the extreme screen edge, and cards are swiped from their
     middle. Fixing it fully would need the scroller inset from the page, which
     would visibly off-centre the carousel against the rest of the section. */
  .jr-steps{padding-right:calc(7.5% + 30px)}
}

/* ==========================================================================
   WordPress integration — the only rules with no counterpart in the static
   draft. Everything above renders identically in both.
   ========================================================================== */

/* style.css sets a{color:#005088} and a:hover{color:#e62117} sitewide at (0,1,1).
   Every other Junior link declares its own hover colour, but .jr-store sets
   colour at (0,1,0) with no hover — so without this the App Store and Google
   Play buttons turn red on hover, which never happens in the static draft. */
.jr-store:hover{color:var(--jr-navy)}

/* --wp-admin-offset is set on .kpjlh-page in style.css and resolves to 0 with no
   admin bar. The base rule is .jr-subnav{top:65px} in junior-playful.css; this
   sheet is a declared dependant of it, so it loads after and wins the tie. */
.jr-subnav{top:calc(65px + var(--wp-admin-offset,0px))}
