/* KeyGen Consulting. Tokens and decisions come from design/DESIGN-PACKAGE.md. */

@font-face{font-family:"Plex Sans";src:url(../fonts/ibm-plex-sans-latin-300-normal.woff2) format("woff2");font-weight:300;font-display:swap}
@font-face{font-family:"Plex Sans";src:url(../fonts/ibm-plex-sans-latin-400-normal.woff2) format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Plex Sans";src:url(../fonts/ibm-plex-sans-latin-500-normal.woff2) format("woff2");font-weight:500;font-display:swap}
@font-face{font-family:"Plex Mono";src:url(../fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2");font-weight:400;font-display:swap}

:root{
  --canvas:#FBF7EF;
  --canvas-deep:#0D2136;   /* sampled from the film's open water */
  --canvas-abyss:#08101B;  /* sampled from the bottom of the film's final frame */
  --panel:#F3EDE1;
  --accent:#1D5C4B;
  --accent-hover:#174A3C;
  --accent-line:#2E8B6E;
  --accent-muted:#7CC4A0;
  --text-primary:#1F2D3D;
  --text-secondary:#4A5867;
  --text-on-deep:#FBF7EF;
  --text-on-deep-2:#B9C3CC;
  --placeholder:#66717E;    /* 4.65:1 on the canvas */
  --error:#9A2F24;          /* 6.4:1 on the form panel */
  --hairline:rgba(31,45,61,.14);
  --hairline-strong:rgba(31,45,61,.42);

  --sans:"Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"Plex Mono",ui-monospace,"Cascadia Mono",Consolas,monospace;

  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-io:cubic-bezier(.65,0,.35,1);

  --gutter:clamp(20px,5vw,64px);
  --section-gap:clamp(96px,12vw,136px);
  --max:1200px;
  --nav-h:72px;

  --tshadow:0 1px 2px rgba(5,10,18,.95),0 3px 12px rgba(5,10,18,.78),0 10px 44px rgba(5,10,18,.8);
}

*,*::before,*::after{box-sizing:border-box}
html{overflow-x:hidden;overflow-x:clip;scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{margin:0;overflow-x:hidden;overflow-x:clip;background:var(--canvas);color:var(--text-primary);font:400 18px/1.5 var(--sans);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;animation:page-in .3s var(--ease-out) both}
@keyframes page-in{from{opacity:0}to{opacity:1}}
img,svg,video{display:block;max-width:100%}
a{color:inherit}
h1,h2,h3,p,ul,ol{margin:0}
ul,ol{padding:0;list-style:none}
button,input,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--accent-line);outline-offset:3px;border-radius:2px}
::selection{background:rgba(124,196,160,.45);color:var(--text-primary)}

.skip{position:fixed;left:16px;top:16px;z-index:100;padding:10px 16px;background:var(--text-primary);color:var(--canvas);border-radius:999px;text-decoration:none;transform:translateY(-80px);transition:transform .2s var(--ease-out)}
.skip:focus{transform:none}
main:focus{outline:none}

.wrap{width:min(100% - 2*var(--gutter),var(--max));margin-inline:auto}

/* Type */
.display{font-weight:300;font-size:clamp(44px,6.4vw,84px);line-height:1;letter-spacing:-.04em}
.statement{font-weight:300;font-size:clamp(36px,4.6vw,60px);line-height:1.05;letter-spacing:-.03em;max-width:18ch}
.lede{font-size:clamp(18px,1.6vw,21px);line-height:1.55;color:var(--text-secondary);max-width:60ch}
.label{display:inline-flex;align-items:center;gap:10px;font:400 12px/1.2 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:28px}
.label::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent-line)}
.nw{white-space:nowrap} /* keeps compound words like "20-minute" from breaking at the hyphen */
.ul{background:linear-gradient(var(--accent-muted),var(--accent-muted)) left 100%/100% 2px no-repeat;padding-bottom:.04em}

/* Buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;white-space:nowrap;padding:14px 26px;border-radius:999px;font-weight:500;font-size:16px;line-height:1;text-decoration:none;border:1px solid transparent;cursor:pointer;transition:background-color .2s ease,color .2s ease,border-color .2s ease,transform .16s var(--ease-out)}
.btn-primary{background:var(--accent);color:var(--canvas)}
.btn-ghost{border-color:currentColor;padding:11px 20px;font-size:15px}
/* Hover changes only for a real mouse; touch screens fire sticky hovers on tap */
@media (hover:hover) and (pointer:fine){
  .text-link:hover{text-decoration-thickness:2px}
  .btn-primary:hover{background:var(--accent-hover);transform:translateY(-1px)}
  .btn-ghost:hover{background:var(--text-on-deep);color:var(--canvas-deep);border-color:var(--text-on-deep)}
}
.btn:active{transform:scale(.97)} /* press feedback; after the hover rules so a pressed (and hovered) button still presses */
.text-link{font-size:16px;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px}
@media (pointer:coarse){.btn,.text-link,.nav-links a,.footer-links a{min-height:44px;display:inline-flex;align-items:center;justify-content:center}}

/* Navigation: navy text throughout. Over the hero it sits on the film's silver surface band
   (navy measures 5.6:1 or better there; cream would be under 2.4:1). Over the page it gets a cream bar. */
.nav{position:fixed;inset:0 0 auto;z-index:50;height:var(--nav-h);display:flex;align-items:center;gap:32px;padding-inline:var(--gutter);color:var(--text-primary);background:rgba(251,247,239,.5);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);box-shadow:0 1px 0 rgba(31,45,61,.08);transition:background-color .25s ease,box-shadow .25s ease} /* frosted over the film: blurs the surface ripples so navy text stays readable */
.nav-brand{flex:none;width:150px}
.nav-brand img{width:150px;height:auto}
.nav nav{margin-left:auto}
.nav-links{display:flex;gap:28px}
.nav-links a{text-decoration:none;font-size:15px;font-weight:500;opacity:.88;transition:opacity .15s ease}
.nav-links a:hover{opacity:1}
@media (hover:hover) and (pointer:fine){.nav .btn-ghost:hover{background:var(--text-primary);color:var(--canvas);border-color:var(--text-primary)}}
.nav.on-page{background:rgba(251,247,239,.92);box-shadow:0 1px 0 var(--hairline);backdrop-filter:blur(10px)}
@media (max-width:900px){.nav nav{display:none}.nav-cta{margin-left:auto}}
@media (max-width:380px){.nav{gap:12px}.nav-brand,.nav-brand img{width:124px}} /* logo and Book a call both fit on the smallest phones */

/* Hero: a tall pinned region with a sticky full-viewport stage */
.hero{position:relative;height:600vh;background:var(--canvas-deep);color:var(--text-on-deep)}
.stage{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden}
.poster,.hero-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;background:center/cover no-repeat var(--canvas-deep)}
.hero-video{opacity:0;transform:translateZ(0);will-change:transform;transition:opacity .8s var(--ease-out)}
.stage.video-ready .hero-video{opacity:1}
.scrim{position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse 120% 90% at 50% 45%,rgba(8,14,22,0) 35%,rgba(8,14,22,.55) 100%)}
.band{position:absolute;z-index:2;opacity:0;text-shadow:var(--tshadow)} /* own stacking context, so each band's ::before scrim sits above the video, not behind it */
.band::before{content:"";position:absolute;inset:-30% -20%;z-index:-1;pointer-events:none;opacity:calc(.25 + .75*var(--k,1));background:radial-gradient(ellipse 60% 55% at 50% 50%,rgba(8,14,22,var(--scrim,.62)) 0%,rgba(8,14,22,calc(var(--scrim,.62)*.66)) 46%,rgba(8,14,22,0) 76%)}
.band .btn{text-shadow:none}
.band-side{left:var(--gutter);top:44%;max-width:min(38vw,520px)}
.band-high{top:30%}
.band-line{width:fit-content;font-weight:300;font-size:clamp(34px,4.2vw,58px);line-height:1.05;letter-spacing:-.03em}
.band[data-fx=drift]{--scrim:.7}
.band-settle{left:50%;top:23%;width:min(100% - 2*var(--gutter),980px);transform:translateX(-50%);text-align:center}
.band-settle .display{margin-inline:auto}
.settle-sub{margin:20px auto 0;max-width:56ch;font-size:clamp(17px,1.5vw,20px);line-height:1.55;color:var(--text-on-deep-2)}
.cta-row{margin-top:28px;display:flex;flex-wrap:wrap;gap:16px 28px;align-items:baseline;justify-content:center}
.cta-row .btn{align-self:center}
.ring{position:absolute;left:50%;bottom:28px;width:36px;height:36px;margin-left:-18px;color:var(--accent-muted);transform:rotate(-90deg);transition:opacity .4s var(--ease-out)}
.ring circle{stroke-dashoffset:var(--ld,126)}
.stage.video-ready .ring,.stage.video-failed .ring{opacity:0}
@media (max-height:560px){.ring{display:none}}

/* The five still-hero gates. These strings must match GATES in js/site.js exactly. */
@media (max-width: 720px), (orientation: portrait) and (max-width: 1024px), (orientation: portrait) and (pointer: coarse), (orientation: landscape) and (pointer: coarse) and (max-height: 560px), (prefers-reduced-motion: reduce){
  .hero{height:auto}
  .stage{position:relative;height:auto;min-height:100vh;min-height:100svh;display:flex;align-items:flex-start;padding:calc(19vh + 28px) 0 72px;padding-top:calc(19svh + 28px)}
  .poster{background-image:url(../assets/hero-ending.jpg)}
  .hero-video,.ring,.band-side{display:none}
  .band{--k:1}
  .band-settle{position:relative;left:auto;top:auto;transform:none;opacity:1;margin-inline:auto;--scrim:.8}
  /* On tall crops the points of light sit behind the words, so the pool of calm water is deeper and wider here */
  .band-settle::before{inset:-14% -10%;background:radial-gradient(ellipse 70% 64% at 50% 50%,rgba(8,14,22,var(--scrim)) 0%,rgba(8,14,22,calc(var(--scrim)*.92)) 52%,rgba(8,14,22,0) 82%)}
  .band-settle .text-link{padding:6px 14px;border-radius:999px;background:rgba(8,14,22,.62);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
}

/* Sections */
.section{position:relative;padding-block:var(--section-gap)}
.section + .section{border-top:1px solid var(--hairline)}
/* The film ends in deep water; this lets it fade into the cream page instead of cutting */
.approach{padding-top:calc(var(--section-gap) + 24vh)}
.approach::before{content:"";position:absolute;left:0;right:0;top:-14vh;height:58vh;pointer-events:none;background:linear-gradient(rgba(8,16,27,0) 0%,var(--canvas-abyss) 24%,#0F2A33 40%,#1F4F45 59%,#7FA88F 77%,#E4EBDD 91%,var(--canvas) 100%)}
.approach .lede{margin-top:32px}

.service-list{margin-top:64px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:clamp(32px,6vw,96px)}
.service-list li{display:grid;grid-template-columns:minmax(0,11ch) minmax(0,1fr);gap:24px;align-items:baseline;padding-block:24px;border-top:1px solid var(--hairline)}
.service-list h3{font-weight:500;font-size:17px}
.service-list p{color:var(--text-secondary);font-size:17px;max-width:42ch}
@media (max-width:820px){.service-list{grid-template-columns:1fr}.service-list li{grid-template-columns:1fr;gap:6px}}

.how-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);column-gap:clamp(40px,7vw,112px);align-items:start}
.steps{display:grid;gap:0;padding-top:6px}
.step{position:relative;display:grid;grid-template-columns:48px minmax(0,1fr);column-gap:24px;padding-block:28px;border-top:1px solid var(--hairline)}
.step:last-child{border-bottom:1px solid var(--hairline)}
.step-num{grid-row:span 2;font:400 13px/1.9 var(--mono);color:var(--text-secondary)}
.step h3{font-weight:300;font-size:clamp(28px,2.8vw,38px);letter-spacing:-.02em;line-height:1.1}
.step p{margin-top:8px;color:var(--text-secondary);max-width:44ch}
@media (max-width:820px){.how-grid{grid-template-columns:1fr;row-gap:48px}}

.faq{margin-top:56px;max-width:880px}
.faq details{border-top:1px solid var(--hairline)}
.faq details:last-child{border-bottom:1px solid var(--hairline)}
.faq summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:baseline;gap:24px;padding-block:26px;font-size:clamp(19px,1.8vw,23px);font-weight:400;letter-spacing:-.01em}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";flex:none;width:16px;height:16px;background:var(--accent-line);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.5v13M1.5 8h13' stroke='%23000' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.5v13M1.5 8h13' stroke='%23000' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;transition:transform .2s var(--ease-out)} /* a drawn plus, not a typed character */
.faq details[open] summary::after{transform:rotate(45deg)}
.faq details p{padding:0 48px 28px 0;color:var(--text-secondary);max-width:62ch}
.faq details[open] p{animation:answer-in .2s var(--ease-out)} /* the answer eases in on every open; closing snaps */
@keyframes answer-in{from{opacity:0;transform:translateY(-4px)}}

.about .wrap{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,5fr);column-gap:clamp(40px,7vw,112px);align-items:end}
.about .label{grid-column:1/-1}
.about .statement{font-size:clamp(40px,5.4vw,72px);max-width:12ch}
@media (max-width:820px){.about .wrap{grid-template-columns:1fr;row-gap:28px}}

.contact-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(48px,7vw,112px);align-items:start}
.contact-call .lede{margin:24px 0 36px}
.form{display:grid;gap:18px;padding:clamp(28px,4vw,48px);background:var(--panel);border:1px solid var(--hairline)}
.form-title{font-weight:300;font-size:28px;letter-spacing:-.02em;margin-bottom:6px}
.field{display:grid;gap:8px}
.field label{font:400 12px/1.2 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--text-secondary)}
.field .opt{text-transform:none;letter-spacing:0}
.field input,.field textarea{width:100%;padding:13px 14px;background:var(--canvas);border:1px solid var(--hairline-strong);border-radius:0;transition:border-color .15s ease}
.field input::placeholder,.field textarea::placeholder{color:var(--placeholder)}
.field input,.field textarea{caret-color:var(--accent-line)}
.field input:focus-visible,.field textarea:focus-visible{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 1px var(--accent-line)}
.field textarea{resize:vertical;min-height:120px}
.form .btn{justify-self:start;margin-top:6px}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-status{min-height:1.5em;font-size:16px}
.form-status.ok{color:var(--accent)}
.form-status.err{color:var(--error)}
.btn:disabled{opacity:.6;cursor:progress} /* Send message while the message is on its way */
@media (max-width:900px){.contact-grid{grid-template-columns:1fr}}

.footer{background:var(--canvas-deep);color:var(--text-on-deep-2);padding-block:72px 56px}
.footer-grid{display:grid;grid-template-columns:auto 1fr auto;gap:24px 48px;align-items:center}
.footer-logo{width:150px;height:auto}
.footer-place{font-size:15px}
.footer-links{display:flex;gap:28px;font-size:15px}
.footer-links a{color:var(--text-on-deep);text-underline-offset:4px}
.footer-fine{grid-column:1/-1;font:400 12px/1.2 var(--mono);letter-spacing:.04em;opacity:.7}
@media (max-width:820px){.footer-grid{grid-template-columns:1fr}}

/* The thread: one line drawn down the page by js/site.js */
main{position:relative}
.thread{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;z-index:0}
.thread-path{fill:none;stroke:var(--accent-line);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;opacity:.7}
main > .section > .wrap{position:relative;z-index:1}

/* Split text and the four hero entrances, all scrubbed off each band's --k */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.split .w{display:inline-block;white-space:nowrap}
.split .c{display:inline-block}
.band{pointer-events:none}
.band.live{pointer-events:auto}
.band[data-fx=drift] .w{--kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);opacity:var(--kc);transform:translateY(calc((1 - var(--kc))*-24px))}
.band[data-fx=focus] .band-line{position:relative}
.band[data-fx=focus] .split.sharp{opacity:var(--k,0)}
.band[data-fx=focus] .split.soft{position:absolute;left:0;top:0;width:100%;filter:blur(10px);opacity:calc(1 - var(--k,0))}
.band[data-fx=weave] .c{--kc:clamp(0,(var(--k,0) - var(--th,0))*2.6,1);opacity:var(--kc);transform:translateY(calc((1 - var(--kc))*var(--jy,0px)))}
.band[data-fx=rise] .display .w{--kc:clamp(0,(var(--k,0) - var(--th,0))*3,1);opacity:var(--kc);transform:translateY(calc((1 - var(--kc))*28px))}
.band[data-fx=rise] .settle-sub{opacity:clamp(0,(var(--k,0) - .66)*4,1)}
.band[data-fx=rise] .cta-row{opacity:clamp(0,(var(--k,0) - .78)*5,1)}
.poster-end{opacity:0;transition:opacity .9s var(--ease-out)}
.stage.show-ending .poster-end{opacity:1}
.cue{position:absolute;left:50%;bottom:24px;margin-left:-11px;color:var(--text-on-deep-2)}

/* Section entrances: staggered, then the delays retire so hovers respond instantly */
.js .reveal{opacity:0;transform:translateY(12px);transition:opacity .6s var(--ease-out),transform .6s var(--ease-out);transition-delay:calc(var(--i,0)*60ms)}
.js .section.in .reveal{opacity:1;transform:none}
.js .section.settled .reveal{transition-delay:0s}

/* One living element per section: a slow glow on the label's dot while the section is on screen */
.label{position:relative}
.label::after{content:"";position:absolute;left:0;top:50%;width:6px;height:6px;margin-top:-3px;border-radius:50%;box-shadow:0 0 0 4px rgba(46,139,110,.16),0 0 14px rgba(46,139,110,.5);opacity:0}
.section.in-view .label::after{animation:glow 5s var(--ease-io) -1.6s infinite}
@keyframes glow{0%,100%{opacity:0}50%{opacity:1}}

/* The page's one background environment: a few points of light drifting very slowly */
body::before{content:"";position:fixed;inset:-10%;z-index:-1;pointer-events:none;opacity:.9;
  background:
    radial-gradient(circle at 12% 18%,rgba(124,196,160,.22) 0 1.5px,transparent 2.5px),
    radial-gradient(circle at 78% 26%,rgba(124,196,160,.18) 0 1.5px,transparent 2.5px),
    radial-gradient(circle at 34% 62%,rgba(46,139,110,.14) 0 1.5px,transparent 2.5px),
    radial-gradient(circle at 88% 74%,rgba(124,196,160,.2) 0 1.5px,transparent 2.5px),
    radial-gradient(circle at 56% 88%,rgba(46,139,110,.12) 0 1.5px,transparent 2.5px),
    radial-gradient(circle at 6% 84%,rgba(124,196,160,.16) 0 1.5px,transparent 2.5px);
  animation:drift 96s var(--ease-io) -20s infinite alternate;will-change:transform}
@keyframes drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(-2%,-4%,0)}}
body.paused *,body.paused *::before,body.paused *::after,body.paused::before{animation-play-state:paused !important}

/* Reduced motion: final states, nothing moves */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none !important;transition:none !important;transition-delay:0s !important}
  .js .reveal{opacity:1;transform:none}
  .btn:active{transform:none}
  .band{--k:1}
}
