/* =============================================================================
   Metronome — Public marketing stylesheet
   Hand-written, servable (no build step). Extends the portal's "Metronome"
   design language (see STYLE_GUIDE.md + design/metronome-showcase.html) to the
   public site: sage & pine neutrals, the logo's magenta→purple as a two-tone
   brand accent, condensed capitals, sharp 3–4px corners, one hard offset
   shadow, no gradients, no blur, light only.

   Two brand tones, one family: MAGENTA (--accent) is the loud, semantic one
   (actions, trial, the needle, current step, corner tick); DEEP PLUM (--brand)
   is the quiet identity layer (eyebrows, links, wordmark, emphasis rules).
   Every musical device (metronome, staff ruling, notehead, note-value glyph,
   melody stepper) carries meaning; none is used as decoration.
   ============================================================================= */

/* ------------------------------------------------------------------ tokens -- */
:root{
  --bg:#eaf0e7;        /* sage — page ground */
  --card:#f9fbf6;      /* paper — card surface */
  --card2:#f1f5ec;     /* inset panels / wells */
  --ink:#16302a;       /* pine — text, strong borders */
  --muted:#54705f;     /* secondary text */
  --line:#d3ddcf;      /* hairline borders */
  --line2:#c2cfbd;     /* stronger hairline */
  /* Brand accent — the logo's magenta, made the hero. This is the ONE loud
     colour: primary actions, trial, the metronome needle, current step,
     corner tick, active state. */
  --accent:#a82d7c;     /* magenta-plum */
  --accent-ink:#fdf2f8; /* text on accent */
  --accent-soft:#f3d8ea;/* soft magenta tint (chips, wells) */
  /* Brand deep — the logo's purple end. The quiet identity layer: eyebrows,
     in-content links, the wordmark, emphasis rules. Same family as the accent,
     one step deeper, so the two read as one brand — never a competing hue. */
  --brand:#732c66;      /* deep plum */
  --brand-ink:#fbf1f7;
  --brand-soft:#e9d8e6;
  --plum-deep:#4c1c47;  /* darkest plum — for large brand fills / on-dark accents */
  --good:#2e7d5b;   --good-bg:#e0ecdf;
  --warn:#8a6410;   --warn-bg:#efe6cf;
  --crit:#8c1d12;   --crit-bg:#efd8d3;
  --chip:#dfe8db;      /* neutral chip fill */
  --shadow-press:2px 2px 0 var(--ink);
  --staff:rgba(22,48,42,.18);
  color-scheme: light;

  --disp:'Avenir Next Condensed','Helvetica Neue Condensed','Arial Narrow',Arial,sans-serif;
  --body:'Avenir Next',Avenir,'Helvetica Neue',Helvetica,Arial,sans-serif;
}

/* ------------------------------------------------------------------- reset -- */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:15px/1.55 var(--body);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img,video,iframe{max-width:100%}
img{height:auto}
a{color:var(--brand); text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{margin:0}
:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

/* --------------------------------------------------------------- typography -- */
.disp{font-family:var(--disp); font-weight:700; text-transform:uppercase; letter-spacing:.05em}
.num{font-variant-numeric:tabular-nums}
.kick{font:700 12px/1.3 var(--disp); text-transform:uppercase; letter-spacing:.22em; color:var(--brand); margin:0}
.lab{font-size:10.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); font-weight:700}
.lead{color:var(--muted); font-size:clamp(16px,2.2vw,19px); max-width:60ch; margin:0 auto}
p{margin:0 0 1em; max-width:65ch}

/* ---------------------------------------------------------------- layout -- */
.wrap{max-width:1120px; margin:0 auto; padding:0 20px}
.wrap.narrow{max-width:900px}
.section{padding:clamp(48px,8vw,84px) 0}
.section.tight{padding:clamp(32px,5vw,52px) 0}
.section--sage{background:var(--bg)}
.section--paper{background:var(--card); border-top:1px solid var(--line); border-bottom:1px solid var(--line)}
/* Two paper sections back to back (an instrument page's teachers band running
   into its trust strip) read as one band. */
.section--paper + .section--paper{border-top:0}
.section--paper:has(+ .section--paper){border-bottom:0; padding-bottom:0}
.section--ink{background:var(--ink); color:var(--card)}
.section--ink .lead,.section--ink p{color:rgba(249,251,246,.82)}

.sec-head{max-width:64ch; margin:0 auto clamp(28px,5vw,48px); text-align:center}
.sec-head h2{font-family:var(--disp); font-weight:700; text-transform:uppercase; letter-spacing:.04em;
  font-size:clamp(28px,5vw,44px); line-height:1.02; margin:6px 0 12px}
.sec-head .kick{margin-bottom:2px}

.grid{display:grid; gap:16px}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.g5{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}

/* -------------------------------------------------------------- buttons -- */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:8px;
  border:0; background:var(--accent); color:var(--accent-ink); border-radius:3px;
  padding:13px 22px; font:700 14px/1 var(--body); cursor:pointer;
  box-shadow:var(--shadow-press); transition:transform .15s cubic-bezier(.3,1.3,.4,1), box-shadow .15s}
.btn:hover{text-decoration:none; color:var(--accent-ink)}
.btn:active{transform:translate(2px,2px); box-shadow:0 0 0 var(--ink)}
.btn.ghost{background:var(--card); color:var(--ink); border:1.5px solid var(--ink)}
.btn.ghost:hover{color:var(--ink)}
.btn.on-ink{background:var(--card); color:var(--ink)}
.btn.big{padding:16px 28px; font-size:15.5px}
.btn.block{width:100%}

/* -------------------------------------------------------------- chips -- */
.chipS{display:inline-flex; align-items:center; gap:6px; font:700 11px/1 var(--body);
  padding:6px 10px; border-radius:2px; letter-spacing:.03em; white-space:nowrap}
.chipS.ok{background:var(--good-bg); color:var(--good)}
.chipS.warn{background:var(--warn-bg); color:var(--warn)}
.chipS.crit{background:var(--crit-bg); color:var(--crit)}
.chipS.acc{background:var(--accent-soft); color:var(--accent)}
.chipS.mut{background:var(--chip); color:var(--ink)}
.chipS.brand{background:var(--brand-soft); color:var(--brand)}

/* -------------------------------------------------------------- cards -- */
.card{background:var(--card); color:var(--ink); border:1px solid var(--line); border-radius:4px;
  padding:22px; display:flex; flex-direction:column}
.card h3{font-family:var(--body); font-weight:700; font-size:19px; margin:0 0 8px}
.card .cap{color:var(--muted); font-size:13.5px; margin:0 0 14px}
.card--inset{background:var(--card2); border-style:solid}
.card--pad-lg{padding:clamp(24px,4vw,40px)}

/* one corner tick per screen — "this needs you now" (reserve for the trial CTA) */
.ct{position:relative; overflow:hidden}
.ct::before{content:""; position:absolute; top:0; left:0; width:0; height:0;
  border-top:18px solid var(--accent); border-right:18px solid transparent; z-index:1}

/* =========================================================== signature devices */
/* metronome — brand mark / loader; resting by default (still) */
.met{position:relative; flex:0 0 auto; width:58px; height:76px;
  clip-path:polygon(31% 0,69% 0,100% 100%,0 100%); background:var(--ink)}
.met .slot{position:absolute; left:50%; top:9px; bottom:13px; width:11px; transform:translateX(-50%);
  background:var(--card);
  background-image:repeating-linear-gradient(to bottom,var(--line2) 0 1px,transparent 1px 6px);
  border-radius:99px}
.met .needle{position:absolute; left:50%; bottom:11px; height:54px; width:2px; background:var(--accent);
  transform-origin:bottom center; transform:translateX(-50%) rotate(-9deg)}
.met .needle::before{content:""; position:absolute; left:50%; top:7px; width:9px; height:12px;
  transform:translateX(-50%); background:var(--accent); border-radius:2px}
.met .foot{position:absolute; left:0; right:0; bottom:0; height:5px; background:var(--ink);
  border-top:1.5px solid var(--card)}
.met.lg{width:76px; height:100px}
.met.lg .needle{height:72px; bottom:14px}
.met.lg .slot{top:12px; bottom:17px}
.met.swing .needle,
.met.hoverable:hover .needle,
.met.hoverable:focus-visible .needle{animation:tick .82s cubic-bezier(.45,0,.55,1) infinite alternate}
@keyframes tick{from{transform:translateX(-50%) rotate(-17deg)}to{transform:translateX(-50%) rotate(17deg)}}

/* staff ruling — "a lesson lives here"; carried by the headline so it scales */
.staffText{display:inline-block; line-height:1; padding:.02em .1em;
  background-image:repeating-linear-gradient(to bottom,var(--staff) 0 1px,transparent 1px .205em);
  background-size:100% calc(.82em + 1px); background-repeat:no-repeat; background-position:center 46%}

/* note-value glyph — lesson length; ALWAYS beside the plain number */
.noteg{font-size:1.05em; line-height:1}

/* notehead marker — "part of what you'll play"; used as a filled list bullet */
.nh{position:relative; display:inline-block; width:14px; height:20px; flex:0 0 auto; color:var(--ink)}
.nh::before{content:""; position:absolute; bottom:0; left:0; width:10.5px; height:7.5px;
  border:1.5px solid currentColor; border-radius:50%; transform:rotate(-12deg); background:currentColor}
.nh::after{content:""; position:absolute; left:12px; bottom:3.5px; width:1.5px; height:15px; background:currentColor}
.nh.hollow::before{background:transparent}
.nh.acc{color:var(--accent)}

/* feature list built on noteheads */
.flist{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:11px}
.flist li{display:flex; align-items:flex-start; gap:11px; font-size:14.5px}
.flist li .nh{margin-top:1px}

/* whole rest — empty/"quiet" states */
.rest{width:46px; margin:0 auto}
.rest .rline{height:2px; background:var(--muted)}
.rest .rblock{width:16px; height:8px; background:var(--muted); margin:0 auto}

/* melody stepper — progress in a flow (trial booking) */
.melody{max-width:420px; margin:0 auto}
.mstaff{position:relative; height:37px; margin:30px 4px 12px;
  background-image:repeating-linear-gradient(to bottom,var(--staff) 0 1px,transparent 1px 9px);
  background-size:100% 37px; background-repeat:no-repeat;
  display:grid; grid-template-columns:repeat(4,1fr)}
.mcell{position:relative}
.mn{position:absolute; left:50%; bottom:var(--y); transform:translateX(-50%); width:17px; height:38px; color:var(--line2)}
.mn::before{content:""; position:absolute; bottom:0; left:0; width:12.5px; height:9px;
  border:1.5px solid currentColor; border-radius:50%; transform:rotate(-12deg); background:transparent}
.mn::after{content:""; position:absolute; left:14px; bottom:4.5px; width:1.5px; height:31px; background:currentColor}
.mn.done{color:var(--ink)} .mn.done::before{background:currentColor}
.mn.cur{color:var(--accent)} .mn.cur::before{background:currentColor}
.fine{position:absolute; right:-4px; top:-1px; bottom:-1px; width:8px; border-left:1.5px solid var(--ink)}
.fine::after{content:""; position:absolute; right:0; top:0; bottom:0; width:3.5px; background:var(--ink)}
.msteps{display:grid; grid-template-columns:repeat(4,1fr); text-align:center;
  font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:700}
.msteps span.on{color:var(--accent)}

/* stars rendered in pine, understated */
.stars{display:inline-flex; gap:3px; color:var(--ink); font-size:1em; line-height:1}

/* ================================================================= nav === */
.nav{position:sticky; top:0; z-index:50; background:var(--card); border-bottom:1.5px solid var(--ink)}
.nav__bar{display:flex; align-items:center; justify-content:space-between; gap:16px;
  max-width:1120px; margin:0 auto; padding:12px 20px}
.brand{display:flex; align-items:center; gap:10px; color:var(--ink)}
.brand:hover{text-decoration:none}
.brand img{width:34px; height:34px; border-radius:4px; display:block}
.brand b{font:700 20px/1 var(--disp); text-transform:uppercase; letter-spacing:.06em; color:var(--brand)}
.nav__links{display:flex; align-items:center; gap:22px}
.nav__links a.navlink{color:var(--ink); font-weight:600; font-size:14px}
.nav__links a.navlink:hover{color:var(--accent); text-decoration:none}
.nav__cta{display:flex; align-items:center; gap:10px}
.nav__toggle{display:none; background:none; border:1.5px solid var(--ink); border-radius:3px;
  width:42px; height:38px; cursor:pointer; align-items:center; justify-content:center; color:var(--ink)}
.nav__toggle span,.nav__toggle span::before,.nav__toggle span::after{
  content:""; display:block; width:18px; height:1.5px; background:var(--ink); position:relative}
.nav__toggle span::before{position:absolute; top:-5px}
.nav__toggle span::after{position:absolute; top:5px}

/* mobile slide-out (Alpine-driven) */
.nav__panel{position:fixed; inset:0 0 0 auto; width:300px; max-width:85vw; background:var(--card);
  border-left:1.5px solid var(--ink); box-shadow:var(--shadow-press); z-index:60; padding:20px;
  display:flex; flex-direction:column; gap:6px; overflow-y:auto}
.nav__panel a{color:var(--ink); font-weight:600; padding:12px 8px; border-bottom:1px solid var(--line)}
.nav__panel a:hover{color:var(--accent); text-decoration:none}
.nav__panel .lab{margin:16px 0 4px}
.nav__backdrop{position:fixed; inset:0; background:rgba(22,48,42,.32); z-index:55}

/* Compact "Log in" control for the mobile bar. Below 900px the desktop ghost
   "Student login" button is hidden to make room, which used to leave phones
   with no visible way in at all — the only login link was buried mid-list in
   the slide-out. This one sits in the bar itself, next to "Book a trial",
   with a 44px tap target. Hidden on desktop, where the full-width ghost
   button already says "Student login". */
.nav__login{display:none; align-items:center; justify-content:center; gap:7px;
  min-height:44px; padding:0 14px;
  border:1.5px solid var(--ink); border-radius:3px; color:var(--ink); background:var(--card);
  font-weight:700; font-size:14px; white-space:nowrap}
.nav__login:hover{color:var(--accent); border-color:var(--accent); text-decoration:none}
.nav__login i{font-size:15px; line-height:1}

/* The slide-out's own login entry, promoted out of the plain link list so it
   reads as an action rather than another section anchor. */
.nav__panel .nav__panel-login{display:flex; align-items:center; justify-content:center; gap:8px;
  margin:10px 0 4px; padding:13px 14px; min-height:48px; border:1.5px solid var(--ink);
  border-radius:3px; background:var(--card2); font-weight:700}
.nav__panel .nav__panel-login:hover{background:var(--ink); color:var(--card)}

@media (max-width:900px){
  .nav__links,.nav__cta .btn:not(.nav__cta-primary){display:none}
  .nav__toggle{display:inline-flex}
  .nav__login{display:inline-flex}
  .nav__bar{gap:8px; padding:12px 14px}
  .nav__cta{gap:8px}
  /* 44px tap targets across the whole mobile bar. */
  .nav__toggle{width:44px; height:44px}
  .nav__cta-primary{min-height:44px; padding:13px 16px}
}
/* Narrow phones: the brand wordmark, not the login button, is what gives way. */
@media (max-width:430px){
  .nav__bar .brand b{display:none}
  .nav__login{padding:0 11px}
  .nav__cta-primary{padding:13px 12px; font-size:13.5px}
}

/* ================================================================= hero === */
.hero{padding:clamp(56px,10vw,104px) 0 clamp(40px,7vw,72px); border-bottom:1.5px solid var(--ink)}
.hero__grid{display:grid; grid-template-columns:1.35fr .65fr; gap:40px; align-items:center}
.hero h1{font-family:var(--disp); font-weight:700; text-transform:uppercase; letter-spacing:.02em;
  font-size:clamp(38px,7vw,74px); line-height:.96; margin:14px 0 0}
.hero h1 .coral{color:var(--accent)}
.hero .sub{margin:18px 0 26px; color:var(--muted); font-size:clamp(16px,2.4vw,20px); max-width:52ch}
.hero__actions{display:flex; flex-wrap:wrap; gap:12px}
/* The new-student offer line on the instrument pages, just above the buttons
   so the price is on the first screen (see public/_hero_offer.html). */
.hero__offer{margin:-8px 0 18px; font-size:clamp(16px,2.2vw,18px); line-height:1.4; color:var(--ink)}
.hero__offer .price{color:var(--accent)}
.hero__aside{display:flex; align-items:center; justify-content:center}
@media (max-width:820px){
  .hero__grid{grid-template-columns:1fr; gap:28px}
  .hero__aside{order:-1; justify-content:flex-start}
}

/* hero art removed (4b4d6f1): the "On the stave" drifting-melody device and
   its aside were dropped from the homepage hero, which is now single-column.
   The .hero__aside / .hero__grid rules above are kept — the instrument pages
   (piano/guitar/violin/singing) still use an aside. */

/* stat tiles */
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line); border-radius:4px; overflow:hidden; margin-top:32px}
.stat{background:var(--card); padding:18px 16px}
.stat b{display:block; font:700 clamp(24px,3.5vw,34px)/1 var(--disp); letter-spacing:.02em;
  font-variant-numeric:tabular-nums; color:var(--ink)}
.stat span{display:block; margin-top:6px; font-size:12.5px; color:var(--muted)}

/* ---------------------------------------------------- program / pathway cards */
.prog{position:relative}
/* instrument icons are white silhouettes → seat them on a pine tile */
.prog .icon{width:56px; height:56px; border-radius:4px; background:var(--ink);
  border:1px solid var(--ink); display:flex; align-items:center; justify-content:center; margin-bottom:16px; color:var(--card)}
.prog .icon img{width:32px; height:32px; object-fit:contain}
.prog h3{font-size:20px}
.more{margin-top:16px; font-weight:700; font-size:14px; color:var(--brand);
  display:inline-flex; align-items:center; gap:6px}
.more:hover{text-decoration:none; gap:9px; transition:gap .15s}
.prog .flist{margin-top:4px}
/* A linked program card is clickable all over: its one real link, "Learn more",
   stretches an ::after across the card (.prog is the positioned box), so there
   is no nested link and the accessible name stays the link's own. The focus
   ring moves to that overlay so it outlines the card. Anything interactive
   added inside a card later needs position:relative; z-index:1 to sit above
   it. The theory card has no link and so no overlay, hover or pointer. */
.prog .more::after{content:""; position:absolute; inset:0; border-radius:4px}
.prog .more:focus-visible{outline:none}
.prog .more:focus-visible::after{outline:2px solid var(--accent); outline-offset:2px}
.prog:has(.more){transition:border-color .15s}
.prog:has(.more:hover){border-color:var(--brand)}

/* duration key line */
.durkey{display:flex; flex-wrap:wrap; gap:10px 20px; align-items:center; margin-top:14px;
  padding-top:14px; border-top:1px solid var(--line); font-size:13px; color:var(--muted)}
.durkey .noteg{color:var(--ink)}

/* -------------------------------------------------------------- banners -- */
.band{border:1.5px solid var(--ink); border-radius:4px; padding:clamp(20px,4vw,34px);
  display:flex; flex-wrap:wrap; align-items:center; gap:18px 28px; justify-content:space-between}
.band--ink{background:var(--ink); color:var(--card); border-color:var(--ink)}
.band--ink p{color:rgba(249,251,246,.82)}
.band__head{font:700 clamp(20px,3vw,28px)/1.05 var(--disp); text-transform:uppercase; letter-spacing:.03em}

/* -------------------------------------------------------------- pricing -- */
.priceCard{text-align:center; display:flex; flex-direction:column; align-items:center; gap:2px}
/* Scoped to .priceCard so the card's own colours beat `.section--ink p`
   (a light colour) when this section sits on the dark ink background. */
.priceCard .kick{color:var(--brand)}
.priceCard .cap,.priceCard .lab{color:var(--muted)}
.priceTag{font:700 clamp(42px,6vw,60px)/1 var(--disp); letter-spacing:.02em; margin:8px 0 2px}
.priceCard .priceTag{color:var(--ink)}
.priceTag sup{font-size:.42em; font-weight:700; top:-.62em; margin-right:1px; color:var(--muted)}
.priceNote{max-width:68ch; margin:clamp(26px,4vw,38px) auto 0; text-align:center;
  font-size:clamp(15px,1.8vw,17px); line-height:1.62}

/* trust strip */
.trust{display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line); border-radius:4px; overflow:hidden}
.trust > div{background:var(--card); padding:18px 20px; display:flex; align-items:center; gap:12px}
.trust b{font:700 15px/1.2 var(--body)}
.trust small{display:block; color:var(--muted); font-size:12px; margin-top:2px}

/* -------------------------------------------------------------- media -- */
.frame{border:1px solid var(--line); border-radius:4px; overflow:hidden; background:var(--card); display:block; line-height:0}
.frame.ink{border:1.5px solid var(--ink)}
.media-grid{display:grid; grid-template-columns:1fr 1fr; gap:12px}
.ratio16{position:relative; padding-bottom:56.25%; height:0; overflow:hidden}
.ratio16 iframe{position:absolute; inset:0; width:100%; height:100%; border:0}
/* YouTube click-to-play thumbnail (public/_yt.html), filling a .ratio16 box */
.yt,.yt__btn{position:absolute; inset:0}
.yt__btn{display:block; background:var(--ink)}
.yt__btn img{width:100%; height:100%; object-fit:cover; display:block}
.yt__play{position:absolute; left:50%; top:50%; width:68px; height:48px; margin:-24px 0 0 -34px;
  border-radius:12px; background:rgba(22,48,42,.85); transition:background .15s}
.yt__play::after{content:""; position:absolute; left:27px; top:14px;
  border-style:solid; border-width:10px 0 10px 17px; border-color:transparent transparent transparent #fff}
.yt__btn:hover .yt__play,.yt__btn:focus-visible .yt__play{background:var(--accent)}
.yt__btn:focus-visible{outline:3px solid var(--accent); outline-offset:-3px}

/* fluid, aspect-ratio-safe <video> — sized from its width/height attributes
   (no layout shift), never autoplays, first frame paints via preload=metadata
   + a #t= media-fragment (no autoplay/no eager network cost on page load). */
.vid-fluid{display:block; width:100%; height:auto; background:var(--ink)}
/* two tall (portrait) videos side by side get cramped on small phones —
   stack them full-width instead. */
@media (max-width:480px){
  .media-grid:has(video){grid-template-columns:1fr}
}
/* capped-height showcase video (index hero band): centred, never taller
   than the ink band. The ratio is set outright (not left to width/height)
   because it shows a square poster until played, which would otherwise
   resize the box. */
.vidbox{display:flex; justify-content:center; background:var(--ink)}
.vidbox__el{display:block; height:auto; max-height:560px; max-width:100%; aspect-ratio:1080/1920}

/* instrument hero icon tile */
.icontile{width:clamp(180px,26vw,260px); aspect-ratio:1; border:1.5px solid var(--ink); border-radius:4px;
  background:var(--ink); display:flex; align-items:center; justify-content:center}
.icontile img{width:46%; height:46%; object-fit:contain}

/* -------------------------------------------------------- feature (why) -- */
.feature{text-align:center}
.feature .icon{width:64px; height:64px; margin:0 auto 16px; border-radius:4px;
  background:var(--card2); border:1px solid var(--line); display:flex; align-items:center; justify-content:center; color:var(--ink)}
.feature h3{font-size:18px; margin-bottom:8px}
.feature p{color:var(--muted); font-size:14px; margin:0 auto; max-width:36ch}

/* ----------------------------------------------------- teacher profiles -- */
/* The public "meet your teachers" band: home (grouped per instrument) and each
   instrument page (that instrument's teachers). Same card either way.
   auto-FILL, not auto-fit, so a group with one teacher keeps a card-sized card
   instead of stretching it across the whole row — and a portrait-shaped card
   (narrow enough for four across the 1120px wrap, three on a tablet, one on a
   phone) is what makes the band read as a row of faces rather than a list. */
.tgrid{display:grid; grid-template-columns:repeat(auto-fill,minmax(232px,1fr));
  gap:clamp(14px,2vw,20px)}
/* One teacher, one card: a face on top of a centred column. `height:100%`
   against the grid's default stretch keeps every card in a row the same height
   whatever the bio length. */
.tprofile{height:100%; background:var(--card); border:1px solid var(--line); border-radius:4px;
  padding:26px 20px 22px; display:flex; flex-direction:column; align-items:center;
  text-align:center; gap:9px}
/* The one round thing in the system — a face, never a card. Fixed px (not a
   ratio) so the card height is reserved before the photo lands. */
.tprofile__photo{flex:0 0 auto; width:104px; height:104px; border-radius:50%; overflow:hidden;
  background:var(--ink); display:grid; place-items:center; border:1.5px solid var(--ink)}
/* Headshots are framed for the head, so a square crop keeps the top, not the
   middle — chins survive, foreheads don't get cut off. */
.tprofile__photo img{width:100%; height:100%; object-fit:cover; object-position:center top; display:block}
.tprofile__initial{color:var(--card); font-size:38px; line-height:1; letter-spacing:.04em}
.tprofile__name{font-size:17px; line-height:1.15; margin:3px 0 0}
.tprofile__chips{display:flex; flex-wrap:wrap; gap:5px; justify-content:center}
/* The max-width is under the global 65ch on <p> — it does nothing at card
   width, and on a phone (where the card is the full column) it keeps the
   centred lines readable. The four-line clamp applies from first paint
   whenever JS is on (`.js` comes from public/_js_class.html, not from Alpine)
   and lifts when Read more marks the bio --open; without JS the whole bio shows. */
.tprofile__bio{margin:1px 0 0; max-width:46ch; color:var(--muted); font-size:13.5px; line-height:1.55}
.js .tprofile__bio:not(.tprofile__bio--open){display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:4; overflow:hidden}
/* margin-top:auto pins the toggle to the foot of the card, so the toggles line
   up across a row of unequal bios. */
.tprofile__more{margin-top:auto; padding:8px 0 0; min-height:28px;
  background:none; border:0; cursor:pointer; font:700 12px/1 var(--body); color:var(--brand);
  text-decoration:underline; text-underline-offset:3px}
.tprofile__more:hover{color:var(--accent)}
/* The toggle and the "Book with …" button share one foot. margin-top:auto
   pins it to the bottom of the card, so both line up across a row of unequal
   bios; a hidden toggle takes no room (or gap) in it. */
.tprofile__foot{margin-top:auto; display:flex; flex-direction:column; align-items:center; gap:12px}
.tprofile__foot .tprofile__more{margin-top:0}
/* Small and secondary: the band's own big button below the grid stays the
   main call to action. Still a 40px target for a thumb. */
.tprofile__book{min-height:40px; padding:10px 16px; font-size:13.5px}

/* homepage: one titled group per instrument */
.tgroup + .tgroup{margin-top:clamp(30px,5vw,46px)}
.tgroup__head{display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin:0 0 16px; padding-bottom:10px; border-bottom:1px solid var(--line2)}
.tgroup__head h3{font:700 clamp(18px,2.6vw,22px)/1 var(--disp); text-transform:uppercase;
  letter-spacing:.05em; margin:0}
.tgroup__head .more{margin-top:0; margin-left:auto}
.tgroup__icon{width:36px; height:36px; flex:0 0 auto; border-radius:4px; background:var(--ink);
  display:grid; place-items:center}
.tgroup__icon img{width:56%; height:56%; object-fit:contain}

/* Phones: one card per row and a slightly smaller face, so a card is about a
   thumb-scroll tall rather than a screenful. Nothing rearranges — the portrait
   card is already the mobile shape. */
@media (max-width:560px){
  .tgrid{grid-template-columns:1fr; gap:12px}
  .tprofile{padding:22px 18px 20px}
  .tprofile__photo{width:88px; height:88px}
  .tprofile__initial{font-size:32px}
  .tprofile__name{font-size:16px}
  .tgroup__head .more{margin-left:0; width:100%}
}

/* -------------------------------------------------------- testimonials -- */
.rev{background:var(--card); border:1px solid var(--line); border-radius:4px; padding:24px;
  display:flex; flex-direction:column; height:100%; width:100%}
/* break-word, not anywhere: `anywhere` also feeds into intrinsic sizing and can
   let a grid/flex track collapse narrower than the text wants. */
.rev p{font-size:14.5px; line-height:1.62; color:var(--ink); margin:12px 0 20px; flex-grow:1;
  overflow-wrap:break-word}
.rev .who{display:flex; align-items:center; gap:12px; margin-top:auto;
  padding-top:16px; border-top:1px solid var(--line)}
.rev .avvy{width:38px; height:38px; border-radius:4px; background:var(--ink); color:var(--card);
  display:grid; place-items:center; font:800 15px/1 var(--body); flex:0 0 auto}
.rev .who b{display:block; font-size:14px}
.rev .who span{font-size:12px; color:var(--muted)}
.rating{background:var(--card); border:1.5px solid var(--ink); border-radius:4px; padding:22px 28px;
  display:inline-flex; align-items:center; gap:18px; margin:0 auto; max-width:100%}
.rating .big{font:700 46px/1 var(--disp); font-variant-numeric:tabular-nums}

/* swiper (reviews carousel) — recoloured to the palette. These CSS variables
   are read by swiper-bundle.css regardless of stylesheet load order. */
.swiper{padding:8px 4px 8px;
  --swiper-theme-color:var(--accent);
  --swiper-navigation-color:var(--ink);
  --swiper-pagination-color:var(--accent)}
/* Equal-height cards. The wrapper is a flex row, so stretching the slides and
   letting the card fill its slide is what keeps a row of reviews level however
   long one of them runs. Scoped past a bare `.swiper-slide` on purpose: the
   bundle ships `height:100%`, which resolves to content height against an
   auto-height wrapper and left the cards ragged. */
.reviewsSwiper .swiper-wrapper{align-items:stretch}
.reviewsSwiper .swiper-slide{height:auto; display:flex}

/* Carousel controls: a row UNDER the track. Overlaid arrows covered the review
   text on desktop and sat under the swiping thumb on mobile. */
.revnav{display:flex; align-items:center; justify-content:center; gap:16px; margin-top:22px}
.revnav__btn{width:42px; height:42px; flex:0 0 auto; display:grid; place-items:center;
  background:var(--card); color:var(--ink); border:1.5px solid var(--ink); border-radius:3px;
  box-shadow:var(--shadow-press); font-size:17px; line-height:1; cursor:pointer;
  transition:background .15s ease, color .15s ease}
.revnav__btn:hover{background:var(--ink); color:var(--card)}
.revnav__btn:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.revnav__btn.swiper-button-disabled{opacity:.35; cursor:default}
/* The dots are a sibling of .swiper here, so swiper's absolute positioning for
   an in-container pagination must be undone. Kept as a plain block, NOT flex:
   swiper's dynamic bullets are inline-blocks it offsets by transform, and as
   flex items they were shrunk to zero width and vanished. */
.revnav__dots.swiper-pagination{position:static; width:auto; display:block;
  text-align:center; line-height:0}
.swiper-pagination-bullet{background:var(--line2); opacity:1; width:8px; height:8px;
  display:inline-block; vertical-align:middle; margin:0 4px;
  transition:background .15s ease, transform .15s ease}
.swiper-pagination-bullet-active{background:var(--accent); transform:scale(1.15)}

@media (max-width:640px){
  .rev{padding:20px 18px}
  .rev p{font-size:15px}
  /* One card per view, so every slide is as tall as the LONGEST review in the
     set. Pinning the name to the bottom left a short quote stranded above a
     void; centring the whole card reads as deliberate instead. (Growing the
     container per slide was the other option — but the height would jump under
     the reader's thumb mid-autoplay.) */
  .reviewsSwiper .rev{justify-content:center}
  .reviewsSwiper .rev p{flex-grow:0}
  .reviewsSwiper .rev .who{margin-top:20px}
  .rating{padding:16px 20px; gap:14px; width:100%; justify-content:center}
  .rating .big{font-size:38px}
  /* 10.5px at .12em tracking wrapped to three cramped lines on a phone. */
  .rating .lab{font-size:11px; letter-spacing:.05em}
  .revnav{gap:12px; margin-top:18px}
  .revnav__btn{width:46px; height:46px}  /* comfortable 44px+ tap target */
}

/* -------------------------------------------------------- location -- */
.loc-info{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:12px}
.loc-info li{display:flex; align-items:flex-start; gap:12px; font-size:14.5px}
.loc-info .bi{color:var(--accent); margin-top:2px}

/* -------------------------------------------------------- prose (SEO) -- */
.prose h2{font-family:var(--disp); text-transform:uppercase; letter-spacing:.03em;
  font-size:clamp(24px,4vw,34px); text-align:center; margin:0 0 28px}
.prose h3{font-size:19px; margin:0 0 12px}
.prose h4{font-size:15px; margin:0 0 8px; color:var(--ink)}
.prose p{color:var(--muted); line-height:1.65; margin:0 0 14px}
.prose .callout{background:var(--card); border-left:3px solid var(--brand); border-radius:0 3px 3px 0;
  padding:18px 20px; margin-top:8px}
.prose .callout p{margin:0}

/* -------------------------------------------------------- quote -- */
.quote{text-align:center; max-width:720px; margin:0 auto}
.quote blockquote{font-family:var(--disp); text-transform:none; font-weight:700; letter-spacing:.01em;
  font-size:clamp(22px,3.5vw,32px); line-height:1.2; margin:0 0 16px}
.quote cite{font-style:normal; color:var(--muted); font-size:14px}
.quote .portrait{width:80px; height:80px; border-radius:4px; object-fit:cover;
  border:1.5px solid var(--ink); margin:0 auto 18px; display:block}

/* -------------------------------------------------------- forms wells -- */
.formwell{background:var(--card); border:1px solid var(--line); border-radius:4px;
  padding:clamp(20px,4vw,32px)}
.formwell h3{font-family:var(--disp); text-transform:uppercase; letter-spacing:.03em; font-size:22px; margin:0 0 4px}
.or-rule{display:flex; align-items:center; gap:16px; color:var(--muted); margin:28px 0; font-weight:700;
  font-size:12px; letter-spacing:.12em; text-transform:uppercase}
.or-rule::before,.or-rule::after{content:""; flex:1; height:1px; background:var(--line)}

/* -------------------------------------------------------- footer -- */
.foot{background:var(--ink); color:var(--card); padding:clamp(40px,6vw,60px) 0 28px}
.foot__grid{display:grid; grid-template-columns:1.4fr 1fr 1fr 1fr; gap:32px}
.foot h4{font:700 12px/1 var(--disp); text-transform:uppercase; letter-spacing:.14em;
  color:rgba(249,251,246,.6); margin:0 0 16px}
.foot ul{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:10px}
.foot a{color:rgba(249,251,246,.82)}
.foot a:hover{color:var(--card)}
.foot .brand b{color:var(--card)}
.foot .brand img{border-radius:4px}
.foot p{color:rgba(249,251,246,.6); font-size:13.5px}
.foot__social{display:flex; gap:10px; margin-top:4px}
.foot__social a{width:38px; height:38px; border-radius:3px; border:1px solid rgba(249,251,246,.28);
  display:flex; align-items:center; justify-content:center; color:var(--card)}
.foot__social a:hover{background:var(--accent); border-color:var(--accent); color:var(--accent-ink)}
.foot__bar{border-top:1px solid rgba(249,251,246,.16); margin-top:36px; padding-top:22px;
  text-align:center; font-size:13px}
.foot__bar address{font-style:normal; color:rgba(249,251,246,.6)}
@media (max-width:760px){ .foot__grid{grid-template-columns:1fr 1fr} }
@media (max-width:460px){ .foot__grid{grid-template-columns:1fr} }

/* -------------------------------------------------------- back to top -- */
.totop{position:fixed; right:22px; bottom:22px; z-index:40; width:46px; height:46px;
  border:1.5px solid var(--ink); background:var(--card); color:var(--ink); border-radius:3px;
  box-shadow:var(--shadow-press); cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:18px}
.totop:active{transform:translate(2px,2px); box-shadow:0 0 0 var(--ink)}

/* ------------------------------------------------- phone booking bar -- */
/* public/_sticky_book.html. Phones only; the template's script adds .is-on
   between the hero button and the enrolment card/footer. It slides rather than
   appears, and being fixed it never moves the page. */
.stickybook{display:none}
@media (max-width:640px){
  .stickybook{position:fixed; left:0; right:0; bottom:0; z-index:45;
    display:flex; align-items:center; gap:10px; min-height:52px;
    padding:6px 12px calc(6px + env(safe-area-inset-bottom)) 16px;
    background:var(--card); border-top:1.5px solid var(--ink);
    transform:translateY(100%); visibility:hidden;
    transition:transform .2s ease, visibility 0s linear .2s}
  .stickybook.is-on{transform:none; visibility:visible; transition:transform .2s ease}
  .stickybook[hidden]{display:none}
  .stickybook__txt{flex:1; min-width:0; font-weight:700; font-size:14.5px; line-height:1.2; color:var(--ink)}
  .stickybook__book{padding:12px 16px; white-space:nowrap}
  .stickybook__call{flex:0 0 auto; width:40px; height:40px; display:grid; place-items:center;
    border:1.5px solid var(--ink); border-radius:3px; background:var(--card); color:var(--ink); font-size:16px}
  .stickybook__call:hover{color:var(--accent); border-color:var(--accent); text-decoration:none}
  /* Lift back-to-top clear of the bar while it is up. */
  .stickybook-on .totop{bottom:calc(52px + 16px + env(safe-area-inset-bottom))}
}

/* -------------------------------------------------------- utilities -- */
.center{text-align:center}
.mt-s{margin-top:16px}.mt-m{margin-top:28px}.mt-l{margin-top:44px}
.stack-8{display:flex; flex-direction:column; gap:8px}
.hide{display:none}

/* ================================================= blog / article prose === */
.article{max-width:68ch; margin:0 auto; font-size:16px; line-height:1.75; color:var(--ink)}
.article > *{margin:0 0 1.25em}
.article > *:last-child{margin-bottom:0}
.article h2{font-family:var(--disp); text-transform:uppercase; letter-spacing:.03em; font-size:1.7rem; line-height:1.1; margin:2em 0 .6em}
.article h3{font-size:1.3rem; margin:1.6em 0 .5em}
.article h4{font-size:1.05rem; margin:1.4em 0 .4em}
.article a{color:var(--brand); text-decoration:underline; text-underline-offset:2px}
.article ol{margin:0 0 1.25em 1.4em; padding:0; list-style:decimal}
.article ul{margin:0 0 1.25em 1.4em; padding:0; list-style:none}
.article li{margin:.4em 0}
.article ul > li{position:relative; padding-left:2px}
.article ul > li::before{content:""; position:absolute; left:-1.15em; top:.62em; width:8px; height:5.5px;
  background:var(--brand); border-radius:50%; transform:rotate(-12deg)}   /* tiny notehead bullet */
.article img{width:100%; height:auto; border:1px solid var(--line); border-radius:4px; margin:1.6em 0}
.article blockquote{border-left:3px solid var(--brand); padding:2px 0 2px 18px; margin:1.6em 0;
  color:var(--muted); font-style:italic}
.article blockquote p:last-child{margin-bottom:0}
.article pre{background:var(--ink); color:var(--card); padding:16px 18px; border-radius:4px; overflow-x:auto; font-size:.9em; line-height:1.5}
.article code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.9em}
.article :not(pre) > code{background:var(--card2); border:1px solid var(--line); border-radius:3px; padding:1px 5px}
.article table{width:100%; border-collapse:collapse; margin:1.6em 0; font-size:.95em; display:block; overflow-x:auto}
.article th,.article td{border:1px solid var(--line); padding:8px 11px; text-align:left}
.article th{background:var(--card2); font-weight:700}
.article hr{border:0; border-top:1px solid var(--line2); margin:2em 0}

/* blog listing cards + article chrome */
.postcard{padding:0; overflow:hidden}
.postcard .thumb{display:block; aspect-ratio:16/10; overflow:hidden; background:var(--ink); border-bottom:1px solid var(--line)}
.postcard .thumb img{width:100%; height:100%; object-fit:cover; display:block}
.postcard .body{padding:20px; display:flex; flex-direction:column; flex:1}
.postcard h2{font-size:18px; line-height:1.25; margin:0 0 8px; font-family:var(--body); font-weight:700}
.postcard h2 a{color:var(--ink)}
.postcard h2 a:hover{color:var(--brand); text-decoration:none}
.postcard .excerpt{color:var(--muted); font-size:14px; margin:0 0 16px; flex:1}
.postcard .meta{display:flex; justify-content:space-between; gap:10px; margin-top:auto;
  font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums}
.article-meta{display:flex; flex-wrap:wrap; gap:6px 14px; align-items:center; color:var(--muted); font-size:13px;
  font-variant-numeric:tabular-nums}
.article-nav{display:flex; justify-content:space-between; gap:16px; margin-top:56px; padding-top:24px;
  border-top:1px solid var(--line); font-weight:700; font-size:14px}
.article-nav a{color:var(--brand)}
.draft-banner{background:var(--warn-bg); color:var(--warn); text-align:center; font-weight:700;
  padding:12px 16px; border-bottom:1px solid var(--line2)}
