/* ============================================================
   Melanie Katz — Voice Over
   Layout follows Melanie's notes: name + branding left, demos right,
   then logos, then videos. No logo mark — the name is the brand.
   ============================================================ */

:root{
  --ink:#0F0E0C;
  --ink-2:#17150F;
  --ink-3:#211E16;
  --cream:#F5F1EA;
  --cream-dim:rgba(245,241,234,.62);
  --gold:#D4A94E;
  --gold-soft:rgba(212,169,78,.14);
  --paper:#FFFFFF;
  --maxw:1240px;
  --pad:clamp(20px,5vw,64px);
  --serif:"Fraunces",Georgia,"Times New Roman",serif;
  --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --ease:cubic-bezier(.2,.7,.2,1);
}

*{ box-sizing:border-box; }
html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; }
/* The header is fixed at 81px, so an anchor jump would otherwise park the
   section's first line underneath it — which is what was hiding "Trusted by".
   Offset every jump target by the header plus a little breathing room. */
:target, #top, #demos, #clients, #work, #about, #contact{ scroll-margin-top:104px; }
body{
  margin:0; background:var(--ink); color:var(--cream);
  font-family:var(--sans); font-size:17px; line-height:1.6;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
h1,h2,h3,p,ul,ol{ margin:0; padding:0; }
ul,ol{ list-style:none; }
a{ color:inherit; text-decoration:none; }
img{ max-width:100%; display:block; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
.mono{ font-variant-numeric:tabular-nums; letter-spacing:.02em; }
/* Labels an icon-only link for screen readers without giving the browser an
   accessible name to build a native tooltip from — Safari pops one of those
   white boxes on any link that has a name but no visible text. */
.sr-only{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0;
}
.wrap{ width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad); }

.eyebrow{
  font-size:12px; font-weight:600; letter-spacing:.24em; text-transform:uppercase;
  color:var(--gold); margin-bottom:18px;
}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; gap:.6em;
  padding:14px 26px; border-radius:2px; font-weight:500; font-size:15px;
  letter-spacing:.02em; border:1px solid transparent; white-space:nowrap;
  transition:background .2s, color .2s, border-color .2s, transform .2s var(--ease);
}
.btn:hover{ transform:translateY(-2px); }
.btn--solid{ background:var(--gold); color:#1A1508; border-color:var(--gold); font-weight:600; }
.btn--solid:hover{ background:#E2BB68; }
.btn--ghost{ border-color:rgba(245,241,234,.28); color:var(--cream); }
.btn--ghost:hover{ border-color:var(--cream); background:rgba(245,241,234,.06); }

/* ---------- header ---------- */
.site-header{
  position:fixed; inset:0 0 auto 0; z-index:60;
  display:flex; align-items:center; justify-content:space-between;
  padding:18px var(--pad); border-bottom:1px solid transparent;
  transition:background .3s, padding .3s, border-color .3s;
}
.site-header.scrolled{
  background:rgba(15,14,12,.93); backdrop-filter:saturate(150%) blur(12px);
  border-bottom-color:var(--ink-3); padding-block:12px;
}
.brand{ display:flex; flex-direction:column; line-height:1.1; }
.brand__name{ font-family:var(--serif); font-size:19px; font-weight:600; }
.brand__role{
  font-size:9.5px; font-weight:600; letter-spacing:.22em; text-transform:uppercase;
  color:var(--gold); margin-top:4px;
}
/* Header contact. Sits outside .nav on purpose — .nav becomes a full-screen
   overlay behind the hamburger below 900px, and these must never be hidden
   behind a tap. Inherits .social for the gold circles. */
.hdr-contact{ margin-left:auto; margin-right:20px; gap:8px; }
/* 30% down from the 40px circles used in the contact section — the header
   versions are a quick-access strip, not the main call to action.
   Doubled up on the class because .social a is defined later in this file with
   the same specificity, so a plain .hdr-contact a loses to it. */
.hdr-contact.social a{ width:28px; height:28px; }
.hdr-contact.social svg{ width:13px; height:13px; }

/* The phone is the exception: no circle, just the icon with the number beside
   it. A producer should be able to read the number without clicking anything. */
.hdr-contact.social .hdr-contact__tel a{
  width:auto; height:auto; border:0; border-radius:0;
  gap:7px; padding:2px 0;
  display:inline-flex; align-items:center;
  font-size:14px; font-weight:600; letter-spacing:.02em;
  color:var(--gold); background:none;
}
.hdr-contact.social .hdr-contact__tel a:hover{
  background:none; color:var(--cream); transform:none;
}
.hdr-contact.social .hdr-contact__tel svg{ width:16px; height:16px; }
.hdr-contact .hdr-contact__tel{ margin-right:6px; }

.nav{ display:flex; align-items:center; gap:28px; }
.nav a{ font-size:14px; font-weight:500; color:var(--cream-dim); transition:color .2s; }
.nav a:hover{ color:var(--cream); }
.nav a.btn{ color:var(--cream); padding:10px 20px; }
.nav-toggle{ display:none; width:44px; height:44px; }
.nav-toggle span{ display:block; width:24px; height:1.5px; background:var(--cream); margin:5px auto; transition:.3s; }

/* ---------- hero: intro left, demos right ---------- */
.hero{
  padding:clamp(120px,14vh,168px) 0 clamp(14px,1.5vw,20px);
  background:
    radial-gradient(85% 65% at 82% 14%, rgba(212,169,78,.13), transparent 62%),
    radial-gradient(65% 55% at 6% 92%, rgba(212,169,78,.05), transparent 62%),
    var(--ink);
}
/* Three columns: photo, name, demos. */
.hero__grid{
  /* Photo left, card right, both 30% down from 460/420. The type inside the
     card is scaled by the same factor (--card-scale) — shrinking the box alone
     would just push every line into wrapping. */
  --card-scale:.7;
  display:grid; grid-template-columns:minmax(0,322px) minmax(0,294px);
  justify-content:center;
  /* row gap kept tight — it is the space between the boxes and the trait words;
     the column gap between the three boxes stays wide */
  gap:clamp(8px,1vw,14px) clamp(26px,3.2vw,48px); align-items:stretch;
}
.hero__name{
  font-family:var(--serif); font-weight:300;
  font-size:calc(clamp(46px,5.4vw,82px) * var(--card-scale,1)); line-height:.9; letter-spacing:-.02em;
}
.hero__name em{ font-style:italic; font-weight:400; color:var(--gold); }
/* Sits between the name and the tagline. Deliberately cream rather than gold —
   the rotating roles just below are already gold, and two gold lines stacked
   under the name would fight each other. */
.hero__place{
  margin-top:14px;
  font-size:calc(11.5px * var(--card-scale,1)); font-weight:700; letter-spacing:.20em;
  text-transform:uppercase; color:#C08BFF;
}
/* Once the whole hero has settled, the line lights like a sign: a few flickers,
   then it keeps breathing. Two animations chained — the flicker runs once, and
   the pulse starts as it ends and continues. The pulse is listed second so it
   wins the text-shadow once its delay is up. */
.hero__place.is-lit{
  animation:vegasNeon 2.4s var(--ease) both,
            vegasPulse 4.2s ease-in-out 2.4s infinite;
}
@keyframes vegasNeon{
  0%   { text-shadow:none; }
  5%   { text-shadow:0 0 26px rgba(192,139,255,1), 0 0 58px rgba(192,139,255,.7); }
  9%   { text-shadow:none; }
  15%  { text-shadow:0 0 30px rgba(192,139,255,1), 0 0 70px rgba(192,139,255,.8); }
  20%  { text-shadow:0 0 4px rgba(192,139,255,.25); }
  28%  { text-shadow:0 0 34px rgba(192,139,255,1), 0 0 80px rgba(192,139,255,.85); }
  100% { text-shadow:0 0 20px rgba(192,139,255,.75), 0 0 46px rgba(192,139,255,.4); }
}
/* the resting breath — never fully off, so it reads as a lit sign not a blink */
@keyframes vegasPulse{
  0%,100% { text-shadow:0 0 18px rgba(192,139,255,.62), 0 0 40px rgba(192,139,255,.3); }
  50%     { text-shadow:0 0 34px rgba(192,139,255,1),   0 0 76px rgba(192,139,255,.6); }
}
@media (prefers-reduced-motion:reduce){
  .hero__place.is-lit{ animation:none; text-shadow:0 0 20px rgba(192,139,255,.7); }
}
.hero__tagline{
  font-family:var(--serif); font-size:calc(clamp(19px,2.1vw,26px) * var(--card-scale,1)); font-style:italic;
  font-weight:300; line-height:1.3; margin-top:22px; color:var(--cream);
  max-width:22ch;
}
.hero__credits{
  position:relative; height:1.6em; margin-top:20px;
  font-size:calc(11.5px * var(--card-scale,1)); letter-spacing:.16em; text-transform:uppercase; color:var(--gold);
}
.hero__credits span{
  position:absolute; left:0; top:0; white-space:nowrap;
  opacity:0; transform:translateY(5px);
  transition:opacity .45s var(--ease), transform .45s var(--ease);
}
/* incoming waits for the outgoing to clear, so they never overlap at full strength */
.hero__credits span.is-on{ opacity:1; transform:none; transition-delay:.35s; }
/* reduced motion: show them all, wrapped, no cycling */
.hero__credits.is-static{ position:static; height:auto; display:flex; flex-wrap:wrap; gap:6px 0; }
.hero__credits.is-static span{ position:static; opacity:1; transform:none; }
.hero__credits.is-static span + span::before{ content:"•"; margin:0 10px; color:rgba(212,169,78,.5); }
.hero__lead{
  margin-top:calc(22px * var(--card-scale,1)); color:var(--cream-dim);
  font-size:calc(16.5px * var(--card-scale,1)); line-height:1.75;
}
/* the number carries the credential, so it gets the display face and weight */
.hero__years{
  font-family:var(--serif); font-weight:600; font-size:2.1em;
  color:var(--cream); line-height:1; letter-spacing:-.02em;
  margin-right:2px; display:inline-block;
  font-variant-numeric:tabular-nums;   /* stops the line jittering as digits change */
}
.hero__years.is-counting{ color:var(--gold); }
.hero__years.is-done{ animation:yearPop .7s var(--ease); }
@keyframes yearPop{
  0%{ transform:scale(1); }
  40%{ transform:scale(1.22); color:var(--gold); }
  100%{ transform:scale(1); }
}
.hero__cta{ display:flex; flex-wrap:wrap; gap:12px; margin-top:30px; }

/* ---------- hero entrance ----------
   A staged curtain-up on first paint, kept distinct from the gestures already
   on the page: the three panels rise, the name wipes up from behind its own
   baseline, the tagline follows, and the photo settles out of a slow zoom.
   Nothing here touches the roles rotator, the 30 count-up or the trait blur —
   those still run exactly as before, layered on top.
   main.js adds .is-in on load; an observer is unreliable for content already on
   screen at first paint, which is why the traits are load-driven too. */
.hero__intro, .hero__photo, .hero__demos{
  opacity:0; transform:translateY(26px);
  transition:opacity 1.1s var(--ease), transform 1.1s var(--ease);
}
.hero.is-in .hero__intro{ opacity:1; transform:none; transition-delay:.05s; }
.hero.is-in .hero__photo{ opacity:1; transform:none; transition-delay:.18s; }
.hero.is-in .hero__demos{ opacity:1; transform:none; transition-delay:.31s; }

/* The mask. Padding plus a matching negative margin gives the italic and the
   tall caps room inside the clip without shifting the layout by a pixel. */
.hero__name .line{
  display:block; overflow:hidden;
  padding:.08em .1em; margin:-.08em -.1em;
}
.hero__name .line > *{
  display:block; transform:translateY(125%);
  transition:transform 1.15s var(--ease);
}
.hero.is-in .hero__name .line > *{ transform:none; }
.hero.is-in .hero__name .line:nth-child(1) > *{ transition-delay:.34s; }
.hero.is-in .hero__name .line:nth-child(2) > *{ transition-delay:.46s; }

.hero__tagline, .hero__place{
  opacity:0; transform:translateY(14px);
  transition:opacity .95s var(--ease), transform .95s var(--ease);
}
.hero.is-in .hero__place{ opacity:1; transform:none; transition-delay:.62s; }
.hero.is-in .hero__tagline{ opacity:1; transform:none; transition-delay:.76s; }

/* the photo eases out of a slow zoom rather than simply fading in */
.hero__photo img{ transform:scale(1.08); transition:transform 1.9s var(--ease); }
.hero.is-in .hero__photo img{ transform:none; transition-delay:.18s; }

@media (prefers-reduced-motion:reduce){
  .hero__intro, .hero__photo, .hero__demos, .hero__tagline, .hero__place{
    opacity:1; transform:none; transition:none;
  }
  .hero__name .line > *{ transform:none; transition:none; }
  .hero__photo img{ transform:none; transition:none; }
}

/* Trait words under the three hero boxes. Each one resolves out of a blur, in
   turn, and stays put — an entrance, not a loop. */
.traits{
  grid-column:1/-1; order:3;                 /* span beneath all three hero boxes */
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:10px clamp(20px,2.6vw,40px);
  margin-top:clamp(4px,0.5vw,8px);
}
.traits li{
  font-family:var(--serif); font-style:italic; font-weight:400;
  font-size:clamp(17px,1.8vw,23px); color:var(--gold);
  opacity:0; filter:blur(18px); transform:translateY(10px);
  transition:opacity 1.4s var(--ease), filter 1.4s var(--ease), transform 1.4s var(--ease);
}
/* The words are buttons now — they inherit the italic serif look, and turn
   purple on hover to say they do something. */
.traits .trait{
  font: inherit; color: inherit; letter-spacing: inherit;
  background: none; border: 0; padding: 0; cursor: pointer;
  transition: color .22s var(--ease), text-shadow .22s var(--ease);
}
.traits .trait:hover, .traits .trait:focus-visible{
  color: #C08BFF; text-shadow: 0 0 18px rgba(192,139,255,.55); outline: none;
}
.traits .trait.is-cued{ color: #C08BFF; text-shadow: 0 0 22px rgba(192,139,255,.7); }

.traits li.is-on{
  opacity:1; filter:blur(0); transform:none;
  /* white while it is still out of focus, still white at the moment it lands
     (1.4s), then it cools down into the gold */
  animation:traitSettle 2.4s var(--ease) forwards;
}
@keyframes traitSettle{
  0%,58%{ color:#fff; text-shadow:0 0 20px rgba(255,255,255,.30); }
  100%  { color:var(--gold); text-shadow:none; }
}
@media (prefers-reduced-motion:reduce){
  .traits li{ opacity:1; filter:none; transform:none; transition:none; }
  /* The words are buttons now — they inherit the italic serif look, and turn
   purple on hover to say they do something. */
.traits .trait{
  font: inherit; color: inherit; letter-spacing: inherit;
  background: none; border: 0; padding: 0; cursor: pointer;
  transition: color .22s var(--ease), text-shadow .22s var(--ease);
}
.traits .trait:hover, .traits .trait:focus-visible{
  color: #C08BFF; text-shadow: 0 0 18px rgba(192,139,255,.55); outline: none;
}
.traits .trait.is-cued{ color: #C08BFF; text-shadow: 0 0 22px rgba(192,139,255,.7); }

.traits li.is-on{ animation:none; }
}

/* ---------- hero photo ---------- */
/* Uncropped: the frame carries the source image's own 3:4, so cover has
   nothing to cut. Her head fills most of this 480x640 frame and every earlier
   crop attempt clipped her face. */
/* The photo now matches the demo panel's height. Filling a TALLER, narrower box
   crops horizontally, not vertically — so her chin is never at risk; it only
   trims a little of the mic side. */
.hero__photo{
  order:1; align-self:center;
  margin:0; border:1px solid var(--ink-3);
  width:100%; aspect-ratio:480/640; height:auto; overflow:hidden;
}
.hero__photo img{
  width:100%; height:100%; display:block;
  object-fit:cover; object-position:8% center;   /* her face is left of frame — crop from the mic side */
  filter:saturate(.94) contrast(1.02);
}
/* Panelled to match the demos, and set flush right so the text runs up against
   the photo in the centre. */
.hero__intro{
  order:2; align-self:center;
  display:flex; flex-direction:column; justify-content:center;
  text-align:left;
  border:1px solid var(--ink-3); border-radius:3px;
  background:linear-gradient(180deg, rgba(245,241,234,.035), rgba(245,241,234,.012));
  padding:26px 24px 30px;
}
.hero__intro .hero__tagline{ max-width:none; margin-right:auto; }
.hero__intro .hero__credits{ justify-content:flex-start; }
.hero__credits span{ left:0; right:auto; }

/* ---------- demos (in the hero, compact) ---------- */
/* The demos sit in their own panel so the column reads as a module rather than
   loose icons floating beside the name. */
.hero__demos{
  border:1px solid var(--ink-3); border-radius:3px;
  background:linear-gradient(180deg, rgba(245,241,234,.035), rgba(245,241,234,.012));
  /* tighter side padding buys the width the 13px labels need to stay 2 lines */
  padding:24px 13px 28px;
}
/* matched to .clients__label ("Trusted by") */
.demos__label{
  /* Larger than the other section labels (15px) — the demos are what a producer
     comes for — but not so large it dominates the hero. */
  font-size:20px; font-weight:600; letter-spacing:.28em; text-transform:uppercase;
  color:var(--gold); text-align:center;
  /* Tried aligning these cap-tops with the M of Melanie. It does not work in
     this layout: the demos panel already fills its row, so the shift has to
     make the hero taller, and it left dead space at the top of this panel and
     under the intro. Reverted. */
  margin-top:0; margin-bottom:22px;
  padding-bottom:18px; border-bottom:1px solid var(--ink-3);
}
/* Two rows on purpose: the two long titles share the top row at half width
   each, the three short ones sit together below. A six-column grid gives that
   exactly — 3+3 above, 2+2+2 below — and the extra width is what stops the
   labels stacking three and four lines deep. */
/* All five across one row. The old 3+2 split with its column spans existed
   only because the demos were squeezed into a hero column — with a band of
   their own they simply share five equal tracks. */
.demo-list{
  display:grid; grid-template-columns:repeat(5,1fr);
  gap:0 clamp(14px,2.4vw,40px); justify-items:center;
  max-width:1040px; margin-inline:auto;
}
.demo{ width:100%; max-width:190px; }
.demo{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:10px; cursor:pointer;
}
.demo__play{
  width:56px; height:56px; border-radius:50%;
  border:1px solid rgba(245,241,234,.24); color:var(--cream);
  display:grid; place-items:center; flex:none;
  transition:background .25s, border-color .25s, color .25s, transform .25s var(--ease);
}
.demo__play svg{ width:24px; height:24px; fill:currentColor; margin-left:2px; }
/* One button, two glyphs — the pause bars replace the triangle while that demo
   is sounding, so the control says what it will do rather than what it did. */
.demo__play .i-pause{ display:none; }
.demo.is-playing .demo__play .i-play{ display:none; }
.demo.is-playing .demo__play .i-pause{ display:inline; }
/* the bars are optically centred, unlike the triangle */
.demo.is-playing .demo__play svg{ margin-left:0; }
.demo.is-playing .demo__play{
  background:var(--gold); border-color:var(--gold); color:#1A1508;
}
/* Download the MP3 — a producer pulling a demo to send on, without needing to
   ask for an audition. Quiet until hovered so it never competes with play. */
.demo__dl{
  display:inline-flex; align-items:center; gap:6px;
  font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(245,241,234,.42);
  padding:4px 2px; transition:color .22s;
}
.demo__dl svg{ width:15px; height:15px; }
.demo__dl:hover, .demo__dl:focus-visible{ color:var(--gold); }
.demo:hover .demo__dl{ color:rgba(245,241,234,.68); }
.demo:hover .demo__dl:hover{ color:var(--gold); }
/* The triangle picks up the purple on hover — the svg is fill:currentColor, so
   the colour here drives it. The ring stays gold so the button still reads as
   part of the gold system. */
.demo:hover .demo__play{ border-color:var(--gold); color:#C08BFF; transform:scale(1.07); }
.demo:hover .demo__play svg{ filter:drop-shadow(0 0 7px rgba(192,139,255,.65)); }
/* playing beats hovering — a gold triangle on the gold fill would vanish */
.demo.is-active:hover .demo__play{ color:#1A1508; }
.demo.is-active:hover .demo__play svg{ filter:none; }
.demo.is-active .demo__play{
  background:var(--gold); border-color:var(--gold); color:#1A1508;
  box-shadow:0 0 0 6px rgba(212,169,78,.12);
}
.demo__title{
  /* was capped at 14ch, which is what forced the long titles three and four
     lines deep — the tile width governs the wrap now */
  max-width:100%;
  font-size:13px; font-weight:600; line-height:1.4; letter-spacing:.02em;
  color:var(--cream-dim); text-transform:uppercase;
  transition:color .25s;
}
.demo:hover .demo__title, .demo.is-active .demo__title{ color:var(--cream); }

.ai-notice{
  margin-top:22px; font-size:10.5px; line-height:1.5;
  color:rgba(245,241,234,.42); text-align:center;
}

/* The gold rules on both black bands fade out to nothing at the left and right
   rather than butting into the viewport edge. Drawn as pseudo-elements because
   a border can't carry a gradient; the 9%/91% stops match the marquee's own
   mask, so a logo and the rules above and below it fade over the same span. */
.clients::before, .clients::after,
.band::before,    .band::after,
.about__panel::before, .about__panel::after{
  content:""; position:absolute; left:0; right:0; height:2px; pointer-events:none;
  background:linear-gradient(90deg, transparent, var(--gold) 9%, var(--gold) 91%, transparent);
}
/* The two black bands touch, so one rule serves as the divider between them.
   Videos come first now, so its bottom rule is the seam and the logo band's own
   top rule is suppressed — otherwise the two stack into a double line. */
.clients::before{ display:none; }
.band::before, .about__panel::before{ top:0; }
.clients::after,  .band::after,  .about__panel::after{ bottom:0; }

/* ---------- clients: dark band, endless marquee ---------- */
.clients{
  background:#000; padding:34px 0 38px;
  position:relative; overflow:hidden;
}
/* one style for every black-band label: TRUSTED BY, ON SCREEN */
.clients__label, .band__label{
  font-size:15px; font-weight:600; letter-spacing:.28em; text-transform:uppercase;
  color:var(--gold); text-align:center; margin-bottom:28px;
}
/* ABOUT MELANIE runs a touch larger than the other section labels at Melanie's
   request — TRUSTED BY and SELECTED WORK stay at 15px — and carries the same
   purple neon as "Based in Las Vegas": one flicker on arrival, then a resting
   breath. Reuses the vegasNeon / vegasPulse keyframes rather than duplicating
   them, so the two stay in step if either is retuned. */
#about .band__label{ font-size:18px; color:#C08BFF; }
#about .band__label.is-lit{
  animation:vegasNeon 2.4s var(--ease) both,
            vegasPulse 4.2s ease-in-out 2.4s infinite;
}
@media (prefers-reduced-motion:reduce){
  #about .band__label.is-lit{ animation:none; text-shadow:0 0 20px rgba(192,139,255,.7); }
}
.marquee{
  position:relative; overflow:hidden;
  cursor:grab; touch-action:pan-y;   /* drag to scrub; vertical swipes still scroll the page */
  user-select:none; -webkit-user-select:none;
  /* fade the ends so logos enter and leave rather than being chopped */
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image:linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.marquee.is-dragging{ cursor:grabbing; }
.marquee__track{
  display:flex; align-items:center; gap:clamp(38px,5vw,72px);
  width:max-content; will-change:transform;
}
.marquee__track img{ -webkit-user-drag:none; user-drag:none; }
.marquee__track img{
  height:46px; width:auto; max-width:none; object-fit:contain;
  opacity:.88; transition:opacity .25s;
}
/* Apple TV, Splunk, TCA and Lionsgate are near-black marks meant for light
   backgrounds — measured luminance 0.00 to 0.30, so in full colour they vanish
   here. Reversing them to white is what each brand's own guidelines specify for
   dark backgrounds. Add `class="reverse"` to any future logo that's too dark. */
/* Wide wordmarks that carry too much optical weight at the 46px default. The
   class names are the first cut each one took; the comment is the running total,
   since several have been trimmed again since. */
.marquee__track img.sm{ height:33px; }    /* Lionsgate: 28% down from 46px */
.marquee__track img.sm15{ height:35px; }  /* Launch: 24% down from 46px */
.marquee__track img.sm10{ height:41px; }  /* Workato, Ellucian: 10% down from 46px */
/* Square/tall marks (Maker, Porsche, Warner Bros, TCA) need more height than a
   wordmark to carry the same optical weight in the row. */
.marquee__track img.tall{ height:64px; }
.marquee__track img.reverse{ filter:brightness(0) invert(1); opacity:.8; }
/* First load only: the row starts dark and each logo fades up in turn, left
   edge rightward. The loop is NOT held — the row is already travelling, so the
   logos fade and move at once. main.js adds .is-intro at parse time and removes
   it once the sweep is done (which also reveals anything still off-screen), so
   with JS disabled the logos simply render as normal. */
.marquee__track li{ transition:opacity 1.6s var(--ease); }
.marquee__track.is-intro li{ opacity:0; }
.marquee__track.is-intro li.up{ opacity:1; }

@media (prefers-reduced-motion:reduce){
  /* reduced motion: no loop, no drag — just a static wrapped row */
  .marquee__track{ flex-wrap:wrap; justify-content:center; width:auto; transform:none !important; }
  .marquee{ -webkit-mask-image:none; mask-image:none; cursor:default; }
  .marquee__track li, .marquee__track.is-intro li{ opacity:1; transition:none; }
}

/* ---------- sections ---------- */
.section{ padding:clamp(64px,8.5vw,116px) 0; }
/* About follows the video band directly — it doesn't need the band's gap AND a
   full section pad on top of it. */
#about{ padding-top:clamp(40px,4.5vw,64px); }
.section--alt{ background:var(--ink-2); }
/* About runs straight into the contact block; the two default section paddings
   stacked up to ~250px of empty band between the last spec and LET'S CHAT. */
.section--alt{ padding-bottom:clamp(28px,3.2vw,44px); }
.section-head{ max-width:640px; margin-bottom:clamp(34px,4.5vw,56px); }
.section-head h2, .about h2, .cta h2{
  font-family:var(--serif); font-weight:300;
  font-size:clamp(34px,5vw,60px); line-height:1.04; letter-spacing:-.02em;
}

/* the work section is a black band like the logo wall */
/* The waveform rule occupying the gap between the two black bands. Full width,
   masked at both ends on the same 9%/91% stops as the band rules and the
   marquee, so it dissolves rather than stopping dead. */
.wave-rule{
  /* LAYOUT PREVIEW: last row of the hero grid, spanning all three columns so
     it runs below her photo. */
  grid-column:1/-1; order:4;
  width:min(860px, 72%); margin:clamp(10px,1.4vw,20px) auto 0;
  height:clamp(150px,16vw,215px);   /* taller strip = bigger absolute swing */
  /* a long dissolve — fully transparent at both edges, so it reads as the rule
     emerging out of the background rather than being cut off by a mask edge */
  -webkit-mask-image:linear-gradient(90deg, transparent 0%, #000 34%, #000 66%, transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0%, #000 34%, #000 66%, transparent 100%);
  opacity:0; transition:opacity 1.4s var(--ease);
}
.wave-rule.is-in{ opacity:1; }
/* The transport that used to live in the sticky pop-up. Hidden until a demo is
   playing, so the rule is a plain divider the rest of the time. */
.wave-rule__meta{
  display:flex; align-items:center; justify-content:center; gap:14px;
  margin-top:8px; font-size:13px; color:var(--cream-dim);
  opacity:0; transform:translateY(-6px); pointer-events:none;
  transition:opacity .4s var(--ease), transform .4s var(--ease);
}
.wave-rule.is-open .wave-rule__meta{ opacity:1; transform:none; pointer-events:auto; }
.wave-rule__btn{
  width:30px; height:30px; border-radius:50%; flex:0 0 auto;
  border:1px solid var(--gold); color:var(--gold);
  display:grid; place-items:center; font-size:11px; line-height:1;
  transition:background .2s, color .2s;
}
.wave-rule__btn:hover{ background:var(--gold); color:#1A1508; }
.wave-rule__title{ font-weight:600; color:var(--cream); white-space:nowrap; }
.wave-rule__time{ font-variant-numeric:tabular-nums; }
.wave-rule__close{ color:var(--cream-dim); font-size:13px; padding:4px 6px; }
.wave-rule__close:hover{ color:var(--cream); }
/* only a scrubber while something is playing */
.wave-rule.is-open canvas{ cursor:pointer; }
.wave-rule canvas{
  display:block; width:100%; height:100%;
  /* the faint zero line a scope traces against */
  background:linear-gradient(180deg, transparent calc(50% - 0.5px),
             rgba(212,169,78,.14) calc(50% - 0.5px), rgba(212,169,78,.14) calc(50% + 0.5px),
             transparent calc(50% + 0.5px));
}
/* Idle <-> live swap: it drops away, is repainted while invisible, then springs
   back. transform is on the canvas so the CSS mask on the host is unaffected. */
.wave-rule canvas{
  transition:opacity .34s var(--ease), transform .34s var(--ease);
  transform-origin:50% 50%;
}
.wave-rule.is-out canvas{ opacity:0; transform:scaleY(.28); }
.wave-rule.is-pop canvas{ animation:waveRulePop .68s var(--ease); }
@keyframes waveRulePop{
  0%   { opacity:0; transform:scaleY(.28); }
  46%  { opacity:1; transform:scaleY(1.22); }
  72%  { transform:scaleY(.94); }
  100% { opacity:1; transform:scaleY(1); }
}
@media (prefers-reduced-motion:reduce){
  .wave-rule canvas{ transition:none; }
  .wave-rule.is-out canvas{ opacity:1; transform:none; }
  .wave-rule.is-pop canvas{ animation:none; }
}
@media (prefers-reduced-motion:reduce){
  .wave-rule{ opacity:1; transition:none; }
}

/* The demos band. Same black + gold rules as the videos, and it butts straight
   onto them so the two read as one block of samples. */
.demos-band{ padding:36px 0 40px; margin-top:clamp(30px,3.6vw,52px); }
.demos-band .demos__label{ border-bottom:0; padding-bottom:0; margin-bottom:26px; }
/* One line. The 66ch measure was sized for the old narrow hero column; in a
   full-width band the sentence fits across, and wrapping it read as a stray
   second line rather than a paragraph. */
.demos-band .ai-notice{ max-width:none; margin-inline:auto; text-align:center; white-space:nowrap; }
@media (max-width:1100px){
  /* below this it genuinely does not fit — let it wrap rather than overflow */
  .demos-band .ai-notice{ white-space:normal; max-width:70ch; }
}
/* one rule at the seam between demos and videos */
.demos-band + .band{ margin-top:0; }
.demos-band + .band::before{ display:none; }

/* breathing room so the two black bands read as separate blocks rather than
   one continuous slab */
.band{
  background:#000; padding:40px 0 46px;
  position:relative;
  margin-top:clamp(30px,3.6vw,52px); margin-bottom:0;   /* clears the hero */
}

/* ---------- video carousel (3D coverflow) ---------- */
.carousel{
  position:relative; max-width:1180px; margin-inline:auto;
  padding:0 clamp(0px,4vw,54px); overflow:hidden;
}
/* the stage: side slides fly out past this box, which is why the parent clips */
.car__viewport{
  position:relative; width:min(480px,69%); margin-inline:auto;   /* 20% down from 600px/86% */
  aspect-ratio:16/9; perspective:1500px; perspective-origin:50% 50%;
}
.car__track{
  position:absolute; inset:0; margin:0; padding:0;
  transform-style:preserve-3d;
}
.car__slide{
  position:absolute; inset:0; list-style:none;
  transition:transform .62s var(--ease), opacity .62s var(--ease), filter .62s var(--ease);
  backface-visibility:hidden; will-change:transform,opacity;
}
/* only the front slide gets full contrast; the rest sit back and dim */
.car__slide:not(.is-front){ filter:saturate(.55) brightness(.72); cursor:pointer; }
.car__slide:not(.is-front) .video{ pointer-events:none; }   /* click selects, not plays */
.car__slide.is-front .video{ box-shadow:0 26px 60px -24px rgba(0,0,0,.85); }

/* Type tag. Melanie's note: some of these are show work and two are
   commercials, and the section title alone could not carry that distinction. */
.video__kind{
  position:absolute; top:10px; left:10px; z-index:4;
  font-style:normal; font-size:10px; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase;
  padding:5px 9px; border-radius:2px;
  background:rgba(10,9,7,.82); backdrop-filter:blur(4px);
  border:1px solid rgba(212,169,78,.5); color:var(--gold);
}
.video__kind.kind--commercial{ border-color:rgba(150,215,255,.55); color:#96D7FF; }
.video__kind.kind--corporate{ border-color:rgba(245,241,234,.4); color:rgba(245,241,234,.8); }
/* the tag belongs to the front slide — behind it, it is just clutter */
.car__slide:not(.is-front) .video__kind{ opacity:0; transition:opacity .4s var(--ease); }

.car__nav{
  position:absolute; top:50%; transform:translateY(-50%); z-index:20;
  width:46px; height:46px; border-radius:50%;
  border:1px solid var(--ink-3); background:rgba(15,14,12,.8);
  color:var(--cream-dim); display:grid; place-items:center;
  transition:color .2s, border-color .2s, background .2s;
}
.car__nav svg{ width:20px; height:20px; }
.car__nav:hover{ color:var(--gold); border-color:var(--gold); background:var(--ink); }
.car__prev{ left:4px; }
.car__next{ right:4px; }

.car__dots{ display:flex; justify-content:center; gap:9px; margin-top:26px; }
.car__dot{
  width:7px; height:7px; border-radius:50%; padding:0;
  background:rgba(245,241,234,.25); transition:background .25s, transform .25s var(--ease);
}
.car__dot.is-on{ background:var(--gold); transform:scale(1.35); }

.video{
  position:relative; aspect-ratio:16/9; width:100%;
  background:var(--ink-2) center/cover no-repeat;
  display:flex; flex-direction:column; justify-content:flex-end; align-items:flex-start;
  padding:20px; text-align:left; border:1px solid var(--ink-3);
  transition:border-color .25s;
}
.video::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(to top, rgba(15,14,12,.86) 0%, rgba(15,14,12,.12) 58%, transparent 100%);
}
.video::before{
  content:"\25B6"; position:absolute; inset:0; display:grid; place-items:center;
  font-size:30px; color:var(--cream); opacity:.9; z-index:2;
  transition:opacity .25s, transform .25s var(--ease), color .25s, text-shadow .25s;
}
.video:hover{ border-color:var(--gold); }
/* the play triangle goes purple on hover, matching the demo buttons; the frame
   stays gold so the tile still sits in the gold system */
.video:hover::before{
  opacity:1; transform:scale(1.12); color:#C08BFF;
  text-shadow:0 0 12px rgba(192,139,255,.65);
}
.video span, .video small{ position:relative; z-index:2; }
.video span{ font-size:16px; font-weight:600; }
.video small{ font-size:12px; color:var(--cream-dim); letter-spacing:.06em; text-transform:uppercase; }
.video.is-playing::before, .video.is-playing::after{ content:none; }
.video video{
  position:absolute; inset:0; width:100%; height:100%; border:0; z-index:3;
  /* contain, not cover — the three Coupa films are 640x160, and cropping them
     to 16:9 would cut the picture rather than letterbox it */
  object-fit:contain; background:#000;
}

/* ---------- about ---------- */
.about{ display:block; }
/* Selector doubled up on purpose: the shared `.about h2` rule above is (0,1,1)
   and was beating a plain `.about__h2` (0,1,0) no matter the order, so this
   headline had always been rendering at the shared 60px. */
.about h2.about__h2{
  font-family:var(--serif); font-weight:300;
  font-size:clamp(28px,3.9vw,50px); line-height:1.1; letter-spacing:-.02em;
  text-align:center; max-width:34ch; margin:0 auto clamp(34px,4vw,52px);
}
/* One column of running paragraphs. It was set in two columns because a single
   1100px measure runs to ~130 characters a line, which is unreadable — so the
   fix is not full width, it is a constrained measure: ~68 characters, centred,
   with a little more size and leading than the two-column version needed. */
.about__body{
  max-width:68ch; margin-inline:auto;
}
.about__body p{
  color:var(--cream-dim); margin:0 0 22px;
  font-size:17.5px; line-height:1.78;
}
.about__body p:last-child{ margin-bottom:0; }
.about__kicker{
  color:var(--cream); font-family:var(--serif); font-size:clamp(26px,3.1vw,38px);
  font-style:italic; text-align:center; margin:0 auto;   /* the panel's padding owns this space now */
  white-space:nowrap;
  max-width:100%;
}
/* the emphasised word carries the same purple as the Vegas line and the
   About Melanie label */
.about__kicker em{ color:#C08BFF; font-style:italic; }
/* The kicker resolves out of a blur, word by word — deliberately unlike
   anything else on the page (the traits slide, the logos fade, the 30 counts).
   main.js splits the line into .w spans and adds .kick, so with no JS the
   sentence just sits there fully legible. */
.about__kicker.kick .w{
  display:inline-block;
  opacity:0; filter:blur(18px); transform:translateY(12px);
  transition:opacity 1.5s var(--ease), filter 1.5s var(--ease), transform 1.5s var(--ease);
}
.about__kicker.kick .w.in{ opacity:1; filter:blur(0); transform:none; }
/* the gold word carries a glow while it is still out of focus */
.about__kicker.kick em.w{ text-shadow:0 0 30px rgba(212,169,78,.6); transition:opacity 1.5s var(--ease), filter 1.5s var(--ease), transform 1.5s var(--ease), text-shadow 1.9s var(--ease); }
.about__kicker.kick em.w.in{ text-shadow:none; }
@media (prefers-reduced-motion:reduce){
  .about__kicker.kick .w{ opacity:1; filter:none; transform:none; transition:none; text-shadow:none; }
}
@media (max-width:700px){ .about__kicker{ white-space:normal; } }

/* Studio Equipment · Vocal Profile · How We Connect */
/* The panel holds the pull quote and the rider as one block: full-bleed black,
   with the fading gold rules top and bottom. Its inner .wrap keeps the content
   on the same column as the copy above. */
.about__panel{
  position:relative; background:#000;
  margin-top:clamp(30px,3.6vw,46px);
  padding:clamp(18px,2vw,26px) 0 clamp(30px,3.4vw,44px);
}
.about__panel > .wrap{
  display:flex; flex-direction:column; gap:clamp(26px,3vw,38px);
}
/* Two stacked rows rather than two columns — the chips wrap on their own, and
   a column split just reintroduces the dead space this replaced. */
.about__specs{
  display:flex; flex-direction:column; gap:clamp(16px,1.8vw,22px);
}
.spec{ display:flex; flex-direction:column; align-items:center; gap:12px; }
.spec h3{
  font-size:16px; font-weight:600; letter-spacing:.22em; text-transform:uppercase;
  color:var(--gold); margin:0; text-align:center;
}
.speclist{ display:flex; flex-wrap:wrap; justify-content:center; gap:9px 10px; }
.speclist li{
  color:var(--cream); font-size:14px; line-height:1;
  padding:9px 14px; border:1px solid var(--gold); border-radius:2px;
  background:rgba(212,169,78,.07);
  transition:background .3s var(--ease), color .3s var(--ease);
}
.speclist li:hover{ background:rgba(212,169,78,.16); }
.speclist li span{ color:var(--cream); }


/* ---------- cta ---------- */
/* Carries the About section's warm tint (--ink-2) all the way down to the
   footer, so there is no tonal step between the two — the page darkens once,
   at the footer rule, rather than twice. */
.cta{
  text-align:center; background:var(--ink-2);
  padding-top:clamp(22px,2.4vw,32px); padding-bottom:clamp(30px,3.4vw,44px);
}

/* Contact entrance, on scroll into view. The headline wipes up from behind its
   baseline exactly as her name does in the hero — the two ends of the page use
   the same gesture — and everything under it follows in turn. */
.cta .eyebrow, .cta__lead, .cta__row, .cta__note{
  opacity:0; transform:translateY(16px);
  transition:opacity .9s var(--ease), transform .9s var(--ease);
}
.cta h2 .line{ display:block; overflow:hidden; padding:.08em .1em; margin:-.08em -.1em; }
.cta h2 .line > *{ display:block; transform:translateY(125%); transition:transform 1.1s var(--ease); }

.cta.is-in .eyebrow{ opacity:1; transform:none; transition-delay:.04s; }
.cta.is-in h2 .line > *{ transform:none; transition-delay:.20s; }
.cta.is-in .cta__lead{ opacity:1; transform:none; transition-delay:.50s; }
.cta.is-in .cta__row{ opacity:1; transform:none; transition-delay:.66s; }
.cta.is-in .cta__note{ opacity:1; transform:none; transition-delay:.82s; }

@media (prefers-reduced-motion:reduce){
  .cta .eyebrow, .cta__lead, .cta__row, .cta__note{ opacity:1; transform:none; transition:none; }
  .cta h2 .line > *{ transform:none; transition:none; }
}
.cta h2{ max-width:none; white-space:nowrap; }
@media (max-width:640px){ .cta h2{ white-space:normal; } }
/* Wider measure so the two sentences sit on one line on a normal screen. */
.cta__lead{ max-width:60ch; margin:20px auto 0; color:var(--cream-dim); }
/* inline-block keeps the closing sentence whole — it moves to the next line as
   a unit rather than breaking after "get back to" */
.cta__lead .keep{ display:inline-block; }
.cta__row{ display:flex; flex-wrap:wrap; gap:14px; justify-content:center; margin-top:34px; }
.cta__note{ margin-top:22px; font-size:13px; color:var(--cream-dim); letter-spacing:.06em; }

/* ---------- footer ---------- */
.site-footer{
  border-top:1px solid var(--ink-3); padding:26px var(--pad);
  display:flex; justify-content:center; align-items:center; gap:18px 26px; flex-wrap:wrap;
  font-size:13px; color:var(--cream-dim);
}

/* Social. Gold-outlined circles, matching the chips and the section rules. */
.social{ display:flex; align-items:center; gap:12px; justify-content:center; }
.cta .social{ margin-top:26px; }
.social a{
  width:40px; height:40px; border-radius:50%;
  display:grid; place-items:center;
  border:1px solid rgba(212,169,78,.55); color:var(--gold);
  transition:background .22s, color .22s, border-color .22s, transform .22s var(--ease);
}
.social a:hover, .social a:focus-visible{
  background:var(--gold); color:#1A1508; border-color:var(--gold); transform:translateY(-2px);
}
.social svg{ width:19px; height:19px; }

/* ---------- sticky player ---------- */


/* ---------- reveal ---------- */
.reveal{ transition:opacity .7s var(--ease), transform .7s var(--ease); }
html.js .reveal{ opacity:0; transform:translateY(18px); }
html.js .reveal.in{ opacity:1; transform:none; }

@media (prefers-reduced-motion:reduce){
  *{ animation:none !important; scroll-behavior:auto; }
  html.js .reveal{ opacity:1 !important; transform:none !important; }
  .btn:hover{ transform:none; }
}

/* ---------- responsive ---------- */
/* name + photo share row one, demos take the full width below */
@media (max-width:1120px){
  .hero__grid{ grid-template-columns:1.3fr .7fr; gap:36px; }
  .hero__demos{ grid-column:1/-1; }
}
@media (max-width:760px){
  .hero__grid{ grid-template-columns:1fr; gap:32px; }
  .hero__tagline{ max-width:none; }
  .about__body{ columns:1; }

  /* Single column on a phone, so the right-alignment that pins the name to the
     photo on desktop has nothing to align against — everything centres instead,
     her photo included. */
  .hero__intro{ text-align:center; }
  .hero__intro .hero__tagline{ margin-left:auto; margin-right:auto; }
  .hero__lead{ margin-left:auto; margin-right:auto; }
  .hero__place{ text-align:center; }
  .hero__name .line > *{ text-align:center; }

  /* the rotating role sits in an absolutely positioned slot — it has to be
     stretched across the row before text-align can centre it */
  .hero__intro .hero__credits{ justify-content:center; }
  .hero__credits span{ left:0; right:0; text-align:center; }
  .hero__credits.is-static{ justify-content:center; }

  .hero__photo{ max-width:320px; margin-left:auto; margin-right:auto; }
}
@media (max-width:900px){
  .hdr-contact{ margin-right:12px; gap:7px; }
  .nav-toggle{ display:block; z-index:80; position:relative; }
  .nav{
    position:fixed; inset:0; background:var(--ink);
    flex-direction:column; justify-content:center; gap:28px;
    transform:translateX(100%); transition:transform .35s var(--ease); z-index:70;
  }
  .nav.open{ transform:none; }
  .nav a{ font-size:22px; color:var(--cream); }
}
@media (max-width:600px){
  /* At half a phone's width the two long titles run to three lines. Give them
     the full row so each still reads in two, and keep the short three together
     underneath. */
  /* five across is too tight on a phone — two rows instead */
  .demo-list{ grid-template-columns:repeat(2,1fr); gap:26px 14px; }
  .demo{ max-width:none; }
  /* email and phone stay; the social three would crowd the hamburger and are
     already in the contact section and the footer */
  .hdr-contact__social{ display:none; }
  .hdr-contact.social a{ width:30px; height:30px; }   /* a little back for touch */
  /* the number stays readable on a phone — it fits, it just needs to stop
     touching the wordmark, so it runs a shade smaller here */
  .hdr-contact.social .hdr-contact__tel a{ font-size:12.5px; gap:5px; }
  .hdr-contact.social .hdr-contact__tel svg{ width:14px; height:14px; }
  .hdr-contact{ margin-left:14px; }
  .demo{ grid-template-columns:34px 1fr; row-gap:6px; padding:12px 13px; }
  .demo__time{ grid-column:2; }
  /* the transport wraps rather than squeezing the title off-screen */
  .wave-rule__meta{ flex-wrap:wrap; gap:8px 12px; font-size:12px; }
}
