/* Section experiment (/?hero=gsap, see sections-motion.js). Rules are scoped to
   html.hero-gsap or to elements that only exist once that script runs, so the
   page without the parameter stays as it was. */
html.hero-gsap{--logo-a:#6f5bff;--logo-b:#f03cf2;--pink-shadow:#e56eef}

/* Selected work: the title alone, aligned with the grid, then the projects.
   Each one is cover, category, title and short description, sitting on the
   page background with no frame. They stay static (no hover, no link cursor)
   until they point to real case studies. Global rules: the content is in
   index.html. The filter tabs stay hidden in this version. */
html.hero-gsap .filters{display:none}
.work-section .section-heading{display:block;margin-bottom:36px}
.project-grid{gap:56px 32px}
.project-info{padding:20px 0 0}
/* Mid-page CTA after Testimonials, where trust is highest. A card with two
   corners cut at 45 degrees (the same chamfer as the 9-slice game panel),
   drawn as a 1px lilac-to-fuchsia edge around a dark violet face. Short CTA: "Email me" says exactly what
   happens; Fiverr stays as a quiet alternative. */
/* Same width as the testimonial cards above (the carousel keeps room for its
   arrows on each side, 60px from the column edges). */
.mid-cta{--cut:30px;margin:64px 60px 0;padding:1px;
  background:linear-gradient(120deg,#a378ff73,#c24cf759 55%,#e56eef99);
  clip-path:polygon(0 0,calc(100% - var(--cut)) 0,100% var(--cut),100% 100%,var(--cut) 100%,0 calc(100% - var(--cut)))}
.mid-cta-inner{--split:64%;position:relative;display:flex;align-items:flex-start;justify-content:space-between;gap:24px 56px;padding:44px 64px 44px 56px;
  /* Split fill: a calm dark side for the copy and, past a 45-degree edge (the
     same angle as the cut corners), a violet-to-fuchsia side with a fine 45
     degree hatch where the button sits. Different from the flat testimonial
     cards without adding glow. */
  background:
    linear-gradient(135deg,#170827 0 calc(var(--split) - 1px),#c24cf766 calc(var(--split) - 1px) var(--split),transparent var(--split)),
    repeating-linear-gradient(135deg,#ffffff0d 0 1px,transparent 1px 10px),
    radial-gradient(90% 140% at 100% 0%,#8e2aa8 0%,#4c1470 55%,#2a0b45 100%);
  clip-path:polygon(0 0,calc(100% - var(--cut)) 0,100% var(--cut),100% 100%,var(--cut) 100%,0 calc(100% - var(--cut)))}
.mid-cta-title{color:var(--text);font:400 clamp(30px,3vw,42px)/1.05 var(--display)}
.mid-cta-text{max-width:540px;margin-top:10px;color:var(--muted);font-size:17px;line-height:1.55}
/* The button lines up with the title (centre to centre), not with the copy block. */
.mid-cta-actions{display:flex;flex-direction:column;align-items:center;gap:10px;flex:none;margin-top:calc((clamp(30px,3vw,42px) * 1.05 - 48px) / 2)}
.mid-cta-link{display:inline-flex;align-items:center;justify-content:center;gap:12px;min-width:200px;min-height:48px;padding:12px 30px;border-radius:999px;
  background:#faf7ff;color:var(--bg);font:500 16px/1.25 var(--body);text-decoration:none;transition:background-color .19s ease-out}
.mid-cta-link .icon{width:16px;height:16px}
/* White, like the header "Contact me": it stands out on the vivid side. */
.mid-cta-link:hover{background:#e5d8ff}
.mid-cta-link:active{background:#d6c4fb}
.mid-cta-link:focus-visible,.mid-cta-alt:focus-visible{outline:2px solid #fff;outline-offset:3px}
.mid-cta-alt{display:inline-flex;align-items:center;min-height:32px;color:#f1e7fb;font-size:14px;text-decoration:underline;text-underline-offset:3px;text-decoration-color:#ffffff40}
.mid-cta-alt:hover{color:var(--text);text-decoration-color:currentColor}
@media(max-width:800px){
  .mid-cta{--cut:22px;margin:48px 0 0}
  .mid-cta-inner{--split:62%;flex-direction:column;align-items:flex-start;padding:30px 24px 32px;
    background:
      linear-gradient(165deg,#170827 0 calc(var(--split) - 1px),#c24cf766 calc(var(--split) - 1px) var(--split),transparent var(--split)),
      repeating-linear-gradient(135deg,#ffffff0d 0 1px,transparent 1px 10px),
      radial-gradient(120% 90% at 100% 100%,#8e2aa8 0%,#4c1470 55%,#2a0b45 100%)}
    .mid-cta-actions{align-self:stretch}
  .mid-cta-link{width:100%}
}

/* Per-project link to the real file (Figma, or the audit's Google Sheet):
   a compact outline pill under each description, same family as the
   secondary buttons, so visitors can open the work themselves. */
.project-info .project-link{display:inline-flex;align-items:center;gap:10px;min-height:44px;margin-top:18px;padding:10px 18px;
  border:1px solid #ffffff33;border-radius:999px;color:var(--text);font:500 15px/1.2 var(--body);text-decoration:none;
  transition:background-color .19s ease-out,border-color .19s ease-out}
.project-link .icon{width:18px;height:18px;color:#d68cff;stroke-width:1.7}
.project-link .project-link-arrow{width:14px;height:14px;color:var(--muted)}
.project-link:hover{background:#8a45bb22;border-color:#c9a1e5}
.project-link:focus-visible{outline:2px solid #fff;outline-offset:3px}

/* Closing row of Latest work: separated from the grid by space and a hairline,
   copy on the left, and the site's filled violet button on the right, so it
   reads as the end of the list and not as one more per-project outline link. */
.work-more{display:flex;align-items:center;justify-content:space-between;gap:24px 48px;margin-top:96px;padding-top:40px;border-top:1px solid #ffffff17}
.work-more-title{color:var(--text);font:400 clamp(28px,2.6vw,36px)/1.1 var(--display)}
.work-more-text{max-width:560px;margin-top:8px;color:var(--muted);font-size:16px;line-height:1.6}
.work-more-link{display:inline-flex;align-items:center;justify-content:center;gap:12px;flex:none;min-height:52px;padding:14px 30px;border-radius:999px;
  background:var(--btn-primary-bg,#a02ad0);color:#fff;font:500 16px/1.25 var(--body);text-decoration:none;transition:background-color .19s ease-out}
.work-more-link .icon{width:16px;height:16px}
.work-more-link:hover{background:var(--btn-primary-bg-hover,#9226bf)}
.work-more-link:active{background:var(--btn-primary-bg-press,#8422ad)}
.work-more-link:focus-visible{outline:2px solid #fff;outline-offset:3px}
@media(max-width:800px){.work-more{flex-direction:column;align-items:flex-start;margin-top:64px;padding-top:32px}.work-more-link{width:100%}}/* Real covers: a 16:9 box (the supplied mockups are wide, a fixed height
   cropped their sides) with the original radius and border; object-position
   keeps each one's focus in view. */
.project-art.project-cover{height:auto;aspect-ratio:16/9;background:#1a0c2b}
.project-cover :is(img,video){display:block;width:100%;height:100%;object-fit:cover}
/* Frontierz video: quiet pause/play control in the corner, always reachable
   (touch, keyboard), white focus ring like the rest of the page. */
.cover-video-toggle{position:absolute;right:10px;bottom:10px;z-index:2;display:grid;place-items:center;width:36px;height:36px;
  padding:0;border:1px solid #ffffff2e;border-radius:50%;background:#140824b3;color:#faf7ff;cursor:pointer;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:background-color .19s ease-out,border-color .19s ease-out}
.cover-video-toggle::before{content:"";position:absolute;inset:-4px}
.cover-video-toggle:hover{background:#2a1245d9;border-color:#c9a1e5b3}
.cover-video-toggle:focus-visible{outline:2px solid #fff;outline-offset:2px}
.cover-video-toggle svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.cover-video-toggle .i-play{display:none;fill:currentColor;stroke-width:1.5}
.cover-video-toggle.is-paused .i-pause{display:none}
.cover-video-toggle.is-paused .i-play{display:block}
.cover-web img{object-position:50% 30%}
/* Hover, same language as My approach (mouse only, motion allowed): the cover
   rises 2px, its border turns lilac with a soft close shadow, the image eases
   in 3% and a slow sheen crosses it. The sheen has no transition at rest, so it
   resets instantly instead of sweeping back. Not a link: default cursor. */
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  html.hero-gsap .project-cover{transition:translate .3s ease-out,border-color .3s ease-out,box-shadow .3s ease-out}
  html.hero-gsap .project-cover :is(img,video){transition:scale .7s cubic-bezier(.33,1,.68,1)}
  html.hero-gsap .project-cover::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(110deg,transparent 40%,#ffffff2e 50%,transparent 60%) 130% 0/250% 100% no-repeat}
  html.hero-gsap .project:hover .project-cover{translate:0 -2px;border-color:#c9a1e5b3;box-shadow:0 14px 30px -16px #e56eef59}
  html.hero-gsap .project:hover .project-cover :is(img,video){scale:1.03}
  html.hero-gsap .project:hover .project-cover::after{background-position:-30% 0;transition:background-position 1.4s ease-in-out}
}
.project-type{font-size:13px;letter-spacing:.07em;color:#d07cfa;background:none;-webkit-text-fill-color:currentColor;margin-bottom:8px}
.project-info h3{font-size:30px;line-height:1.1;margin-bottom:10px}
.project-info>p:not(.project-type){font-size:16px;line-height:1.7;max-width:460px}@media(max-width:800px){
  .project-grid{gap:48px 24px}
  .project-info h3{font-size:28px}
}
@media(max-width:520px){
  .work-section .section-heading{margin-bottom:32px}
  .project-grid{gap:48px}
}

/* How I help: two columns, intro (~40%) and services (~60%), both starting at
   the same line; the left one never stretches when a service opens
   (align-items:start), the free space below it is intentional. Global rules,
   because the intro and stats live in index.html. */
@media(min-width:801px){
  .expertise-layout{grid-template-columns:minmax(0,2fr) minmax(0,3fr);gap:clamp(48px,7vw,104px);align-items:start}
}
.expertise-intro>p:not(.eyebrow){max-width:430px;margin-top:24px}
/* Three figures, same type treatment, labels below at 8px; no separators. */
.help-stats{list-style:none;margin:40px 0 0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));column-gap:28px}
.help-stat{display:flex;flex-direction:column;align-items:flex-start;gap:8px;min-width:0}
.help-figure{font-family:var(--display);font-size:44px;line-height:1;color:#fff}
.help-label{font-size:14px;font-weight:400;line-height:1.4;color:var(--muted)}
/* The reviews label is the link to the real profile: discreet underline, a
   comfortable hit area that doesn't shift the layout, visible focus. */
.help-link{display:inline-block;padding-block:8px;margin-block:-8px;text-decoration:underline;text-decoration-color:#a678ee80;
  text-underline-offset:4px;transition:color .2s,text-decoration-color .2s}
.help-link:hover{color:#fff;text-decoration-color:var(--pink)}
.help-link:focus-visible{outline:2px solid var(--cyan);outline-offset:2px;border-radius:4px}
@media(min-width:801px) and (max-width:1150px){
  .help-stats{column-gap:20px}
}

/* Services keep their boxed rows, but closed ones are quieter: a background
   closer to the section and a fainter border (still visible). The open one
   keeps the original surface and the stronger lilac border; while it closes
   (data-expanded=false) it already takes the quiet look. Hover lifts the
   border, focus gets a clear outline; text and icons keep full contrast. */
.expertise-list details{background:#170826;border-color:#7f629138;transition:background-color .2s,border-color .2s}
.expertise-list details[open]:not([data-expanded=false]){background:#1b0a2e;border-color:#ab78d780}
.expertise-list details[data-expanded=false]{background:#170826;border-color:#7f629138}
.expertise-list details:not([open]):hover,
.expertise-list details[data-expanded=false]:hover{border-color:#9b7cc070}
.expertise-list summary:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
/* Without the tags, the paragraph is the last thing in each body; the
   bottom padding keeps the original breathing room. */
.expertise-list .details-body{padding-bottom:26px}
/* Softer open/close: duration and easing read by script.js, with a matching
   chevron. */
.expertise-list details{--details-duration:560;--details-easing:cubic-bezier(.33,1,.68,1)}
.expertise-list .chevron{transition:transform .5s cubic-bezier(.33,1,.68,1)}
@media(prefers-reduced-motion:reduce){.expertise-list .chevron{transition:none}}
/* Icons share one gradient stroke in the logo's colors (defined by
   sections-motion.js), heavier to sit closer to the weight of Francois One. */
html.hero-gsap .expertise-list .expertise-icon{stroke:url(#icon-logo);stroke-width:2.4}

/* Wide, diffuse lilac and violet glows at the sides, keeping the reading
   centre dark; a faint fuchsia one lower down, kept well inside the section
   so it never reads as a band. */
html:not(.hero-gsap) .expertise-section{background:
  radial-gradient(ellipse 760px 300px at 6% 46%,#6527a638,transparent 70%),
  radial-gradient(ellipse 660px 280px at 96% 56%,#8a3fd02b,transparent 70%),
  radial-gradient(ellipse 420px 160px at 64% 76%,#e56eef0a,transparent 70%),var(--bg-deep)}

@media(max-width:800px){
  .expertise-intro>p:not(.eyebrow){max-width:none;font-size:16px}
  .help-stats{column-gap:16px}
  .help-figure{font-size:40px}
  .expertise-list .details-body,
  .expertise-list .details-body p{font-size:16px;line-height:1.75}
  html.hero-gsap .expertise-list .tags li{font-size:13px}
}

/* My approach: informative cards (no link cursor). On hover they rise 2px,
   tilt slightly toward the pointer and get a faint, close lilac shadow, about
   60% softer than before; a sheen masked to the drawing's own shape crosses
   the illustration. */
html.hero-gsap .approach-grid article{transition:box-shadow .3s ease-out,border-color .3s ease-out;
  background:linear-gradient(160deg,#26103f,#1b092f 60%);border-color:#87669866;
  box-shadow:inset 0 0 0 999px #c9a1e500,0 14px 30px -16px #e56eef00}
/* Hover: the lilac border and a faint lilac wash inside are what read; the
   outer shadow stays soft and close. */
html.hero-gsap .approach-grid article.is-lit{border-color:#c9a1e5b3;
  box-shadow:inset 0 0 0 999px #c9a1e50d,0 14px 30px -16px #e56eef59}
.art-stage{position:relative;display:block;width:fit-content;margin:0 auto 24px}
.art-stage .approach-art{margin:0}
.art-shine{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(110deg,transparent 38%,#ffffff8c 50%,transparent 62%) 130% 0/250% 100% no-repeat;
  -webkit-mask:var(--art) center/contain no-repeat;mask:var(--art) center/contain no-repeat}
@media(max-width:800px){.art-stage{margin-bottom:20px}}

/* Testimonials: drawn chevrons, optically centred in the round buttons. */
.review-arrow .arrow-icon{width:22px;height:22px;stroke-width:2.2}
.review-prev .arrow-icon{rotate:90deg}
.review-next .arrow-icon{rotate:-90deg}

/* Bar under the hero: three static phrases in the site's secondary lavender,
   separated by small outlined shapes (a ring and a diamond of similar optical
   weight) that are decorative and hidden from screen readers. No band
   background, borders or grid; it reads as a quiet transition to the work.
   Each separator travels with the phrase after it, so on narrow screens a
   wrapped line starts with its symbol and no phrase is ever split. */
.specialties{background:none;border:0}
.specialties>.wrap{min-height:72px;padding-block:20px;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:12px 24px;
  font-size:15px;font-weight:400;letter-spacing:.01em;color:var(--muted)}
.specialties .bar-item{display:inline-flex;align-items:center;gap:24px;flex-basis:auto;white-space:nowrap;text-align:left}
.specialties .bar-sep{display:block;flex:none;opacity:1;background:none;border:1.5px solid #a378ffa6}
.specialties .bar-sep--ring{width:8px;height:8px;border-radius:50%}
.specialties .bar-sep--diamond{width:7px;height:7px;border-radius:1px;rotate:45deg}
/* The desktop hero horizon keeps its haze and line at the photo's base, but
   its perspective grid no longer shows through the bar. */
.neon-horizon--hero .hz-floor{display:none}
@media(max-width:800px){
  .specialties>.wrap{font-size:14px;gap:10px 18px;padding-block:18px}
  .specialties .bar-item{gap:18px}
}

/* Industries version of the bar, all on one line: "100+ projects across",
   then the sectors Cami has designed for (from her real projects) moving
   slowly to the left, ending in "and more". The list is drawn twice for a
   seamless loop (the copy is hidden from screen readers), edges fade out,
   and it pauses with the hero's pause button, on hover, and with reduced
   motion (then it simply sits still, clipped by the fade). */
.specialties--industries>.wrap{flex-wrap:nowrap;justify-content:flex-start;gap:28px}
.bar-label{display:inline-flex;align-items:center;gap:8px;flex:none;margin:0;color:var(--subtle);font-size:13px;line-height:1;letter-spacing:.11em;text-transform:uppercase;white-space:nowrap}
.bar-label b{display:inline-flex;align-items:center;color:var(--text);font:400 22px/1 var(--display);letter-spacing:0}
/* The "+" sits low in Francois One; lift it to the middle of the digits. */
.bar-plus{display:inline-block;margin-left:1px;translate:0 -.16em}
.bar-marquee{display:flex;flex:1;min-width:0;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 92%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 92%,transparent)}
.bar-list{display:flex;flex:none;align-items:center;margin:0;padding:0;list-style:none;animation:bar-scroll 42s linear infinite}
.bar-list li{display:inline-flex;align-items:center;color:#e6dcf2;white-space:nowrap}
.bar-list li::before{content:"";width:6px;height:6px;margin-inline:18px;border:1.5px solid #a378ffa6;border-radius:1px;rotate:45deg;flex:none}
.bar-list .bar-more{color:#d68cff}
.bar-marquee:hover .bar-list,.motion-paused .bar-list{animation-play-state:paused}
@keyframes bar-scroll{to{translate:-100% 0}}
@media(prefers-reduced-motion:reduce){.bar-list{animation:none}}
@media(max-width:800px){
  /* Label on top, the moving list gets the full width underneath so the industries can be read. */
  .specialties--industries>.wrap{flex-direction:column;align-items:center;gap:14px;padding-inline:0}
  .specialties--industries .bar-marquee{flex:none;width:100%}
  .bar-label{font-size:12px;letter-spacing:.08em}
  .bar-label b{font-size:20px}
  .bar-list li::before{margin-inline:14px}
  .bar-list{animation-duration:34s}
}

/* Solid accent #C24CF7 (taken from the middle of the logo) stays for
   highlighted text and current-section indicators. */
:root{--accent-solid:#c24cf7}

/* Primary button variant, violet fill with a white label: "Explore my work",
   "Send me an email", and the mobile menu's round button and "Contact me".
   White on #A02AD0 is 5.6:1, on hover #9226BF 6.5:1, pressed #8422AD 7.5:1.
   No gradients, glow or scaling; ~190ms colour transitions; keyboard focus is
   a white outline set off from the button. */
:root{--btn-primary-bg:#a02ad0;--btn-primary-bg-hover:#9226bf;--btn-primary-bg-press:#8422ad;--btn-primary-text:#fff}
/* Contact copy: the longer button labels stay on one line; the column grows to
   the widest one (both buttons share that width). */
.contact-actions{flex:0 0 auto;min-width:240px}
.contact-actions .button{width:100%;white-space:nowrap}
.contact-panel .contact-note{margin-top:12px}
@media(max-width:800px){.contact-actions{min-width:0}}
@media(max-width:380px){.contact-actions .button{white-space:normal}}
html.hero-gsap .hero-actions .button.primary,
html.hero-gsap .contact-panel .button.primary{min-height:48px;padding:12px 26px;gap:12px;align-items:center;justify-content:center;
  border-color:transparent;background:var(--btn-primary-bg);color:var(--btn-primary-text);font:500 16px/1.25 var(--body);
  transition:background-color .19s ease-out}
html.hero-gsap .hero-actions .button.primary:hover,
html.hero-gsap .contact-panel .button.primary:hover{background:var(--btn-primary-bg-hover);color:var(--btn-primary-text)}
html.hero-gsap .hero-actions .button.primary:active,
html.hero-gsap .contact-panel .button.primary:active{background:var(--btn-primary-bg-press)}
html.hero-gsap .hero-actions .button.primary:focus-visible,
html.hero-gsap .contact-panel .button.primary:focus-visible{outline:2px solid #fff;outline-offset:3px}
/* "Email me" keeps the logo gradient. On hover the gradient reverses direction by sliding a
   mirrored, 3x-wide gradient (a > mid > b > mid > a) from its left third to its right third.
   No filter or transform, so the label never re-rasterizes or shifts. */
html.hero-gsap .contact-panel .button.primary,
html.hero-gsap .contact-panel .button.primary:hover,
html.hero-gsap .contact-panel .button.primary:active{color:#fff;
  background:linear-gradient(110deg,var(--logo-a),#a046ee 16.67%,var(--logo-b) 33.33%,#a046ee 50%,var(--logo-a) 66.67%,#a046ee 83.33%,var(--logo-b)) 0% 0/300% 100% border-box no-repeat}
html.hero-gsap .contact-panel .button.primary{transition:background-position .6s cubic-bezier(.4,0,.2,1)}
html.hero-gsap .contact-panel .button.primary:hover,
html.hero-gsap .contact-panel .button.primary:focus-visible{background-position:50% 0;transform:none}
html.hero-gsap .contact-panel .button.primary:active{background-position:50% 0;box-shadow:inset 0 0 0 999px #00000024}
@media (prefers-reduced-motion:reduce){html.hero-gsap .contact-panel .button.primary{transition:none}}

/* Header "Contact me" (desktop): stays white; the label turns violet and the arrow leaves
   up-right and comes back in from the bottom-left. Replaces the flat white > grey-lilac swap. */
@media (min-width:981px){
  .nav-contact,.nav-contact:hover{background:#faf7ff}
  .nav-contact{transition:color .25s ease-out,box-shadow .25s ease-out}
  .nav-contact:hover,.nav-contact:focus-visible{color:#7a1fc0!important;box-shadow:0 0 22px #c24cf74d}
  .nav-contact .icon{overflow:visible}
  .nav-contact:hover .icon,.nav-contact:focus-visible .icon{animation:nav-arrow-loop .5s cubic-bezier(.4,0,.2,1)}
}
@keyframes nav-arrow-loop{
  0%{translate:0 0;opacity:1}
  45%{translate:7px -7px;opacity:0}
  46%{translate:-7px 7px;opacity:0}
  100%{translate:0 0;opacity:1}
}
@media (prefers-reduced-motion:reduce){.nav-contact .icon{animation:none!important}}

/* Section backgrounds, editorial rhythm: sections alternate between the base
   violet and a deeper tone, each deep band framed by hairlines (as How I help
   originally did). Glows only in the hero (its own) and behind the Contact
   card. Each band is a full-width layer behind the section; main clips the
   sideways overflow. */
html.hero-gsap main{overflow-x:clip}
html.hero-gsap main>.section{position:relative;isolation:isolate}
html.hero-gsap main>.section::before{content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;translate:-50% 0;z-index:-1;pointer-events:none}
html.hero-gsap .expertise-section,
html.hero-gsap .about-section{background:none;border-color:transparent}
/* Conversion order (How I help, Work, Testimonials, My approach, About,
   Contact): the bands follow position, not section, so the rhythm stays
   base / deep / base / deep / base / deep as before. The deep band with the
   side glows moves to position 2 (Work), the plain deep band to position 4
   (My approach). */
html.hero-gsap .approach-section::before{background:var(--bg-deep);border-block:1px solid #ffffff0a}
html.hero-gsap .work-section::before{border-block:1px solid #ffffff0a;background:
  radial-gradient(ellipse 760px 300px at 6% 46%,#6527a638,transparent 70%),
  radial-gradient(ellipse 660px 280px at 96% 56%,#8a3fd02b,transparent 70%),
  radial-gradient(ellipse 420px 160px at 64% 76%,#e56eef0a,transparent 70%),var(--bg-deep)}
html.hero-gsap .contact-section::before{border-top:1px solid #ffffff0a;
  background:radial-gradient(ellipse 760px 220px at 50% 50%,#7a2fa540,transparent 70%),radial-gradient(ellipse 420px 180px at 72% 55%,#e56eef17,transparent 70%),
  linear-gradient(var(--bg-deep) calc(100% - 140px),var(--bg))}
/* The horizon starts just below the Contact card: the section gets enough
   bottom room for the whole floor (170px) plus 40px of air above the line. */
html.hero-gsap .contact-section{padding-top:120px;padding-bottom:210px}
@media(max-width:800px){html.hero-gsap .contact-section{padding-top:80px;padding-bottom:160px}}

/* Footer, professional profiles: icon + name, quiet secondary lavender, accent
   on hover. Each link keeps a 44px tall touch area and the row wraps on phones.
   Global rules: the links are in index.html. */
.footer-profiles{list-style:none;display:flex;flex-wrap:wrap;gap:0 24px;margin:12px 0 0;padding:0}
.footer-profiles a{display:inline-flex;align-items:center;gap:8px;min-height:44px;color:#c3b8d1;
  font:400 15px/1.3 var(--body);text-decoration:none;transition:color .19s ease-out}
.footer-profiles a:hover{color:#c24cf7}
.footer-profiles a:focus-visible{color:#c24cf7;outline:2px solid #fff;outline-offset:3px;border-radius:4px}
.footer-profiles .icon{width:18px;height:18px;flex:none}

/* Legibility: no text below 12px. The original stylesheets raise these sizes
   only above 800px; on phones they dropped to 9-11px. Short helper lines go
   to 13px. The audit mockup's "01/02" numbers were 10px at every width. */
html.hero-gsap .annotation span{font-size:12px}
@media(max-width:800px){
  html.hero-gsap :is(.eyebrow,.section-heading .eyebrow,.project-type,.tags li,.placeholder-tag,.footer-bottom,.brand-role){font-size:12px}
  html.hero-gsap :is(.coming-soon,.small-note,.work-note,.photo-caption,.interests li,.footer-role,.site-footer>div>p,.footer-links){font-size:13px}
}

/* Navigation, desktop and tablet (≥801px): smart header. Fixed at the top,
   it slides away while scrolling down and returns on scroll up, frosted once
   it floats over content. The current section gets a logo-gradient underline. */
@media(min-width:801px){
  html.hero-gsap body{padding-top:var(--header-h,96px)}
  html.hero-gsap .site-header{position:fixed;top:0;left:0;right:0;z-index:50;border-bottom:1px solid transparent;
    transition:transform .45s cubic-bezier(.22,1,.36,1),background-color .3s,border-color .3s,box-shadow .3s}
  html.hero-gsap .site-header.is-floating{background:#10051ed9;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-bottom-color:#ffffff12;box-shadow:0 10px 30px #00000040}
  html.hero-gsap .site-header.is-hidden{transform:translateY(-101%)}
  html.hero-gsap #main-nav>a:not(.button){position:relative}
  html.hero-gsap #main-nav>a:not(.button)::after{content:"";position:absolute;left:0;right:0;bottom:6px;height:2px;border-radius:2px;
    background:var(--accent-solid);scale:0 1;transition:scale .35s cubic-bezier(.22,1,.36,1)}
  html.hero-gsap #main-nav>a[aria-current=true]{color:#fff}
  html.hero-gsap #main-nav>a[aria-current=true]::after{scale:1 1}
}

/* Navigation, mobile: a floating pill at the bottom (logo, current section,
   menu) that opens a panel with every section. Hidden while on the hero. */
.nav-pill-wrap{display:none}
@media(max-width:800px){
  .nav-pill-wrap{display:block;position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom,0px));z-index:60;translate:-50% 0;
    transition:transform .45s cubic-bezier(.22,1,.36,1),opacity .3s}
  .nav-pill-wrap.is-away{transform:translateY(calc(100% + 30px));opacity:0;pointer-events:none}
  .nav-pill{display:flex;align-items:center;gap:10px;height:54px;padding:6px 6px 6px 9px;border-radius:999px;border:1px solid #a678ee59;
    background:#1c0b32e6;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);color:#fff;font:600 14px/1 var(--body);
    box-shadow:0 14px 34px #0000008c;cursor:pointer}
  .nav-pill img{width:32px;height:32px;object-fit:contain}
  .nav-pill-label{min-width:96px;text-align:left;white-space:nowrap}
  .nav-pill-icon{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;width:40px;height:40px;border-radius:50%;
    background:var(--btn-primary-bg);transition:background-color .19s ease-out}
  .nav-pill:hover .nav-pill-icon{background:var(--btn-primary-bg-hover)}
  .nav-pill:active .nav-pill-icon{background:var(--btn-primary-bg-press)}
  .nav-pill:focus-visible{outline:2px solid #fff;outline-offset:3px}
  .nav-pill-icon i{display:block;width:16px;height:1.5px;border-radius:2px;background:var(--btn-primary-text);transition:transform .25s}
  .nav-pill[aria-expanded=true] .nav-pill-icon i:first-child{transform:translateY(3.25px) rotate(45deg)}
  .nav-pill[aria-expanded=true] .nav-pill-icon i:last-child{transform:translateY(-3.25px) rotate(-45deg)}
  /* Centred with a negative margin rather than translate: GSAP animates this
     panel's transform and would otherwise drop the -50% after closing. */
  .nav-pill-panel{position:absolute;left:50%;bottom:calc(100% + 10px);width:min(300px,calc(100vw - 32px));margin-left:calc(min(300px,calc(100vw - 32px)) / -2);padding:8px;
    display:flex;flex-direction:column;gap:2px;border-radius:22px;border:1px solid #a678ee40;background:#1c0b32f5;
    -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);box-shadow:0 20px 50px #000000a6;transform-origin:50% 100%}
  .nav-pill-panel[hidden]{display:none}
  .nav-pill-panel a{display:flex;align-items:center;justify-content:space-between;min-height:48px;padding:0 16px;border-radius:14px;
    color:var(--muted);font:500 15px/1 var(--body);text-decoration:none}
  .nav-pill-panel a[aria-current=true]{color:#fff;background:#7b46c633}
  .nav-pill-panel a[aria-current=true]::after{content:"";width:7px;height:7px;border-radius:50%;background:var(--accent-solid)}
  .nav-pill-panel .nav-pill-contact{margin-top:6px;justify-content:center;gap:10px;color:var(--bg);font:500 16px/1.25 var(--body);
    background:#faf7ff;transition:background-color .19s ease-out}
  .nav-pill-panel .nav-pill-contact:hover{background:#e5d8ff;color:var(--bg)}
  .nav-pill-panel .nav-pill-contact:active{background:#d6c4fb;color:var(--bg)}
  .nav-pill-panel a:focus-visible{outline:2px solid #fff;outline-offset:-2px}
  .nav-pill-panel .nav-pill-contact:focus-visible{outline-offset:2px}
  .nav-pill-contact .icon{width:16px;height:16px}
  /* The test badge moves to the top so it never covers the pill or its panel. */
  .hero-switch-badge{top:12px;bottom:auto;left:50%;translate:-50% 0;white-space:nowrap}
}

/* Hero, mobile: the right-hand text gets the opposite skew of the title above
   (-5° against +5°) and left alignment, echoing the desktop composition. The
   block stays centred as a whole, so the buttons below still line up. */
@media(max-width:800px){
  html.hero-gsap .hero-right{width:auto;transform:skewY(-5deg);transform-origin:left top;text-align:left;margin-top:40px}
  html.hero-gsap .hero-convert-line{justify-content:flex-start}
  html.hero-gsap .hero-description{margin:16px 0 0 34px;max-width:280px}
}

/* Hero, mobile: a lit floor the portrait stands on, like the band under it on
   desktop. Its top follows the portrait's bottom edge (set by the script). */
.hero-floor{display:none}
@media(max-width:800px){
  .hero-floor{display:block;position:absolute;left:0;right:0;top:var(--floor-top,60%);bottom:0;pointer-events:none;
    background:radial-gradient(ellipse 60% 70px at 50% 0%,#e56eef2e,transparent 75%),linear-gradient(180deg,#1d0b35,#12061f 70%)}
  .hero-floor::before{content:"";position:absolute;left:0;right:0;top:0;height:1.5px;
    background:linear-gradient(90deg,transparent,var(--logo-a) 22%,var(--logo-b) 78%,transparent);box-shadow:0 0 14px #e56eef8c}
  .hero-floor .hz-floor{top:0;bottom:auto;height:150px}
}

/* Neon horizon (sections-motion.js): haze above, a glowing line in the logo
   gradient, and a faint perspective grid receding below it. Every part fades
   out toward the sides and the bottom, so nothing ends in a hard edge. */
.neon-horizon{--hz-line:170px;position:absolute;left:50%;bottom:0;width:100vw;height:260px;translate:-50% 0;z-index:-1;pointer-events:none}
.hz-haze{position:absolute;left:0;right:0;top:0;height:var(--hz-line);
  background:radial-gradient(ellipse 34% 100% at 50% 100%,#c44edf33,transparent 72%),radial-gradient(ellipse 26% 80% at 34% 100%,#6f5bff2e,transparent 72%),radial-gradient(ellipse 22% 70% at 68% 100%,#f03cf224,transparent 72%)}
.hz-line{position:absolute;left:0;right:0;top:var(--hz-line);height:1.5px;opacity:.75;
  background:linear-gradient(90deg,transparent 4%,var(--logo-a) 26%,var(--logo-b) 50%,var(--logo-a) 74%,transparent 96%);box-shadow:0 0 12px #e56eef80,0 0 34px #a378ff47}
.hz-floor{position:absolute;left:0;right:0;top:var(--hz-line,0);bottom:0;overflow:hidden;perspective:240px;perspective-origin:50% 0;
  -webkit-mask:linear-gradient(#000,transparent),linear-gradient(90deg,transparent,#000 22%,#000 78%,transparent);-webkit-mask-composite:source-in;
  mask:linear-gradient(#000,transparent) intersect,linear-gradient(90deg,transparent,#000 22%,#000 78%,transparent)}
.hz-plane{position:absolute;left:-60%;right:-60%;top:0;height:600px;transform-origin:50% 0;transform:rotateX(68deg)}
/* The grid stays still: thin lines drifting under perspective cross half
   pixels and shimmer. */
.hz-tiles{position:absolute;left:0;right:0;top:0;bottom:0;
  background:linear-gradient(#c77dff38 1.5px,transparent 1.5px) 0 0/44px 44px,linear-gradient(90deg,#c77dff38 1.5px,transparent 1.5px) 0 0/44px 44px}
.hero>.neon-horizon--hero{--hz-line:160px;top:calc(var(--floor-top,70%) - 160px);bottom:0;height:auto;left:0;width:auto;right:0;translate:none;z-index:0}
.contact-section>.neon-horizon{--hz-line:150px;height:320px}
/* The horizon already fades into the footer; its top border sat right on the
   grid's lower edge and read as a stray line. */
html.hero-gsap .site-footer{border-top:0}
@media(max-width:800px){
  .hero>.neon-horizon--hero{display:none}
  .neon-horizon{--hz-line:120px;height:200px}
  .contact-section>.neon-horizon{--hz-line:100px;height:230px}
  .hz-plane{left:-120%;right:-120%}
}

/* A barely-there grain over the whole page takes the flat digital edge off
   the dark surfaces and smooths the gradients. */
html.hero-gsap body::after{content:"";position:fixed;inset:0;z-index:40;pointer-events:none;opacity:.05;mix-blend-mode:soft-light;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0/180px 180px}

/* My approach, perspective treatment (from version-perspectiva): the title
   leans back like text lying on the horizon floor, step numbers are larger
   and the cards rise from the floor as they scroll in. Uses `rotate` / `scale`
   so it never fights GSAP (which animates `transform`); without scroll-driven
   animation support, or with reduced motion, everything sits at rest. */
.approach-section .section-heading{perspective:900px}
.approach-section .section-heading h2{width:fit-content;margin-inline:auto;font-size:clamp(56px,8.4vw,128px);line-height:.95;
  transform-origin:50% 100%;rotate:1 0 0 22deg}
.approach-grid{perspective:1400px}
.approach-grid .step-number{font-size:1.6em;line-height:.8}
.approach-grid article{transform-origin:50% 100%}
@keyframes p-floor-title{from{rotate:1 0 0 62deg;opacity:.5}}
@keyframes p-rise{from{rotate:1 0 0 58deg;scale:.94}to{rotate:1 0 0 0deg;scale:1}}
@supports (animation-timeline:view()){
  @media(prefers-reduced-motion:no-preference){
    .approach-section .section-heading h2{animation:p-floor-title linear both;animation-timeline:view();animation-range:entry 0% cover 32%}
    .approach-grid article{animation:p-rise linear both;animation-timeline:view();animation-range:entry 0% cover 40%}
    .approach-grid article:nth-child(even){animation-range:entry 12% cover 48%}
  }
}
@media(max-width:800px){
  .approach-section .section-heading{perspective:700px}
  .approach-grid{perspective:900px}
  .approach-section .section-heading h2{font-size:clamp(48px,14vw,72px);rotate:1 0 0 16deg}
}

/* Collapsible header menu (up to 980px): instead of snapping open, the panel
   unrolls from the header (clip + 10px drop + fade, ~0.4s) and the links
   follow one after another; closing reverses it quickly. While closed it is
   visibility:hidden, so nothing inside can be focused. Text at 16px. */
@media (max-width:980px){
  #main-nav{display:flex;font-size:16px;opacity:0;visibility:hidden;translate:0 -10px;clip-path:inset(0 0 100% 0);pointer-events:none;
    transition:opacity .22s ease-out,translate .28s ease-out,clip-path .3s ease-out,visibility 0s linear .3s}
  #main-nav.is-open{opacity:1;visibility:visible;translate:0 0;clip-path:inset(0 -40px -60px -40px);pointer-events:auto;
    transition:opacity .28s ease-out,translate .4s cubic-bezier(.22,1,.36,1),clip-path .45s cubic-bezier(.22,1,.36,1),visibility 0s}
  #main-nav>a{font-size:16px;opacity:0;translate:0 -6px;transition:opacity .2s ease-out,translate .25s ease-out}
  #main-nav.is-open>a{opacity:1;translate:0 0;transition:opacity .3s ease-out,translate .35s cubic-bezier(.22,1,.36,1)}
  #main-nav.is-open>a:nth-child(1){transition-delay:.06s}
  #main-nav.is-open>a:nth-child(2){transition-delay:.1s}
  #main-nav.is-open>a:nth-child(3){transition-delay:.14s}
  #main-nav.is-open>a:nth-child(4){transition-delay:.18s}
  #main-nav.is-open>a:nth-child(5){transition-delay:.22s}
  #main-nav.is-open>a:nth-child(6){transition-delay:.26s}
  #main-nav .nav-contact,#main-nav .nav-contact .button-label{font-size:16px}
}
@media (max-width:980px) and (prefers-reduced-motion:reduce){
  #main-nav,#main-nav.is-open,#main-nav>a,#main-nav.is-open>a{transition:none;translate:none}
}

/* Contact card copy on phones: never below 16px (it dropped to 12px). */
@media (max-width:800px){
  .contact-panel .contact-copy p{font-size:16px;line-height:1.6}
  .contact-panel .contact-email{font-size:15px}
}

/* Phones: the hero keeps a single button ("Explore my work"); the secondary link is removed. */
@media (max-width:800px){.hero-actions .text-link{display:none}}

