/* =============================================================================
   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)}
.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}
.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}

/* 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}

/* 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, full aspect ratio preserved from its own dimensions. */
.vidbox{display:flex; justify-content:center; background:var(--ink)}
.vidbox__el{display:block; height:auto; max-height:560px; max-width:100%}

/* 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}
/* Clamped by default so one long bio can't stretch the row; the Read-more
   button (rendered only when there is more) lifts the clamp. 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. */
.tprofile__bio{margin:1px 0 0; max-width:46ch; color:var(--muted); font-size:13.5px; line-height:1.55;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:4; overflow:hidden}
.tprofile__bio--full{display:block; overflow:visible}
/* 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)}

/* 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)}

/* -------------------------------------------------------- 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)}
