/* Hero. Owner: hero agent (docs/portfolio-review-06/BUILD-CONTRACT.md). Loads after kinetic.css.
   The intro film's last frame is the still behind the hero. States on .hero[data-state], set before paint by the
   inline boot script in the section and then by hero.js:
     film     the intro plays over the still; the copy waits off its marks
     handoff  the film fades (600 ms) to reveal the identical still
     intro    motion on but no film to play: the copy waits for hero.js to bring it in
     page     the copy is in (it moves in when hero.js switches here; it is simply there on a settled load)
   Motion off or reduced: everything settled, no push, no sweep. */

.hero{
  --hero-night:#121311;--hero-ink:#F4F0E8;--hero-copper:#DCA17D;
  --hero-ease:cubic-bezier(.16,1,.3,1);          /* approach: fast arrival, soft landing */
  --hero-fade:600ms;
  --hero-focus:50% 50%;
  position:relative;isolation:isolate;overflow:clip;
  min-height:100vh;min-height:100svh;
  padding:calc(var(--bar-h) + 20px) 0 0;         /* the bar is fixed and transparent over the hero */
  display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr) auto;align-content:stretch;
  background:var(--hero-night);color:var(--hero-ink);
}

/* picture: still underneath, film on top; both cover the hero the same way so the hand-off is seamless */
.hero-media{position:absolute;inset:0;z-index:-1;overflow:hidden;background:var(--hero-night)}
.hero-media picture,.hero-still,.hero-film{position:absolute;inset:0;width:100%;height:100%;max-width:none}
.hero-still,.hero-film{object-fit:cover;object-position:var(--hero-focus)}
.hero-still{transform-origin:72% 50%;will-change:transform}
.hero-film{opacity:0;transition:opacity 260ms ease;background:transparent}
.hero-film.is-on{opacity:1}
.hero[data-state="handoff"] .hero-film{opacity:0;transition-duration:var(--hero-fade)}
/* a flat dim, not a gradient: it settles over the picture as the words arrive, for contrast */
.hero-media::after{content:"";position:absolute;inset:0;background:var(--hero-night);opacity:0;transition:opacity 1.4s var(--hero-ease)}
.hero:not([data-film]):not([data-state="film"]):not([data-state="handoff"]) .hero-media::after{opacity:.5}

/* slow continuous push on the still, about 1.5% a second at first, easing and returning */
@keyframes hero-push{from{transform:scale(1)}to{transform:scale(1.32)}}
html[data-motion="on"] .hero[data-state="page"] .hero-still{animation:hero-push 28s cubic-bezier(.35,.45,.55,1) infinite alternate}
.hero[data-offscreen] .hero-still{animation-play-state:paused}

/* copy. The headline is a data-kt-stack: when line two lands, kinetic.css scales line one to .72 and dims it,
   so line one is set at size / .72 to land at the storyboard's proportions (64 over 112 desktop, 26 over 54 phone). */
.hero-copy{position:relative;z-index:1;align-self:end;padding:0 var(--gutter) 26px;max-width:1320px}
/* small copper type over a picture: a flat dark backing keeps it at 4.5:1 whatever the tiles behind it do */
.hero .hero-eyebrow{display:inline-block;color:var(--hero-copper);font:600 12px/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;margin:0 0 14px -10px;padding:6px 10px;border-radius:3px;background:rgb(18 19 17 / .78)}
.hero .hero-title{
  font-family:var(--kt-font,var(--sans));font-weight:800;letter-spacing:-.045em;line-height:.92;margin:0 0 20px;
  font-size:clamp(40px,13.8vw,62px);
}
.hero .hero-title .kt-line{display:block}
.hero .hero-title .kt-line:first-child{font-size:.66em;line-height:1;margin-bottom:.12em}
.hero .hero-title .kt-line:last-child{max-width:10.6em}
.hero .hero-lead{font-size:16px;line-height:1.55;color:rgb(244 240 232 / .88);max-width:36ch;margin:0 0 22px}
.hero .hero-actions{display:flex;flex-wrap:wrap;gap:10px 12px;align-items:center}
.hero .hero-actions .pill{min-height:48px}
.hero .hero-actions .arrow{display:inline-block}

/* film controls: pills like the films' home. Bottom centre on a phone while the film plays, top left otherwise. */
.hero-ctl{position:absolute;z-index:3;left:0;right:0;bottom:calc(22px + env(safe-area-inset-bottom,0px));display:flex;justify-content:center;gap:8px;padding:0 var(--gutter);pointer-events:none}
.hero-ctl > *{pointer-events:auto}
.hero:not([data-state="film"]) .hero-ctl{bottom:auto;top:calc(var(--bar-h) + 12px);justify-content:flex-start}
.hero-vbtn{
  display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 18px;border-radius:999px;
  border:1px solid rgb(244 240 232 / .7);background:rgb(18 19 17 / .62);color:var(--hero-ink);
  font:500 15px/1 var(--sans);cursor:pointer;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:background .18s,color .18s,border-color .18s,transform .18s var(--spring);
}
.hero-vbtn[hidden]{display:none}
.hero-vbtn svg{width:16px;height:16px;flex:none}
.hero-vbtn.dark{background:var(--hero-ink);border-color:var(--hero-ink);color:var(--hero-night)}
.hero-vbtn[data-sound="on"]{background:var(--hero-copper);border-color:var(--hero-copper);color:var(--hero-night)}
.hero-vbtn .snd-mute{display:none}
.hero-vbtn[data-sound="off"] .snd-wave{display:none}
.hero-vbtn[data-sound="off"] .snd-mute{display:inline}
.hero-vbtn:active{transform:scale(.96)}
.hero-vbtn:focus-visible{outline:3px solid var(--hero-copper);outline-offset:3px}
@media (hover:hover){.hero-vbtn:hover{border-color:var(--hero-ink)}}

/* Examples rail: a flat dark band at the foot; side-scrolls on phones, runs off the right edge on desktop.
   It has no visible label (2026-10-03); the nav is named by aria-label="Examples". */
.hero-ticker{position:relative;z-index:1;display:grid;gap:8px;padding:12px 0 calc(12px + env(safe-area-inset-bottom,0px));border-top:1px solid rgb(244 240 232 / .16);background:rgb(18 19 17 / .78)}
.hero-ticker ol{list-style:none;margin:0;padding:0 var(--gutter);display:flex;gap:8px 22px;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scroll-padding-inline:var(--gutter);scrollbar-width:none}
.hero-ticker ol::-webkit-scrollbar{display:none}
.hero-ticker li{flex:none;scroll-snap-align:start}
.hero-ticker a{display:flex;align-items:center;gap:10px;min-height:44px;text-decoration:none;border-radius:6px;color:rgb(244 240 232 / .74)}
.hero-ticker img{width:58px;height:40px;object-fit:cover;border-radius:5px;background:#1A1B19;box-shadow:0 0 0 1px rgb(244 240 232 / .1);transition:transform .32s var(--spring)}
.hero-ticker span{font-size:13px;line-height:1.25;white-space:nowrap}
.hero-ticker b{font-weight:600;color:var(--hero-ink);font-variant-numeric:lining-nums tabular-nums}
@media (hover:hover){.hero-ticker a:hover{color:var(--hero-ink)}.hero-ticker a:hover img{transform:translateY(-2px) scale(1.06)}}
.hero-ticker a:focus-visible{outline:2px solid var(--hero-copper);outline-offset:2px}

@media (min-width:900px){
  .hero{padding-top:calc(var(--bar-h) + 28px)}
  .hero-copy{align-self:center;padding:24px var(--gutter) 40px}
  .hero .hero-eyebrow{margin-bottom:22px}
  .hero .hero-title{font-size:clamp(60px,7.8vw,124px);margin-bottom:30px}
  .hero .hero-title .kt-line:first-child{font-size:.72em;margin-bottom:.1em;white-space:nowrap}
  .hero .hero-lead{font-size:clamp(18px,1.4vw,21px);max-width:31em;margin-bottom:32px}
  .hero .hero-actions{gap:12px}
  .hero-ctl{top:calc(var(--bar-h) + 18px);bottom:auto;justify-content:flex-start}
  .hero-ticker{display:flex;align-items:center;gap:36px;padding:6px 0;min-height:60px}
  .hero-ticker ol{padding-right:0;gap:34px;overflow-x:auto}
  .hero-ticker img{width:52px;height:34px}
}
/* tall screens show the portrait still; keep its calm lower half under the copy */
@media (max-aspect-ratio:4/5){.hero-still{transform-origin:50% 22%}}

/* ---------- arrival: everything moves in from its mark (never a fade alone) ---------- */
/* styles.css still carries the old hero's rise animation on .eyebrow, .lead and .hero-actions: hero.js and the
   transitions below own the arrival now */
html[data-motion="on"] .hero :is(.hero-eyebrow,.hero-lead,.hero-actions){animation:none}
.hero :is(.hero-eyebrow,.hero-title,.hero-lead,.hero-actions,.hero-ticker){
  transition:opacity .55s ease,transform 1.05s var(--hero-ease),translate 1.05s var(--hero-ease)}
.hero .hero-title{transition-delay:.06s}
.hero .hero-lead{transition-delay:.95s}                    /* after the headline has mostly landed: one focal point at a time */
.hero .hero-actions{transition-delay:1.12s;transition-timing-function:ease,var(--spring),var(--spring)}
.hero .hero-ticker{transition-delay:1.28s}
.hero .hero-ticker li{transition:transform .8s var(--spring),opacity .4s ease;transition-delay:calc(1.36s + var(--i) * 40ms)}
.hero:is([data-state="film"],[data-state="handoff"],[data-state="intro"]) :is(.hero-eyebrow,.hero-title,.hero-lead,.hero-actions){
  opacity:0;transform:translate3d(0,40px,0);transition:none}
.hero:is([data-state="film"],[data-state="handoff"],[data-state="intro"]) .hero-eyebrow{transform:translate3d(-48px,0,0)}
.hero:is([data-state="film"],[data-state="handoff"],[data-state="intro"]) .hero-ticker{opacity:0;transform:translate3d(0,100%,0);transition:none}
.hero:is([data-state="film"],[data-state="handoff"],[data-state="intro"]) .hero-ticker li{opacity:0;transform:translate3d(64px,0,0);transition:none}

/* without JavaScript the stack shows as it lands: line one stepped back */
html:not(.js) .hero .hero-title .kt-line:first-child{scale:.72;opacity:.55;transform-origin:0 100%}

/* if hero.js never runs, nothing stays hidden */
@keyframes hero-failsafe{to{opacity:1;transform:none}}
.hero:not([data-ready]):is([data-state="film"],[data-state="intro"]) :is(.hero-eyebrow,.hero-title,.hero-lead,.hero-actions,.hero-ticker,.hero-ticker li){animation:hero-failsafe .01s 3.5s forwards}

/* motion off or reduced: settled, still, no sweep */
html[data-motion="off"] .hero :is(.hero-still,.hero-film,.hero-eyebrow,.hero-title,.hero-lead,.hero-actions,.hero-ticker,.hero-ticker li,.hero-vbtn,.hero-ticker img){animation:none!important;transition:none!important}
html[data-motion="off"] .hero-media::after{transition:none!important}
@media (prefers-reduced-motion:reduce){
  .hero :is(.hero-still,.hero-film,.hero-eyebrow,.hero-title,.hero-lead,.hero-actions,.hero-ticker,.hero-ticker li,.hero-vbtn,.hero-ticker img),.hero-media::after{animation:none!important;transition:none!important}
}

/* Review fix: over the tile wall the receded first line stays readable (the stack default dims to .55). */
.hero .hero-title[data-kt-stack] .kt-line:has(~ .kt-line.kt-landed){opacity:.82}

/* Phone: a more compact copy block so the film's Mainstay M has room between the top bar and the headline. */
@media (max-width:899px){
  .hero .hero-eyebrow{margin-bottom:12px}
  .hero .hero-title.kt{font-size:clamp(38px,11.4vw,52px);margin-bottom:16px}
  .hero .hero-lead{font-size:15px;line-height:1.5;margin-bottom:18px}
  .hero .hero-actions{gap:8px}
  .hero .hero-actions .pill{min-height:44px}
  .hero-copy{padding-bottom:18px}
}

/* ---------- the lit M (hero.py _lit): lives on the still after the hand-off ---------- */
/* It covers the hero exactly like the still and takes the still's push, so it stays on the M in the picture. Hidden
   while the film plays (the film carries its own M); it appears when the page takes over. */
.hero-lit{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;opacity:0;transform-origin:72% 50%;transition:opacity .5s ease}
.hero-lit.tall{display:none}
@media (max-aspect-ratio:4/5){.hero-lit.wide{display:none}.hero-lit.tall{display:block;transform-origin:50% 22%}}
.hero[data-state="page"] .hero-lit{opacity:1}
.hero-lit .lit-beam,.hero-lit .lit-glint{transform:translateX(-400px)}   /* parked outside the M until motion runs */
.hero-lit .lit-edge{stroke-dasharray:1;stroke-dashoffset:0}
@keyframes lit-pass{0%{transform:translateX(-260px)}58%,100%{transform:translateX(560px)}}
@keyframes lit-glint{0%{transform:translateX(-200px)}58%,100%{transform:translateX(260px)}}
@keyframes lit-trace{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
html[data-motion="on"] .hero[data-state="page"] .hero-lit{animation:hero-push 28s cubic-bezier(.35,.45,.55,1) infinite alternate}
html[data-motion="on"] .hero[data-state="page"] .hero-lit .lit-beam{animation:lit-pass 7s cubic-bezier(.45,.05,.25,1) 1.6s infinite both}
html[data-motion="on"] .hero[data-state="page"] .hero-lit .lit-glint{animation:lit-glint 7s cubic-bezier(.45,.05,.25,1) 1.6s infinite both}
html[data-motion="on"] .hero[data-state="page"] .hero-lit .lit-edge{animation:lit-trace 3.2s cubic-bezier(.22,1,.36,1) .3s both}
.hero[data-offscreen] :is(.hero-lit,.hero-lit *){animation-play-state:paused}
html[data-motion="off"] .hero :is(.hero-lit,.hero-lit *){animation:none!important;transition:none!important}
@media (prefers-reduced-motion:reduce){.hero :is(.hero-lit,.hero-lit *){animation:none!important;transition:none!important}}

/* Phone, after the film: Replay the intro becomes a round icon button at the top right, clear of the M. */
@media (max-width:899px){
  .hero:not([data-state="film"]) .hero-ctl{justify-content:flex-end}
  .hero:not([data-state="film"]) .hero-vbtn[data-film="replay"]{width:44px;padding:0;justify-content:center}
  .hero:not([data-state="film"]) .hero-vbtn[data-film="replay"] span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
}
