/* IvyBound Consulting — native CSS, no framework, no Elementor (CLAUDE.md §2).
   Design tokens sampled from the live site's computed styles. */
@import url('/css/fonts.20fa898e.css');

:root{
  /* Brand palette sampled from live. Ink is a near-black rather than pure #000:
     same authority, less glare, and it is what modern type practice uses. */
  --ink:#20242b;
  --ink-soft:#5a616b;
  --ink-dark:#12151a;
  --blue:#0170b9;           /* link / accent blue             */
  --green:#00aa82;          /* brand green — FILLS ONLY       */
  --green-text:#00795d;     /* text-safe green: #00aa82 is 2.7:1 on mint, fails AA */
  --teal:#81d8d0;
  --mint:#c4efdd;
  --coral:#ff6060;
  --yellow:#ffd400;         /* CTA button                     */
  --white:#fff;
  --line:#e6e8ec;
  --bg:#f6f7f9;
  --grad-hero:linear-gradient(45deg,#06aa82 0%,#0b7dbb 100%);
  --grad-card:linear-gradient(#c4efdd 0%,#81d8d0 100%);
  --display:'Saturday Oblique',Georgia,serif;
  --sans:'Montserrat',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --body:'Open Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --wrap:1200px;
  /* one spacing scale drives every band, so rhythm stays even at all widths */
  --sp:clamp(3rem,6vw,5rem);        /* 48px mobile -> 80px desktop */
  --sp-hero:clamp(3.75rem,8vw,7rem);
  --sp-gap:clamp(1rem,3vw,2rem);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:var(--body);color:var(--ink);background:var(--white);
     line-height:1.65;font-size:clamp(1rem,.35vw + .95rem,1.0625rem); /* -> 17px */
     -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 1.5rem}
h1,h2,h3,h4{font-family:var(--sans);color:var(--ink-dark);line-height:1.25;margin:0 0 .6em;font-weight:700}
h1{font-size:clamp(2rem,4vw,3.1rem)}
h2{font-size:clamp(1.6rem,2.8vw,2.4rem)}
h3{font-size:1.15rem}
p{margin:0 0 1.2em}
a{color:var(--blue);text-decoration:none}
a:hover{text-decoration:underline}
img{max-width:100%;height:auto;display:block}
.skip{position:absolute;left:-9999px}
.skip:focus{left:1rem;top:1rem;background:#fff;padding:.75rem 1rem;z-index:200}

/* ---------- header ---------- */
.site-header{background:var(--white);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:100}
.site-header .wrap{display:flex;align-items:center;gap:2rem;min-height:88px}
.logo img{height:52px;width:auto}
.nav{margin-left:auto;display:flex;align-items:center;gap:1.6rem}
.nav>li{list-style:none;position:relative}
.nav a{font-family:var(--sans);font-size:.78rem;font-weight:700;letter-spacing:.06em;
       text-transform:uppercase;color:var(--ink-dark)}
.nav a:hover{color:var(--green);text-decoration:none}
.nav ul{position:absolute;top:100%;left:0;background:#fff;border:1px solid var(--line);
        min-width:230px;padding:.5rem 0;margin:0;list-style:none;display:none;
        box-shadow:0 8px 24px rgba(0,0,0,.08);z-index:110}
.nav li:hover>ul,.nav li:focus-within>ul{display:block}
.nav ul a{display:block;padding:.6rem 1.1rem;text-transform:none;font-weight:600;font-size:.8rem}
.btn-book{background:var(--yellow);color:var(--ink-dark)!important;padding:.8rem 1.5rem;
          border-radius:4px;font-weight:800!important;white-space:nowrap}
.btn-book:hover{background:#ffdc33;text-decoration:none}
.navbtn{display:none}

/* ---------- hero ---------- */
.hero{background:var(--grad-hero);color:#fff;text-align:center;
  /* Heights matched to live's rendered hero, measured at each breakpoint.
     Note mobile is TALLER than tablet: live keeps the headline at 44px on
     phones, so it wraps to more lines. */
  min-height:703px;display:grid;place-items:center;padding:30px 0}
.hero h1{color:#fff;max-width:1170px;margin:0 auto;
  /* live: Montserrat 75px/600 desktop, 44px at <=1024 */
  font-family:var(--sans);font-weight:600;font-size:75px;line-height:1.2}
.hero .chev{display:inline-block;margin-top:2rem;color:#fff;width:46px;height:46px}
.hero .chev svg{width:100%;height:100%;display:block}
.hero .chev:hover{opacity:.75}

/* hand-drawn underline under the last word */
.u-wrap{position:relative;display:inline-block;white-space:nowrap}
.u-svg{position:absolute;left:0;right:0;bottom:-.34em;width:100%;height:.5em;
  overflow:visible;fill:none;stroke:var(--yellow);
  /* preserveAspectRatio="none" squashes a 150-unit-tall viewBox into ~0.5em,
     so a 7-unit stroke renders under 2px. Scaled up to compensate: 7 / (h/150). */
  stroke-width:26;stroke-linecap:round;stroke-linejoin:round}

/* ---------- generic section ---------- */
.section{padding:var(--sp) 0}
.section-alt{background:#f7fbfa}
.section h2{text-align:center}
.lede{text-align:center;max-width:760px;margin:0 auto var(--sp-gap)}

/* ---------- meet ruchi ---------- */
.split{display:grid;grid-template-columns:0.85fr 1.15fr;gap:var(--sp);align-items:center}
.split img{border-radius:6px}

/* ---------- services grid ---------- */
.services{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-gap)}
.svc{flex:0 1 calc(25% - var(--sp-gap) * 3 / 4)}
.svc{text-align:center;text-decoration:none;color:inherit;display:block}
.svc .thumb{aspect-ratio:1;overflow:hidden;border-radius:8px;background:var(--grad-card)}
.svc .thumb img{width:100%;height:100%;object-fit:cover}
.svc h3{margin-top:1rem;font-size:1rem;color:var(--ink-dark);text-transform:uppercase;letter-spacing:.03em}
.svc:hover h3{color:var(--green)}

/* ---------- testimonials ---------- */
.tgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1.5rem}
.tgrid img{border-radius:8px;border:1px solid var(--line);width:100%}

/* ---------- cta band ---------- */
.btn{display:inline-block;background:var(--yellow);color:var(--ink-dark);
     padding:1rem 2.4rem;border-radius:4px;font-family:var(--sans);font-weight:800;
     letter-spacing:.05em;text-transform:uppercase;font-size:.85rem}
.btn:hover{background:#ffdc33;text-decoration:none}
.btn-outline{background:transparent;border:2px solid var(--green-text);color:var(--green-text)}
.btn-outline:hover{background:var(--green);color:#fff}

/* ---------- blog ---------- */
.postlist{list-style:none;padding:0;display:grid;gap:2rem;
          grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}
.postlist li{border:1px solid var(--line);border-radius:8px;padding:1.6rem;background:#fff}
.postlist h2{font-size:1.1rem;text-align:left;margin:0 0 .4rem}
.postlist a{text-decoration:none}
.meta{color:#8a9099;font-size:.8rem;margin:0 0 .6rem}
.crumb{font-size:.85rem;margin-bottom:1rem}
.post{max-width:780px;margin:0 auto;padding:3.5rem 1.5rem}
.post h1{text-align:left}
.prose h2{text-align:left;margin-top:2em;font-size:1.5rem}
.prose img{margin:1.5rem 0;border-radius:6px}
main{min-height:50vh}
main>.wrap{padding-top:var(--sp);padding-bottom:var(--sp)}

/* ---------- footer ---------- */
.site-footer{background:#fff;border-top:1px solid var(--line);padding:var(--sp) 0 0}
.footer-top img{height:56px;width:auto}
.social{display:flex;gap:1.1rem}
.social a{color:var(--ink);display:inline-flex}
.social a:hover{color:var(--green)}
.newsletter{background:#f7fbfa;margin-top:0;padding:var(--sp) 0}
.newsletter p{text-align:center;max-width:680px;margin:0 auto 1.5rem}
.nform{display:grid;gap:.75rem;max-width:1000px;margin:0 auto;
  grid-template-columns:1fr 1fr 1fr 1fr auto}      /* desktop + tablet: one line */
.nform input,.nform select{font-family:var(--body);font-size:.9rem;padding:.7rem .9rem;
  border:1px solid var(--line);border-radius:4px;background:#fff;color:var(--ink);
  min-width:0;width:100%}
.nform button{font-family:var(--sans);font-weight:800;text-transform:uppercase;font-size:.8rem;
  letter-spacing:.05em;background:var(--yellow);color:var(--ink-dark);border:0;
  padding:.8rem 1.8rem;border-radius:4px;cursor:pointer}
.nform button:hover{background:#ffdc33}
.hp{position:absolute;left:-9999px}
.legal{border-top:1px solid var(--line);padding:1.25rem 0;text-align:center}
.legal a{color:var(--ink);font-family:var(--sans);font-size:.72rem;font-weight:700;
         letter-spacing:.08em;text-transform:uppercase;margin:0 .9rem}
.disclaimer{text-align:center;font-size:.78rem;color:#8a9099;padding:0 0 2rem;margin:0}

@media (max-width:1023px){
  /* 8 services in a 3-up grid leaves an orphan row of 2 that reads as
     unfinished; flex-wrap with justify-content:center balances the last row. */
  .svc{flex-basis:calc(33.333% - var(--sp-gap) * 2 / 3)}
}
@media (max-width:900px){
  .split{grid-template-columns:1fr;gap:var(--sp-gap)}
  .navbtn{display:block;margin-left:auto;width:26px;height:20px;cursor:pointer;position:relative}
  .navbtn span,.navbtn span::before,.navbtn span::after{content:'';position:absolute;left:0;
    width:26px;height:2px;background:var(--ink-dark)}
  .navbtn span{top:9px}.navbtn span::before{top:-8px}.navbtn span::after{top:8px}
  .nav{display:none;width:100%;flex-direction:column;align-items:flex-start;gap:.9rem;
       padding:1rem 0 1.5rem;margin-left:0}
  #navtoggle:checked~.nav{display:flex}
  .nav ul{position:static;display:block;border:0;box-shadow:none;padding-left:1rem}
  .site-header .wrap{flex-wrap:wrap;min-height:70px}
}
@media (max-width:639px){
  /* two form fields per row; submit spans the full width beneath them */
  .nform{grid-template-columns:1fr 1fr}
  .nform button{grid-column:1 / -1}
  .services{gap:1rem}
  .svc{flex-basis:calc(50% - .5rem)}   /* phone: 2-up */
  .svc h3{font-size:.82rem}
}

/* ---------- testimonial carousel ----------
   CSS scroll-snap does the work: native swipe + momentum on touch, trackpad
   scroll on desktop, keyboard on the focusable track. Arrows are progressive
   enhancement (hidden until JS unhides them), so it works with JS off. */
.carousel{position:relative;display:flex;align-items:center;gap:.5rem;
          max-width:var(--wrap);margin:0 auto;padding:0 1.5rem}
.ctrack{display:flex;gap:1.5rem;list-style:none;margin:0;padding:.5rem 0 1.5rem;
        overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
        scrollbar-width:none;-webkit-overflow-scrolling:touch;flex:1}
.ctrack::-webkit-scrollbar{display:none}
.ctrack:focus-visible{outline:2px solid var(--green);outline-offset:4px;border-radius:8px}

.tcard{flex:0 0 85%;scroll-snap-align:center;background:#fff;
       border:1px solid var(--line);border-left:6px solid var(--green);
       border-radius:10px;padding:1.75rem;display:flex;flex-direction:column;
       box-shadow:0 2px 10px rgba(0,0,0,.05)}
.tcard .stars{color:var(--yellow);font-size:1.15rem;letter-spacing:.12em;margin:0 0 .75rem}
.tcard blockquote{margin:0 0 1.25rem;padding:0;border:0;font-size:.95rem;
                  line-height:1.75;color:var(--ink);flex:1}
.tcard .attrib{margin:0;font-family:var(--sans);font-size:.8rem;font-weight:700;
               color:var(--ink-dark);border-top:1px solid var(--line);padding-top:.9rem}
.tcard .attrib span{color:var(--green-text)}

.cbtn{flex:0 0 auto;width:44px;height:44px;border-radius:50%;border:1px solid var(--line);
      background:#fff;color:var(--ink-dark);font-size:1.6rem;line-height:1;cursor:pointer;
      display:grid;place-items:center;box-shadow:0 2px 8px rgba(0,0,0,.08)}
.cbtn:hover{background:var(--green);color:#fff;border-color:var(--green)}
.cbtn:disabled{opacity:.3;cursor:default}
.cbtn:disabled:hover{background:#fff;color:var(--ink-dark);border-color:var(--line)}

@media (min-width:640px){ .tcard{flex-basis:calc(50% - .75rem)} }
@media (min-width:1024px){ .tcard{flex-basis:calc(33.333% - 1rem)} }

@media (prefers-reduced-motion:reduce){ .ctrack{scroll-behavior:auto} }

/* Native CSS carousel (Chrome 135+): real arrows and dots with no JS at all.
   Everything above already works without this — pure progressive enhancement. */
@supports selector(::scroll-marker){
  .ctrack{anchor-name:--ctrack}
  .ctrack::scroll-marker-group{position-area:block-end;display:flex;
    justify-content:center;gap:.5rem;margin-top:.5rem}
  .tcard::scroll-marker{content:'';width:9px;height:9px;border-radius:50%;
    background:var(--line);border:0}
  .tcard::scroll-marker:target-current{background:var(--green)}
}

/* Arrows are for pointer users. On phones they steal ~88px of a 390px viewport
   and squeeze the cards, while swipe already works — so hide them there. */
@media (max-width:639px){
  .carousel{padding:0 0 0 1.5rem}
  .cbtn{display:none}
  .ctrack{padding-right:1.5rem}
}

/* sticky header would otherwise cover the target when jumping to #anchor */
section[id],[id]{scroll-margin-top:100px}

/* round university crest badge on each testimonial card */
.tcard{position:relative}
/* Crest. The logo alone -- no disc, no ring, no shadow. Each mark already has
   its own silhouette and enclosing it in a white circle just adds a shape the
   designer did not draw.
   object-fit is contain, not cover: cover crops a wide wordmark like MIT to a
   square and cuts its ends off. Sized well above 64px because several of these
   are engraved seals whose micro-text is unreadable below ~90px. */
.crest{position:absolute;top:1.75rem;right:1.75rem;width:96px;height:96px;
       object-fit:contain}
/* The crest shares the stars row rather than sitting in the quote. Wrapping text
   around it only works in a wide column; in a ~290px card it cut the opening
   lines to half width. Giving the stars row the crest's height reserves a proper
   header band, so the quote below runs full measure at every size -- 228px of a
   291px card at 390px wide, the same as it was at 64px.
   That is why one size works everywhere and there are no breakpoints here:
   widening the crest costs the quote nothing, it only makes the stars row
   taller. 96px is what the engraved seals need to stay legible. */
.tcard .stars{min-height:96px;display:flex;align-items:center;margin:0 0 .35rem}


/* autoplay pause/play control — required whenever motion runs >5s (WCAG 2.2.2) */
/* 34px was below a usable tap target. WCAG 2.5.8 asks 24px minimum and 44px is
   the practical floor on touch -- and this is the control that stops autoplay,
   so it has to be reachable in a hurry. */
.cplay{position:absolute;right:1.5rem;bottom:-.25rem;width:44px;height:44px;
       border-radius:50%;border:1px solid var(--line);background:#fff;
       color:var(--ink-dark);cursor:pointer;display:none;place-items:center;
       font-size:.7rem;line-height:1;padding:0}
.cplay[data-shown]{display:grid}
.cplay:hover{background:var(--green);color:#fff;border-color:var(--green)}


/* check glyphs left where Font Awesome icon-font bullets used to be */
.tick{color:var(--green);font-weight:700;margin-right:.4em}

/* legal links wrapped awkwardly on narrow screens */
@media (max-width:480px){
  .legal a{display:block;margin:.35rem 0}
  .disclaimer{padding-inline:1.5rem}
}

/* ---------- college carousel: two rows, scrolling horizontally ----------
   grid-auto-flow:column with two rows fills top-to-bottom then left-to-right,
   so the pair in each column stays together as you scroll. */
.ctrack-2row{display:grid;grid-auto-flow:column;grid-template-rows:repeat(2,auto);
             gap:1.25rem;align-items:start}
.ccard{scroll-snap-align:start;width:230px;margin:0}
.ccard img{width:100%;aspect-ratio:3/2;object-fit:cover;border-radius:8px;
           border:1px solid var(--line);background:var(--bg-alt)}
.ccard h3{font-size:.85rem;margin:.6rem 0 0;font-family:var(--sans);font-weight:600;
          color:var(--ink-dark);line-height:1.35}
.ccarousel .ctrack{padding-bottom:.5rem}

@media (min-width:1024px){ .ccard{width:260px} }
@media (max-width:639px){ .ccard{width:60vw;max-width:250px} }


/* ---------- hero background video ----------
   The gradient stays as the base layer, so the hero looks finished before the
   video loads, if it never loads, or under prefers-reduced-motion. */
.hero{position:relative;overflow:hidden;isolation:isolate}
.hero>.wrap{position:relative;z-index:2}
.hero-video{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:0;
            transition:opacity .6s ease}
.hero.has-video .hero-video{opacity:1}
.hero-video iframe{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  /* cover the box at 16:9 whichever way the viewport is shaped */
  width:100vw;height:56.25vw;min-height:100%;min-width:177.78vh;border:0}
.hero-overlay{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:var(--grad-hero);opacity:1}
/* Kept deliberately heavy. The clip is decorative, and a thin overlay lets
   YouTube's own UI (an error, a region block, a "confirm you're not a bot"
   interstitial) show through behind the headline. This keeps it as texture. */
.hero.has-video .hero-overlay{opacity:.88}
@media (prefers-reduced-motion:reduce){
  .hero-video{display:none}
  .hero-overlay{opacity:1}
}

/* ---------- hero responsive geometry (values sampled from live) ---------- */
@media (max-width:1024px){
  .hero{min-height:473px}
  .hero h1{font-size:44px}
}
@media (max-width:640px){
  .hero{min-height:587px;padding:24px 0}
  .hero h1{font-size:44px;line-height:1.22}   /* live keeps 44px on phones */
  .hero .chev{width:38px;height:38px;margin-top:1.25rem}
  .u-svg{stroke-width:34;bottom:-.30em}  /* box is shorter on phones, so scale up */
}

/* display headings are BLUE on live, not navy: 54px #007dbb and 68px #0B7DBB */
h2.script{color:#0b7dbb}
#meet-ruchi h2.script{color:#007dbb}

/* ============================================================================
   BLOCK SYSTEM
   Brand values (colour, type family, button shape) are taken from the live
   site. Everything structural — line-height, spacing rhythm, focus states,
   fluid sizing — is rebuilt to current practice rather than copied.
   Notably NOT copied: line-height:0.1em on the display headings, which
   collapses the line box and overlaps neighbouring content the moment a
   heading wraps.
   ========================================================================= */

/* ---- display headings ---------------------------------------------------- */
/* h1 was missing from this list, so an h1.script silently fell back to the
   generic sans h1 rule and rendered in Montserrat. Any heading level can carry
   the display face. */
h1.script,h2.script,h3.script{font-family:var(--display);font-weight:600;font-style:oblique;
  color:#0b7dbb;line-height:1.3;
  /* Live sets 0.1em. At the desktop 68px that is 6.8px and pulls words apart,
     but on mobile it is exactly what makes the script read as airy rather than
     cramped -- so scale it with the viewport instead of picking one value.
     clamp: ~3.4px at 390px (live: 4px), easing to ~4px at 1280. */
  letter-spacing:.1em;                                  /* live's value; correct on mobile */
  font-size:clamp(2.5rem,1.5rem + 4.1vw,4.25rem);margin:0 0 .5em}  /* live: 40px @390, 68px @1280 */
/* At the desktop 68px, .1em is 6.8px and starts pulling words apart. Ease it
   back once there is room, rather than compromising the mobile look. */
@media (min-width:768px){ h1.script,h2.script,h3.script{letter-spacing:.075em} }
#meet-ruchi h2.script{color:#007dbb;letter-spacing:.06em;
  font-size:clamp(1.9rem,1.1rem + 3.16vw,3.375rem)}  /* live: 54px @1280 */

/* ---- buttons: yellow pill, as on live ------------------------------------ */
.btn,.btn-book,.nform button{
  display:inline-block;background:var(--yellow);color:#333;
  font-family:var(--body);font-weight:700;text-transform:uppercase;
  /* live: 20px at 390px */
  font-size:clamp(1.05rem,.95rem + .35vw,1.25rem);
  letter-spacing:.02em;line-height:1;border:0;border-radius:999px;cursor:pointer;
  padding:.85em 1.6em;text-decoration:none;
  transition:background .18s ease,transform .18s ease}
.btn:hover,.btn-book:hover,.nform button:hover{background:#ffdf3d;text-decoration:none;color:#333}
.btn:active,.btn-book:active,.nform button:active{transform:translateY(1px)}
.btn:focus-visible,.btn-book:focus-visible,.nform button:focus-visible,
a:focus-visible,summary:focus-visible,button:focus-visible{
  outline:3px solid #0b7dbb;outline-offset:3px;border-radius:999px}
/* live: 20px at 390px, easing up on wider screens */
.btn-lg{font-size:clamp(1.25rem,1.1rem + .45vw,1.4rem);padding:.75em 1.5em}
.btn-book{font-size:.95rem;padding:.75em 1.35em}
@media (prefers-reduced-motion:reduce){
  .btn,.btn-book,.nform button{transition:none}
}

/* ---- hero ---------------------------------------------------------------- */
/* live runs the gradient at 0.65 over the video; heavier than that and the
   footage disappears */
.hero.has-video .hero-overlay{opacity:.65}

/* ---- what we do: mint wash, as on live ----------------------------------- */
#what-we-do{background:linear-gradient(0deg,#c4efdd 0%,#81d8d0 100%);
  background-color:#eefaf6;position:relative;isolation:isolate}
#what-we-do::before{content:'';position:absolute;inset:0;z-index:-1;
  background:#fff;opacity:.7}          /* live uses the gradient at 0.3 */
.svc h3{font-family:var(--sans);font-weight:600;color:var(--green-text);
  font-size:clamp(1rem,.5rem + .6vw,1.3125rem);   /* live: 21px */
  text-transform:none;letter-spacing:0;line-height:1.3;margin-top:.9rem}
.svc:hover h3{color:#005c47}


/* ---------- schedule block ------------------------------------------------ */
.schedule{background:linear-gradient(180deg,#f4fbf9 0%,#e8f7f3 100%);padding:var(--sp) 0 0}
.schedule-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.5rem,4vw,4rem);
  align-items:center}
.schedule-main{text-align:center;display:flex;flex-direction:column;align-items:center;gap:1.5rem}
.schedule-portrait{width:clamp(180px,20vw,288px);aspect-ratio:1;border-radius:50%;
  object-fit:cover;box-shadow:0 6px 24px rgba(0,0,0,.10)}
.schedule-copy{font-family:var(--sans);font-weight:600;color:#0170b9;margin:0;
  font-size:clamp(1.125rem,.6rem + .8vw,1.5rem);line-height:1.4;max-width:34ch}
/* deliberate emphasis run, as on live */
.schedule-copy em{font-style:normal;color:#e02020}
.schedule-aside img{width:100%;max-width:366px;margin-inline:auto;height:auto}

.back-to-top{text-align:center;margin:0;padding:2.25rem 0 var(--sp)}
.back-to-top a{display:inline-flex;flex-direction:column;align-items:center;gap:.55rem;
  font-family:var(--body);font-size:1rem;color:#7a7a7a;text-decoration:none}
.back-to-top a:hover{color:var(--ink-dark)}
.btt-icon{display:grid;place-items:center;width:44px;height:44px;border-radius:6px;
  background:#8fdcd2;color:#12151a;font-size:1.15rem;line-height:1;
  transition:background .18s ease}
.back-to-top a:hover .btt-icon{background:#6fd0c3}

@media (max-width:860px){
  .schedule-grid{grid-template-columns:1fr}
  .schedule-aside{order:-1}
  .schedule-aside img{max-width:280px}
}

/* ---------- footer: logo + social on one row, teal circles ---------------- */
.footer-top{display:flex;flex-direction:row;align-items:center;justify-content:center;
  gap:clamp(1.5rem,5vw,4rem);flex-wrap:wrap;text-align:left}
.footer-logo img{height:56px;width:auto}
.social{display:flex;gap:.75rem;list-style:none;margin:0;padding:0}
.social a{display:grid;place-items:center;width:42px;height:42px;border-radius:50%;
  background:#8fdcd2;color:#fff;transition:background .18s ease,transform .18s ease}
.social a:hover{background:var(--green-text);transform:translateY(-2px)}
.social svg{width:19px;height:19px}
@media (prefers-reduced-motion:reduce){ .social a{transition:none} }

/* newsletter: five fields + submit on one line, green-bordered inputs */
.nform{display:grid;gap:.6rem;max-width:1060px;margin:0 auto;
  grid-template-columns:repeat(5,1fr) auto}
.nform input,.nform select{font-family:var(--body);font-size:.95rem;padding:.7rem .85rem;
  border:1px solid #06aa82;border-radius:6px;background:#fff;color:var(--ink);
  min-width:0;width:100%}
.nform input::placeholder{color:#5a616b}
.nform input:focus-visible,.nform select:focus-visible{outline:3px solid #0b7dbb;
  outline-offset:2px;border-radius:6px}
.nform button{text-transform:none;font-size:1rem;padding:.7em 1.6em}

.legal .sep{display:inline-block;width:1px;height:12px;background:#c9ced6;
  margin:0 .35rem;vertical-align:middle}

@media (max-width:1023px){
  .nform{grid-template-columns:repeat(2,1fr)}
  .nform button{grid-column:1 / -1}
}
@media (max-width:520px){
  .nform{grid-template-columns:1fr}
}

/* ---------- meet ruchi block ---------------------------------------------
   Desktop: portrait beside a left-aligned column.
   Mobile:  portrait fills the column width, and the heading and CTA centre to
            match every other section heading on the page. Body copy stays
            left-aligned — centred paragraphs are harder to read. */
#meet-ruchi .mr-portrait{width:100%;height:auto}
#meet-ruchi h2.script{text-align:left}
#meet-ruchi .mr-cta{margin-bottom:0}

@media (max-width:900px){
  #meet-ruchi .split{gap:1.75rem}
  #meet-ruchi .mr-portrait{width:100%;max-width:none}
  #meet-ruchi h2.script{text-align:center}
  #meet-ruchi .mr-cta{text-align:center}
}

/* Phone mockup is decorative: it costs a full screen of scroll on a phone and
   says nothing the copy doesn't. Hidden below the two-column breakpoint. */
@media (max-width:860px){
  .schedule-aside{display:none}
  .schedule-grid{grid-template-columns:1fr}
}

/* ---------- page hero (inner pages) ---------------------------------------
   Photo banner with a bottom-weighted scrim so the type stays legible over
   whatever part of the image sits behind it. Script title + sans subtitle,
   matching live. Content differs per page, so the markup lives in the page and
   only the styling is shared. */
.page-hero{position:relative;isolation:isolate;min-height:clamp(430px,44vw,580px);
  display:grid;place-items:center;text-align:center;overflow:hidden;
  background:#1b2a2e center/cover no-repeat}
.page-hero::after{content:'';position:absolute;inset:0;z-index:1;
  background:linear-gradient(rgba(2,1,1,0) 0%,rgba(0,0,0,.92) 67%);opacity:.72}
.page-hero .wrap{position:relative;z-index:2;padding-block:2rem}
.page-hero .ph-title{font-family:var(--display);font-weight:700;font-style:normal;
  color:#63d8ce;line-height:1.05;margin:0 0 .1em;
  font-size:clamp(3rem,1.4rem + 6.45vw,6.5625rem)}   /* live: 105px @1280 */
.page-hero .ph-sub{font-family:var(--sans);font-weight:600;color:#fff;
  line-height:1.15;margin:0;
  font-size:clamp(1.6rem,.8rem + 3.3vw,3.4375rem)}   /* live: 55px @1280 */



/* ---------- two-part section heading -------------------------------------- */
.dual-head{text-align:center;margin-bottom:1.5rem}
.dual-head .dh-script{display:block;font-family:var(--display);font-weight:600;
  font-style:oblique;color:#0b7dbb;line-height:1.15;letter-spacing:.02em;
  font-size:clamp(2.1rem,1.2rem + 3.97vw,4.375rem)}  /* live: 70px @1280 */
.dual-head .dh-sans{display:block;font-family:var(--sans);font-weight:600;
  color:var(--green-text);line-height:1.25;margin-top:.15em;
  font-size:clamp(1.25rem,.7rem + 1.5vw,2rem)}        /* live: 32px, #05aa82 */


@media (max-width:860px){
  h1,h2,h3,
  .ph-title,.ph-sub,.dual-head,.dh-script,.dh-sans,
                /* prose stays ranged left */
    .lead-copy{text-align:center}
}

/* Display headings centre everywhere except the Meet Ruchi block on desktop,
   where the portrait sits beside a ranged-left column. */
.u-display{text-align:center}
@media (min-width:901px){ #meet-ruchi h2.u-display{text-align:left} }

/* ============================================================================
   PACKAGE TABS
   Desktop: both packages side by side, tab strip hidden.
   Mobile:  a real ARIA tablist, one panel at a time (static/js/tabs.54d50f73.js).
   ========================================================================= */
.pkg-tabs{margin-top:2rem}
.pkg-tablist{display:none}
.pkg-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.5rem,3vw,3rem);
  align-items:start}

.pkg-panel{background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:clamp(1.5rem,2.5vw,2.5rem);box-shadow:0 2px 16px rgba(0,0,0,.05)}
.pkg-head{text-align:center;margin-bottom:1.25rem}
.pkg-title{font-family:var(--sans);font-weight:600;color:#333;line-height:1.2;
  font-size:clamp(1.3rem,.8rem + 2.125vw,2.5rem);margin:0 0 .3rem}  /* live: 40px */
.pkg-aud{font-family:var(--body);font-weight:600;color:var(--green-text);margin:0;
  font-size:clamp(1rem,.7rem + .92vw,1.4375rem)}                    /* live: 23px */
.pkg-panel > p{text-align:left}
.rm-head{font-family:var(--display);font-weight:600;font-style:oblique;
  color:#0170b9;text-align:center;line-height:1.2;margin:2rem 0 1.25rem;
  font-size:clamp(1.6rem,1rem + 2.66vw,3.125rem)}                   /* live: 50px */
.pkg-cta{text-align:center;margin:1.75rem 0 0}

/* ---- roadmap: a confident, colour-coded journey -------------------------
   Each step is a GRID, not absolute positioning. Row 1 is [badge | ribbon] with
   align-items:center, so the circle and the bar are centred to each other by
   the layout rather than by hand-tuned offsets. Row 2 is the description, which
   therefore always clears both.
   The earlier version positioned the badge absolutely and let the description
   flow underneath it — the circle overlapped the first line of text and the
   ribbon never lined up with the circle. */
.roadmap{list-style:none;margin:0;padding:.25rem 0;counter-reset:milestone}
.roadmap li{position:relative;counter-increment:milestone;
  display:grid;grid-template-columns:var(--rm-badge,2.9rem) 1fr;
  column-gap:.9rem;row-gap:.6rem;align-items:center;
  margin-bottom:1.9rem}
.roadmap li:last-child{margin-bottom:0}

/* row 1, column 1 — the numbered badge */
.roadmap li::before{content:counter(milestone,decimal-leading-zero);
  grid-column:1;grid-row:1;
  width:var(--rm-badge,2.9rem);height:var(--rm-badge,2.9rem);border-radius:50%;
  display:grid;place-items:center;
  font-family:var(--sans);font-weight:800;font-size:.88rem;
  color:#fff;background:#0d3b66;font-variant-numeric:tabular-nums;
  box-shadow:0 0 0 5px var(--rm-tint,#d7f5ea)}

/* row 1, column 2 — the tinted stage ribbon */
.rm-title{grid-column:2;grid-row:1;margin:0;
  font-family:var(--sans);font-weight:800;color:#0d3b66;
  font-size:clamp(1.02rem,.75rem + .65vw,1.28rem);line-height:1.3;
  padding:.5em 2.1em .5em .85em;
  background:var(--rm-tint,#d7f5ea);
  clip-path:polygon(0 0,calc(100% - 16px) 0,100% 50%,calc(100% - 16px) 100%,0 100%);
  border-radius:5px 0 0 5px}

/* row 2 — description, clear of both */
.rm-desc{grid-column:2;grid-row:2;margin:0;
  font-size:.98rem;line-height:1.62;color:var(--ink);overflow-wrap:anywhere}

/* the spine, drawn from under the badge to the next step */
.roadmap li::after{content:'';position:absolute;
  left:calc(var(--rm-badge,2.9rem) / 2 - 1.5px);
  top:calc(var(--rm-badge,2.9rem) + 5px);bottom:calc(-1.9rem + 5px);
  width:3px;background:#0d3b66;opacity:.25}
.roadmap li:last-child::after{display:none}

/* stage tints rotate so consecutive steps read as distinct stages */
.roadmap li:nth-child(3n+1){--rm-tint:#d7f5ea}
.roadmap li:nth-child(3n+2){--rm-tint:#d9ecfb}
.roadmap li:nth-child(3n+3){--rm-tint:#e8e2f9}

/* the last milestone is the destination, not another step */
.roadmap li:last-child::before{content:'';background:#0d3b66;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s7-6.2 7-11a7 7 0 1 0-14 0c0 4.8 7 11 7 11z'/%3E%3Ccircle cx='12' cy='10' r='2.4'/%3E%3C/svg%3E");
  background-size:1.35rem;background-position:center;background-repeat:no-repeat}

/* ---- what's included: mint card, blue ticks ------------------------------ */
.included{list-style:none;margin:0;padding:1.5rem 1.5rem 1.5rem 1.25rem;
  background:#fff;border:1px solid #cfeee7;border-left:5px solid #0b7dbb;
  border-radius:10px;box-shadow:0 1px 3px rgba(16,40,50,.05)}
.included li{position:relative;padding-left:2.4rem;margin-bottom:1rem;
  line-height:1.55}
.included li:last-child{margin-bottom:0}
.included li::before{content:'';position:absolute;left:0;top:.15rem;
  width:22px;height:22px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230170b9' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
  background-size:contain;background-repeat:no-repeat}

/* ---- mobile: real tabs --------------------------------------------------- */
@media (max-width:900px){
  /* Option A: the active tab and its panel are one continuous shape — same
     surface, same border, seam between them removed. That is what makes the
     panel read as belonging to the tab. */
  .pkg-tablist{display:flex;gap:.25rem;padding:0 .2rem}
  .pkg-tab{flex:1;font-family:var(--sans);font-weight:600;font-size:.8rem;
    line-height:1.25;padding:.75rem .5rem;cursor:pointer;
    border:1px solid var(--line);border-bottom:0;border-radius:11px 11px 0 0;
    background:#f2f6f8;color:var(--ink-soft);position:relative;top:1px;
    transition:background .16s ease,color .16s ease,border-color .16s ease}
  .pkg-tab[aria-selected="true"]{background:#eafaf5;color:#0f4f47;
    border-color:#cfeee7;box-shadow:0 -2px 0 #63d8ce inset}
  .pkg-tab:focus-visible{outline:3px solid #0b7dbb;outline-offset:2px}
  .pkg-grid{grid-template-columns:1fr}
  .pkg-panel{border:1px solid #cfeee7;border-radius:0 0 12px 12px;
    background:#eafaf5;box-shadow:none;padding:1.25rem 1rem 1.5rem}
}

@media (prefers-reduced-motion:reduce){ .pkg-tab{transition:none} }

/* ---------- colleges block: heading, claim and carousel as one unit --------
   The success-rate heading and claim used to sit loose on the page above the
   carousel, so the spacing between them was arbitrary and differed per page.
   They belong to this block and are spaced with it. */
.colleges-block{background:linear-gradient(180deg,#f7fbfa 0%,#eef8f5 100%)}
.colleges-intro{text-align:center;margin-bottom:clamp(1.75rem,3vw,2.75rem)}
.colleges-intro h2.script{margin:0 0 .35em}
.colleges-intro .claim{margin:0 auto .9em;max-width:46ch;text-wrap:balance}
.colleges-sub{font-family:var(--sans);font-weight:700;color:var(--ink-dark);
  line-height:1.25;margin:0;text-wrap:balance;
  font-size:clamp(1.15rem,.75rem + 1.1vw,1.75rem)}

/* ---------- high school: single package, no tabs -------------------------- */
.pkg-single{max-width:820px;margin-inline:auto}

/* ---------- school types: native <details> (§6) ---------------------------
   Five blocks of ~250 words each. Stacked open that is 1,250 words of wall;
   collapsed, the five options are scannable and the reader opens what applies. */
.schooltypes{max-width:820px;margin-inline:auto;border-top:1px solid var(--line)}
.schooltype{border-bottom:1px solid var(--line)}
.schooltype > summary{cursor:pointer;list-style:none;padding:1.15rem 3rem 1.15rem 0;
  position:relative;font-family:var(--sans);font-weight:700;color:var(--ink-dark);
  font-size:clamp(1.05rem,.75rem + .8vw,1.625rem)}      /* live: 26px */
.schooltype > summary::-webkit-details-marker{display:none}
.schooltype > summary::after{content:'';position:absolute;right:.6rem;top:1.65rem;
  width:11px;height:11px;border-right:2.5px solid var(--green-text);
  border-bottom:2.5px solid var(--green-text);transform:rotate(45deg);
  transition:transform .2s ease}
.schooltype[open] > summary::after{transform:rotate(-135deg)}
.schooltype > summary:hover{color:var(--green-text)}
.schooltype > summary:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.st-body{padding:0 0 1.5rem}
.st-body p{margin:0 0 1rem;max-width:58ch}
.st-body p:last-child{margin-bottom:0}
@media (prefers-reduced-motion:reduce){ .schooltype > summary::after{transition:none} }

/* ---------- FAQ accordion ---------------------------------------------------
   Same interaction as .schooltype above, reused rather than reinvented: the
   summary was unstyled and collapsed to a 28px tap target. */
.acc{border-bottom:1px solid var(--line);max-width:820px;margin-inline:auto}
.acc:first-of-type{border-top:1px solid var(--line)}
.acc > summary{cursor:pointer;list-style:none;padding:1.15rem 3rem 1.15rem 0;
  position:relative;font-family:var(--sans);font-weight:700;color:var(--ink-dark);
  font-size:clamp(1rem,.8rem + .5vw,1.25rem)}
.acc > summary::-webkit-details-marker{display:none}
.acc > summary::after{content:'';position:absolute;right:.6rem;top:1.5rem;
  width:11px;height:11px;border-right:2.5px solid var(--green-text);
  border-bottom:2.5px solid var(--green-text);transform:rotate(45deg);
  transition:transform .2s ease}
.acc[open] > summary::after{transform:rotate(-135deg)}
.acc > summary:hover{color:var(--green-text)}
.acc > summary:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.acc-body{padding:0 0 1.5rem}
.acc-body p{margin:0 0 1rem;max-width:58ch}
.acc-body p:last-child{margin-bottom:0}
@media (prefers-reduced-motion:reduce){ .acc > summary::after{transition:none} }

/* ---------- admitted-schools list ----------------------------------------- */
#hs-success{text-align:center}
.schoollist{list-style:none;margin:0 auto;padding:0;max-width:900px;
  display:grid;gap:.6rem;grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.schoollist li{background:#fff;border:1px solid #cfeee7;border-radius:999px;
  padding:.6rem 1rem;font-family:var(--sans);font-weight:600;font-size:.92rem;
  color:var(--ink-dark)}
.schoollist-more{margin:1.1rem 0 0;color:var(--ink-soft);font-style:italic}

/* ---------- mobile: stop giving the text away to nested padding -----------
   At 390px the roadmap copy was rendering 206px wide — 53% of the viewport —
   because .wrap, .pkg-panel and .roadmap each took their own inset. */
@media (max-width:640px){
  .wrap{padding-inline:1rem}
  .pkg-panel{padding-inline:.75rem}
  /* Row 1 keeps [badge | ribbon]; row 2 spans BOTH columns so the description
     uses the full width instead of sitting in a 60%-wide gutter. */
  .roadmap li{--rm-badge:2.6rem;column-gap:.7rem;margin-bottom:1.6rem}
  .rm-desc{grid-column:1 / -1}
  /* no spine on mobile — the full-width description would run through it */
  .roadmap li::after{display:none}
}

/* ============================================================================
   MEASURE — all three modes
   Reading measure sits best at 45–75 characters. Audited with tests/measure.mjs:
   the page intro was running 135 chars at 1280px because an earlier regex-based
   CSS cleanup deleted this rule's base declaration, leaving only its
   media-query override. The checklist was 29 chars on mobile — too tight —
   because three nested paddings stacked up.
   ========================================================================= */
.lead-copy{max-width:54ch;margin-inline:auto;text-align:center}
.rm-desc{max-width:58ch}
.included li{max-width:56ch}
.pkg-panel > p{max-width:58ch;margin-inline:auto}

@media (max-width:640px){
  /* recover the checklist measure: trim the card and the tick gutter */
  .included{padding:1.15rem 1rem 1.15rem .9rem}
  .included li{padding-left:1.9rem;margin-bottom:.85rem}
  .included li::before{width:19px;height:19px}
}

/* measure caps for the homepage blocks, audited with tests/measure-home.mjs */
.lede{max-width:54ch}                      /* was 760px -> 89 chars at 1280 */
#meet-ruchi .mr-copy p{max-width:57ch}     /* was 84 chars when stacked at 768 */

/* ---------- shop: product cards ------------------------------------------
   §11 required a price on every card. Live shows none — the only "$350" on the
   page is an hourly add-on rate, so every product sent you to Kajabi checkout
   to find out what it cost. Prices below were read off the live offers. */
.page-hero--shop .ph-title{font-size:clamp(3.5rem,1.5rem + 8.6vw,8.75rem)}  /* live: 140px */

.products{display:grid;gap:clamp(1.25rem,2.5vw,2rem);align-items:stretch;
  /* two columns, not auto-fit: four content-heavy cards wrap 3+1 at three
     columns, leaving an orphan and a very narrow measure. */
  grid-template-columns:1fr}
@media (min-width:900px){ .products{grid-template-columns:repeat(2,1fr)} }
.product{background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:clamp(1.35rem,2vw,2rem);box-shadow:0 2px 14px rgba(16,40,50,.05);
  display:flex;flex-direction:column;height:100%}
.prod-head{border-bottom:1px solid var(--line);padding-bottom:.9rem;margin-bottom:1rem}
.prod-name{font-family:var(--sans);font-weight:700;color:#0d3b66;line-height:1.25;
  font-size:clamp(1.15rem,.8rem + 1vw,1.6rem);margin:0 0 .45rem}
.prod-price{margin:0;font-family:var(--sans);line-height:1.3;
  display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap}
.prod-price strong{font-size:clamp(1.4rem,1rem + 1.4vw,2.1rem);font-weight:800;
  color:var(--green-text);font-variant-numeric:tabular-nums}
.prod-pack{font-family:var(--body);font-weight:600;font-size:.85rem;color:var(--ink-soft)}
.prod-body{flex:1}
.prod-body p{max-width:54ch}
.prod-body .included{margin-top:1rem}
.prod-cta{margin:1.5rem 0 0}
.product--free{margin-top:clamp(1.25rem,2.5vw,2rem);
  background:linear-gradient(180deg,#f2fbf8 0%,#e8f7f3 100%);border-color:#cfeee7}
/* Sub-head under the script statement heading. Sans, mid-weight: it labels the
   grid below it rather than competing with the script line above. */
.benefits-lead{font-family:var(--sans);font-weight:600;font-size:clamp(1.35rem,1rem + 1.6vw,2.2rem);
  text-align:center;margin:0 0 1.4em;color:var(--ink-dark)}
/* Short utility pages: 404, thank-you. */
.notice{text-align:center;max-width:40rem;margin-inline:auto}
.notice .btn{margin-top:2rem}
.social-handles{list-style:none;margin:.5rem 0 1rem;padding:0;
  display:grid;gap:.3rem}
.social-handles .sm-net{font-weight:700}

/* ---------- reading measure -------------------------------------------------
   Two different widths, and conflating them is the usual mistake:

     LAYOUT width  -- how far the page furniture may spread. One value, --wrap
                      (1200px), used everywhere. Full-bleed is reserved for
                      colour bands and hero images.
     TEXT measure  -- how long a line of prose may get before the eye loses the
                      return sweep. 45-75 characters regardless of how wide the
                      container happens to be.

   Most prose here is already capped by a component rule. This catches the case
   nothing else does: a paragraph sitting as a direct child of a band's .wrap,
   which is how the ported Elementor pages are built. Those ran the full 1152px
   -- 123 characters a line on /coaching, near double the readable maximum. */
.band > .wrap > p{max-width:62ch}
.band > .wrap[style*="text-align:center"] > p,
.band > .wrap > p.centered{margin-inline:auto}

/* ---------- section bands ---------------------------------------------------
   A three-tone rhythm, applied by wrapping a section rather than by styling its
   contents. The rule that keeps it from becoming stripes-for-the-sake-of-it: a
   tone change signals a change in the KIND of content, not merely the next
   section.

     (default)     white  -- reading-heavy prose, testimonials
     .band-tint    #f6f7f9 -- sections holding white cards, so the cards lift
     .band-accent  mint -> teal -- one showcase band per page, no more

   Padding lives here too, so a band is always a full-bleed colour with its
   content inset -- otherwise the colour stops at the text and reads as a box. */
.band{padding-block:var(--sp)}
.band > .wrap{padding-inline:1.5rem}
.band-tint{background:var(--bg)}
.band-accent{background:var(--grad-card)}

/* Consecutive bands of the same tone would show a seam where padding doubles;
   collapse it so they read as one field. */
.band-tint + .band-tint,
.band-accent + .band-accent{padding-top:0}

/* On the accent band the cards are white on mint, so they need no border --
   the tone difference already separates them. */
.band-accent .flip-front{border-color:transparent;
  box-shadow:0 2px 10px rgba(0,0,0,.06)}

@media (max-width:640px){
  .band{padding-block:calc(var(--sp) * .8)}
  .band > .wrap{padding-inline:1rem}
}

/* ---------- flip cards ------------------------------------------------------
   Six benefit tiles: illustration + title on the front, the explanation on the
   back. Live uses an Elementor flip-box (--effect-flip --direction-up); this is
   the same effect in ~25 lines of CSS with no widget and no JavaScript.

   Accessibility, which the Elementor version gets wrong:
   · tabindex makes each card reachable by keyboard AND gives touch devices a
     flip trigger, since :hover does not exist on a phone.
   · Both faces stay in the DOM and readable -- the back is not hidden from
     assistive tech, so the substance is never behind an interaction.
   · prefers-reduced-motion drops the rotation entirely and stacks both faces,
     so nothing depends on an animation that some readers cannot use. */
/* Six cards, so the column count has to divide six. auto-fit gave four across
   at desktop and left a stranded row of two. Explicit 1 / 2 / 3 instead. */
/* No bottom margin: the enclosing .band supplies the spacing, and both together
   left a band of empty colour under the last row. */
.flips{list-style:none;margin:0;padding:0;display:grid;
  gap:var(--sp-gap);grid-template-columns:1fr}
@media (min-width:600px){ .flips{grid-template-columns:repeat(2,1fr)} }
@media (min-width:960px){ .flips{grid-template-columns:repeat(3,1fr);gap:2rem} }
.flip{perspective:1400px}
.flip-card{position:relative;min-height:19rem;cursor:pointer;border-radius:12px;
  transform-style:preserve-3d;transition:transform .55s ease}
@media (min-width:960px){ .flip-card{min-height:23rem} }
/* Hover only where a pointer actually exists. On touch, :hover sticks after a
   tap and the card never turns back. */
@media (hover:hover){
  .flip-card:hover,.flip-card:focus-within{transform:rotateX(180deg)}
}
/* The reliable path everywhere, including iOS: a class toggled on tap. */
.flip-card.is-flipped{transform:rotateX(180deg)}
.flip-card:focus-visible{outline:3px solid var(--blue);outline-offset:4px}
.flip-face{position:absolute;inset:0;backface-visibility:hidden;border-radius:12px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:1.6rem 1.4rem;text-align:center}
/* The six illustrations have different aspect ratios, so sizing by width left
   every title at a different height and the row read as crooked. Give the art a
   fixed-height row instead: the titles then line up across the grid. */
.flip-front{display:grid;grid-template-rows:clamp(112px,12vw,172px) auto;
  align-content:center;align-items:center;justify-items:center;gap:1.15rem}
.flip-front{background:var(--white);border:1px solid var(--line)}
.flip-front img{max-height:100%;max-width:100%;width:auto;height:auto;margin:0}
.flip-title{font-family:var(--sans);font-weight:700;margin:0;
  font-size:clamp(1.05rem,.95rem + .4vw,1.3rem);
  color:var(--ink-dark);line-height:1.3}
.flip-back{background:#0b7dbb;color:#fff;transform:rotateX(180deg)}
.flip-back p{margin:0;line-height:1.55;max-width:30ch;font-size:clamp(.92rem,.85rem + .25vw,1.05rem)}

@media (prefers-reduced-motion:reduce){
  .flip{perspective:none}
  .flip-card{min-height:0;transition:none;transform:none!important;cursor:default}
  .flip-face{position:relative;inset:auto;backface-visibility:visible;transform:none!important}
  .flip-front{border-radius:10px 10px 0 0;border-bottom:0}
  .flip-back{border-radius:0 0 10px 10px}
}

/* Group-coaching tiers. Two side by side on desktop, stacked on phones. */
.cohorts{display:grid;gap:var(--sp-gap);grid-template-columns:repeat(auto-fit,minmax(19rem,1fr));
  margin:0}
/* The subscription note is a footnote to the cards above it, not a lead-in to
   the section below. It sat 48-77px under the cards and flush against the next
   heading, so it read as belonging to the wrong block. Tuck it under the cards
   and put the section gap after it instead. */
.cohorts + .prod-note{margin-top:.75rem}
.prod-note + h2.script,
.prod-note + .script{margin-top:var(--sp)}
/* A script heading is set at 34-68px; .5em under it reads as cramped once the
   next element is a sub-head rather than body copy. Margins collapse here, so
   this has to exceed the heading's own .5em bottom margin to have any effect. */
h2.script + .benefits-lead{margin-top:1.75rem}
.cohort{background:var(--white);border:1px solid var(--line);border-radius:12px;
  padding:1.6rem 1.5rem;display:flex;flex-direction:column;position:relative;
  overflow:hidden;box-shadow:0 2px 12px rgba(18,21,26,.06)}
/* A coloured rule per tier. The two cards are otherwise near-identical, and
   telling them apart at a glance is the one job they have. */
.cohort::before{content:'';position:absolute;inset:0 0 auto 0;height:6px}
.cohort:first-child::before{background:var(--green)}
.cohort:last-child::before{background:var(--blue)}
.cohort:first-child .cohort-class{color:var(--green-text)}
.cohort:last-child  .cohort-class{color:var(--blue)}
.cohort-name{font-family:var(--sans);font-size:1.15rem;margin:0 0 .2em}
.cohort-class{font-family:var(--sans);font-weight:600;font-size:.8rem;letter-spacing:.04em;
  text-transform:uppercase;color:var(--green-text);margin:0 0 .9em}
.cohort-price{font-family:var(--sans);font-weight:800;font-size:1.35rem;margin:0 0 .8em}
.cohort p{max-width:52ch}
.cohort-cta{margin:auto 0 0;padding-top:1.2rem}
/* FAQ is its own band, not a tail on the section above it. */
.faq-block{/* tone comes from .band-tint */}
.acc-list{max-width:820px;margin-inline:auto}
.acc-body p{margin:0 0 1rem}
.acc-body p:last-child{margin-bottom:0}
.acc-body a{color:var(--blue)}
.acc-body ul{margin:.5rem 0 1rem;padding-left:1.25rem}
.acc-body li{margin-bottom:.4rem}
/* Lead-in above a product's checklist, e.g. "Your report covers:" */
.included-lead{margin:1.25rem 0 0;font-family:var(--sans);font-weight:700;
  font-size:.92rem;color:var(--ink-dark)}
/* Per-product policy line. Muted: it is a term, not a selling point. */
.prod-note-inline{margin:1rem 0 0;font-size:.85rem;color:var(--ink-soft);font-style:italic}
.prod-note{margin:1.5rem 0 0;text-align:center;color:var(--ink-soft);font-size:.92rem}

@media (max-width:860px){ .prod-price{gap:.4rem} }

/* ---------- page-hero variants -------------------------------------------
   Heights matched to live so every page opens at roughly the same scale:
   college 539, high-school 501, coaching 555, about-us 610. */
/* This photo alone is framed with Ruchi on the right and deliberate empty blue on
   the left. `center 30px` pushed it down 30px, but the image covers the hero
   exactly at these sizes, so there was no slack to absorb the offset and a 30px
   strip of the base colour showed above it at every width. */
.page-hero--coaching{background-position:center top}

/* The hero pair carries no bottom margin, so the button needs its own gap --
   .ph-plain used to supply this before the title/subtitle split. */
.ph-cta{margin:1.4rem 0 0}

.page-hero--about{background-position:center top}
.ph-quote{font-family:var(--sans);font-weight:500;color:#fff;margin:.5rem 0 0;max-width:22ch;
  line-height:1.3;font-size:clamp(1.15rem,.7rem + 2.2vw,2.1875rem);
  text-shadow:0 2px 14px rgba(0,0,0,.4)}

@media (max-width:1023px){
  .ph-quote{max-width:30ch;margin-inline:auto}
}

/* ---------- heroes whose photograph has a person in it -------------------- */
/* about-us, college, high-school and coaching all put hero text over a photo of
   someone, and all four were centring it across a face. One rule for the four so
   they read as a set; /shop and the homepage are deliberately not included --
   shop's hero is a single word over a graphic and home is a different component.

   Below 1024px `cover` crops these landscape photos into a portrait box, throwing
   away whatever empty space they were composed with and framing the subject dead
   centre. There is no horizontal room left, so the text sits at the foot of the
   hero and the scrim is weighted to the bottom to carry it.

   From 1024px the whole frame is visible, so the text moves left -- where every
   one of these photographs has its quiet side -- and the scrim runs left to
   right: dark behind the words, clear by the time it reaches the person. */
@media (max-width:1023px){
  .page-hero--subject{place-items:end center}
  .page-hero--subject .wrap{padding-block:1rem 1.75rem}
  /* Alpha is baked into the stops rather than split with an opacity multiplier,
     because the number that matters is the one the text actually sits on. The
     text column starts around 44% of the hero height; 0.55 is the alpha needed
     to hold #63d8ce at 3:1 over the brightest of these four photographs, so the
     ramp reaches 0.62 by then and keeps the top of the frame clear. */
  .page-hero--subject::after{
    background:linear-gradient(rgba(0,0,0,0) 12%,rgba(0,0,0,.34) 30%,
                               rgba(0,0,0,.62) 44%,rgba(0,0,0,.86) 100%);
    opacity:1}
}
@media (min-width:1024px){
  .page-hero--subject{place-items:center stretch}
  /* width:100% rather than relying on justify-items:stretch -- .wrap carries
     `margin:0 auto`, and an auto inline margin disables stretch in grid, so the
     item stayed shrink-to-fit and the "left-aligned" text sat centred instead. */
  .page-hero--subject .wrap{width:100%;max-width:var(--wrap);text-align:left}
  /* Hold the text to the left half. A ch-based cap cannot do this job across four
     different headlines -- "Shop" and "Meet Ruchi S. Kothari..." are not the same
     problem -- so it is measured against the column instead. */
  .page-hero--subject .ph-title,
  .page-hero--subject .ph-sub,
  .page-hero--subject .ph-quote{max-width:min(52%,34rem)}
  .page-hero--subject .ph-quote{margin-inline:0}
  /* The text column ends at 47.5% of the hero width, and the old ramp had already
     decayed to an effective 0.16 by there -- the white subtitle measured 2.53:1
     on about-us. It now holds 0.64 to 48% and only then falls away, reaching zero
     at 76% so the person is never touched. */
  .page-hero--subject::after{
    background:linear-gradient(90deg,rgba(0,0,0,.72) 0%,rgba(0,0,0,.64) 48%,
                               rgba(0,0,0,.22) 62%,rgba(0,0,0,0) 76%);
    opacity:1}
}

/* ---------- about: prose column and the "More About" band ---------------- */
.prose-col{max-width:58ch;margin-inline:auto}
.prose-col p{margin:0 0 1.25em}
.prose-col .included{margin:1.5rem 0}
.signoff{margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--line);
  font-size:.95rem;line-height:1.9}
.signoff strong{font-family:var(--sans);font-weight:700;color:var(--ink-dark)}

/* live sets this band white-on-photo; a solid brand gradient reads better and
   costs no image request */
.about-band{background:linear-gradient(45deg,#06aa82 0%,#0b7dbb 100%);
  text-align:center;padding:clamp(2.5rem,5vw,4.5rem) 0}
.ab-kicker{font-family:var(--sans);font-weight:600;color:#fff;margin:0;line-height:1.1;
  font-size:clamp(1.6rem,.9rem + 3vw,3.5rem)}          /* live: 90px Montserrat white */
.ab-name{font-family:var(--display);font-weight:600;font-style:oblique;color:#63d8ce;
  margin:.15em 0 0;line-height:1.15;
  font-size:clamp(2rem,1rem + 4.3vw,4.25rem)}          /* live: 85px, #63d8ce */

/* newsletter status line — one grid row under the fields */
/* Reserve the widget's height before it renders. Turnstile injects its iframe
   asynchronously, so the footer grew by 72px whenever it finished -- a visible
   jump for anyone who had already scrolled there, and the source of a phantom
   73px difference in the preview-vs-Pages height comparison, which flip-flopped
   between the two environments because it depended purely on load timing.
   72px is the widget's rendered height at its default size. */
.cf-turnstile{min-height:72px}
.nform-msg{grid-column:1 / -1;margin:.25rem 0 0;font-size:.9rem;min-height:1.2em;
  color:var(--ink-soft);text-align:center}
.nform-msg.is-ok{color:var(--green-text);font-weight:600}
.nform-msg.is-error{color:#b3261e;font-weight:600}
.nform button:disabled{opacity:.6;cursor:default}
