/*
Theme Name: Kronvall
Theme URI: https://kronvall.com
Author: Kronvall
Author URI: https://kronvall.com
Description: Boutique advisory theme for Kronvall — a senior-led firm bringing advisory, technology and operations together. Cream editorial canvas anchored by deep navy folds, with gold used as a precision accent. One-page composition: hero, about, vision & mission, capabilities, why Kronvall, approach and contact.
Version: 1.22.4
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: kronvall
Tags: one-page, business, advisory, custom-logo, custom-menu, editor-style, translation-ready
*/

/* ==========================================================================
   01 — TOKENS
   ========================================================================== */
:root{
  /* Brand — sampled from the Kronvall logo and the approved moodboard */
  --navy:#042943;          /* logo wordmark, primary ink */
  --navy-deep:#021C2E;     /* footer, depth */
  --navy-soft:#0A3D63;     /* raised surfaces on navy */
  --navy-line:rgba(4,41,67,.12);
  --gold:#D4AF37;          /* decorative + text on navy */
  --gold-ink:#8A6220;      /* gold that passes contrast on cream */
  --gold-light:#EBD08A;
  --ivory:#F2E8D5;         /* brand cream */
  --slate:#4A5568;
  --forest:#0F4D3E;

  /* Surfaces */
  --paper:#FAF7F1;
  --paper-2:#F4EFE5;
  --paper-3:#EDE6D8;

  /* Ink */
  --ink:var(--navy);
  --ink-2:#3C566B;
  --ink-3:var(--slate);
  --on-navy:#EDE4D4;
  --on-navy-2:rgba(237,228,212,.68);
  --on-navy-3:rgba(237,228,212,.44);
  --on-navy-line:rgba(237,228,212,.16);

  /* Type */
  --f-display:"Fraunces","Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
  --f-body:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --f-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --t-hero:clamp(3.1rem,1.1rem + 7.4vw,7.25rem);
  --t-h2:clamp(2.05rem,1.1rem + 3.5vw,4rem);
  --t-h3:clamp(1.35rem,1.05rem + 1.05vw,1.85rem);
  --t-lead:clamp(1.22rem,1.02rem + .78vw,1.6rem);
  --t-body:clamp(1rem,.97rem + .14vw,1.075rem);
  --t-small:.9375rem;
  --t-mono:.6875rem;

  /* Space */
  --head-h:clamp(80px,5.8vw,100px);
  --gutter:clamp(1.25rem,4vw,3.5rem);
  --wrap:1320px;
  --sect:clamp(5rem,3rem + 8.5vw,9.75rem);
  --stack:clamp(2.5rem,1.5rem + 3vw,4.5rem);

  /* Form */
  --r-xl:32px; --r-lg:22px; --r-md:14px; --r-sm:9px; --r-pill:999px;
  --shadow-sm:0 1px 2px rgba(4,41,67,.05),0 6px 18px -10px rgba(4,41,67,.18);
  --shadow-md:0 2px 4px rgba(4,41,67,.05),0 24px 48px -28px rgba(4,41,67,.32);
  --shadow-lg:0 40px 80px -44px rgba(2,28,46,.55);
  --ease:cubic-bezier(.22,.61,.36,1);
  --speed:.5s;
}

/* ==========================================================================
   02 — RESET + BASE
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:calc(var(--head-h) + 26px)}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--f-body);font-size:var(--t-body);font-weight:400;line-height:1.7;
  font-optical-sizing:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  /* `clip` rather than `hidden`, and the two together on purpose. `hidden` on
     one axis forces the other to `auto`, which turns the body into a scroll
     container — and a scroll container is what `position:sticky` resolves
     against, so the pinned hero would stop pinning. `clip` holds the same
     horizontal overflow back without creating one. The `hidden` ahead of it
     is the fallback for anything that does not know `clip`: it keeps the
     overflow in check there and the fold simply degrades to a normal,
     unpinned one. */
  overflow-x:hidden;overflow-x:clip;
}
img,svg,video{max-width:100%;height:auto;display:block}
h1,h2,h3,h4,p,figure,blockquote{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
button,input,textarea,select{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
::selection{background:var(--navy);color:var(--ivory)}
:focus-visible{outline:2px solid var(--gold-ink);outline-offset:3px;border-radius:4px}
.k-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ==========================================================================
   03 — TYPE PRIMITIVES
   ========================================================================== */
.k-eyebrow{
  font-family:var(--f-mono);font-size:var(--t-mono);font-weight:500;
  letter-spacing:.19em;text-transform:uppercase;color:var(--ink-3);
  display:inline-flex;align-items:center;gap:.6em;line-height:1;
}
.k-eyebrow::before{content:"";width:1.9em;height:1px;background:linear-gradient(90deg,transparent,var(--gold-ink));flex:none}
.k-eyebrow--pill{
  padding:.65em 1.1em;border:1px solid var(--navy-line);border-radius:var(--r-pill);
  background:rgba(255,255,255,.5);color:var(--ink-2);
}
.k-eyebrow--pill::before{display:none}
.k-eyebrow--onnavy{color:var(--on-navy-3)}
/* The pill's light fill is for cream backgrounds; on navy it needs its own. */
.k-eyebrow--pill.k-eyebrow--onnavy{
  background:rgba(237,228,212,.1);border-color:var(--on-navy-line);color:var(--on-navy-2);
}
.k-eyebrow--onnavy::before{background:linear-gradient(90deg,transparent,var(--gold))}

.k-h1{
  --h1-lh:.94;
  font-family:var(--f-display);font-weight:300;font-size:var(--t-hero);
  line-height:var(--h1-lh);letter-spacing:-.028em;color:var(--ink);text-wrap:balance;
}
.k-h2{
  font-family:var(--f-display);font-weight:350;font-size:var(--t-h2);
  line-height:1.04;letter-spacing:-.022em;color:var(--ink);text-wrap:balance;
}
.k-h3{
  font-family:var(--f-display);font-weight:400;font-size:var(--t-h3);
  line-height:1.16;letter-spacing:-.014em;color:var(--ink);
}
.k-accent{
  font-style:italic;font-weight:300;
  background:linear-gradient(96deg,#8A6220 0%,#D4AF37 46%,#9A6F1F 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  padding-right:.06em;
}
@supports not (background-clip:text){.k-accent{color:var(--gold-ink);background:none}}

/* --------------------------------------------------------------------------
   Scroll-controlled accent word
   --------------------------------------------------------------------------
   A window exactly one line box tall, opened up by --roll-t / --roll-b so
   ascenders and italic tails are not shaved off, with matching negative
   margins so none of that extra height reaches the layout. The words stack
   inside it and are advanced by scroll in assets/js/theme.js; each carries its
   own gradient so the sweep always fits the word on screen rather than the
   animating width of the box.
   ----------------------------------------------------------------------- */
.k-roll{
  --roll-t:.24em;--roll-b:.22em;
  position:relative;display:inline-block;vertical-align:top;overflow:hidden;
  box-sizing:content-box;background:none;
  height:calc(var(--h1-lh,1) * 1em + var(--roll-t) + var(--roll-b));
  margin-top:calc(var(--roll-t) * -1);margin-bottom:calc(var(--roll-b) * -1);
  transition:width .62s var(--ease);
}
.k-roll__word{
  /* The padding runs top AND bottom so the word's box matches the window.
     background-clip:text only paints inside that box, so a descender hanging
     past it — the g in "Strengthens" — would lose its gradient and vanish.
     Matching the two also makes the box exactly one travel unit tall. */
  display:block;padding-top:var(--roll-t);padding-bottom:var(--roll-b);
  line-height:var(--h1-lh,1);white-space:nowrap;
  background:linear-gradient(96deg,#8A6220 0%,#D4AF37 46%,#9A6F1F 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* Only the first word holds the box open; the rest wait behind it. */
.k-roll__word + .k-roll__word{position:absolute;left:0;top:0;opacity:0}
.k-roll.is-ready .k-roll__word{position:absolute;left:0;top:0}
@supports not (background-clip:text){.k-roll__word{color:var(--gold-ink);background:none}}
@media (prefers-reduced-motion:reduce){
  .k-roll{transition:none}
}
.k-lead{font-family:var(--f-display);font-weight:350;font-size:var(--t-lead);line-height:1.32;letter-spacing:-.012em;color:var(--ink);text-wrap:balance}
.k-body{color:var(--ink-3);max-width:64ch}
.k-body + .k-body{margin-top:1.15em}
.k-body strong{color:var(--ink);font-weight:600}

.k-onnavy{color:var(--on-navy)}
.k-onnavy .k-h2,.k-onnavy .k-h3,.k-onnavy .k-lead{color:var(--on-navy)}
.k-onnavy .k-body{color:var(--on-navy-2)}

/* ==========================================================================
   04 — LAYOUT
   ========================================================================== */
.k-wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter)}
.k-section{padding-block:var(--sect);position:relative}
.k-section--navy{
  background:var(--navy);color:var(--on-navy);
  background-image:radial-gradient(120% 90% at 15% 0%,#0A3D63 0%,#042943 46%,#021C2E 100%);
  position:relative;overflow:hidden;
}
.k-section--navy::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(2,28,46,.5),transparent 22%,transparent 78%,rgba(2,28,46,.55));
}
.k-section--navy > .k-wrap{position:relative;z-index:2}
.k-texture{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background-repeat:no-repeat;background-size:cover;background-position:center;
  opacity:.18;
}
.k-head{display:grid;gap:1.5rem;margin-bottom:var(--stack)}
.k-head__top{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:2rem}
.k-head__lede{max-width:46ch}
@media (min-width:900px){
  .k-head--split{grid-template-columns:minmax(0,1.05fr) minmax(0,.85fr);align-items:end;gap:clamp(2rem,4vw,5rem)}
  .k-head--split .k-eyebrow{grid-column:1/-1}
}
.k-rule{height:1px;background:var(--navy-line);border:0;margin:0}
.k-head > .k-h2{max-width:19ch}
.k-head--split > .k-h2{max-width:none}
.k-skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  padding:.95em 1.4em;background:var(--navy);color:var(--ivory);
  font-size:var(--t-small);border-radius:0 0 var(--r-md) 0;
}
.k-skip:focus{left:0}
.k-onnavy .k-rule,.k-section--navy .k-rule{background:var(--on-navy-line)}

/* ==========================================================================
   05 — BUTTONS
   ========================================================================== */
.k-btn{
  display:inline-flex;align-items:center;gap:.7em;
  padding:1.02em 1.75em;border-radius:var(--r-pill);
  font-size:var(--t-small);font-weight:550;letter-spacing:-.005em;line-height:1;
  border:1px solid transparent;white-space:nowrap;
  transition:background var(--speed) var(--ease),color var(--speed) var(--ease),
             border-color var(--speed) var(--ease),transform .3s var(--ease),box-shadow .4s var(--ease);
}
.k-btn svg{width:1.05em;height:1.05em;flex:none;transition:transform .4s var(--ease)}
.k-btn:hover{transform:translateY(-2px)}
.k-btn:hover svg{transform:translateX(3px)}
.k-btn:active{transform:translateY(0)}

.k-btn--primary{background:var(--navy);color:var(--ivory);box-shadow:var(--shadow-sm)}
.k-btn--primary:hover{background:var(--navy-deep);box-shadow:var(--shadow-md)}
.k-btn--ghost{border-color:var(--navy-line);color:var(--ink);background:rgba(255,255,255,.45)}
.k-btn--ghost:hover{border-color:var(--gold-ink);background:#fff}
.k-btn--gold{
  color:var(--navy);border-color:transparent;
  background:linear-gradient(96deg,#B8892B,#EBD08A 42%,#D4AF37 70%,#A87F26);
  box-shadow:0 10px 30px -14px rgba(138,98,32,.75);
}
.k-btn--gold:hover{filter:brightness(1.07);box-shadow:0 16px 38px -14px rgba(138,98,32,.85)}
.k-btn--onnavy{border-color:var(--on-navy-line);color:var(--on-navy);background:rgba(237,228,212,.05)}
.k-btn--onnavy:hover{border-color:var(--gold);background:rgba(212,175,55,.1)}
.k-btn--sm{padding:.82em 1.3em;font-size:.875rem}

.k-link{
  display:inline-flex;align-items:center;gap:.55em;font-size:var(--t-small);font-weight:550;
  color:var(--ink);padding-bottom:.35em;border-bottom:1px solid var(--navy-line);
  transition:border-color var(--speed) var(--ease),color var(--speed) var(--ease),gap .3s var(--ease);
}
.k-link:hover{border-color:var(--gold-ink);color:var(--gold-ink);gap:.85em}

/* ==========================================================================
   06 — TAGS
   ========================================================================== */
.k-tags{display:flex;flex-wrap:wrap;gap:.5rem}

/* One treatment for every tag on the page — the capability services, the
   About caption and the showcase status chips all share it, so a tag reads
   the same wherever it appears. Only the differences each context genuinely
   needs are set further down. */
.k-tag,
.k-figure__tag,
.k-status__state{
  font-family:var(--f-mono);font-size:var(--t-mono);font-weight:400;
  letter-spacing:.14em;text-transform:uppercase;line-height:1.32;
  padding:.58em .9em;border-radius:var(--r-pill);
  border:1px solid var(--navy-line);
  color:var(--ink-2);background:rgba(255,255,255,.55);
  transition:border-color .35s var(--ease),color .35s var(--ease),background .35s var(--ease);
}
.k-tag:hover{border-color:var(--gold-ink);color:var(--gold-ink);background:#fff}
.k-tag--onnavy{border-color:var(--on-navy-line);color:var(--on-navy-2);background:rgba(237,228,212,.04)}

/* ==========================================================================
   07 — SITE HEADER
   ========================================================================== */
.k-header{
  position:fixed;top:0;left:0;right:0;z-index:80;
  transition:background .45s var(--ease),box-shadow .45s var(--ease),border-color .45s var(--ease);
  border-bottom:1px solid transparent;
}
.k-header.is-stuck{
  background:rgba(250,247,241,.82);backdrop-filter:saturate(160%) blur(14px);
  -webkit-backdrop-filter:saturate(160%) blur(14px);
  border-bottom-color:var(--navy-line);
}
.k-header__inner{
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  height:var(--head-h);
}
.k-logo{display:block;flex:none}
.k-logo img{height:clamp(20px,1.7vw,25px);width:auto}
.k-nav{display:none}
@media (min-width:1024px){
  .k-nav{display:flex;align-items:center;gap:clamp(1.5rem,2.6vw,2.9rem)}
}
.k-nav a{
  position:relative;font-size:.9375rem;font-weight:500;color:var(--ink);
  padding-block:.4rem;transition:color .35s var(--ease);
}
.k-nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,var(--gold-ink),var(--gold));
  transform:scaleX(0);transform-origin:left;transition:transform .45s var(--ease);
}
.k-nav a:hover,.k-nav a[aria-current="true"]{color:var(--gold-ink)}
.k-nav a:hover::after,.k-nav a[aria-current="true"]::after{transform:scaleX(1)}
.k-header__cta{display:none}
@media (min-width:1024px){.k-header__cta{display:inline-flex}}

.k-burger{
  display:inline-flex;flex-direction:column;justify-content:center;gap:5px;
  width:46px;height:46px;align-items:center;border:1px solid var(--navy-line);
  border-radius:var(--r-pill);background:rgba(255,255,255,.5);
}
@media (min-width:1024px){.k-burger{display:none}}
.k-burger span{display:block;width:17px;height:1.5px;background:var(--ink);transition:transform .4s var(--ease),opacity .3s var(--ease)}
.k-burger[aria-expanded="true"] span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.k-burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.k-burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

.k-mobile{
  position:fixed;inset:0;z-index:75;background:var(--paper);
  padding:calc(var(--head-h) + 2.5rem) var(--gutter) 3rem;
  display:flex;flex-direction:column;gap:.25rem;
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .4s var(--ease),transform .4s var(--ease),visibility .4s;
}
.k-mobile.is-open{opacity:1;visibility:visible;transform:none}
.k-mobile a:not(.k-btn){
  font-family:var(--f-display);font-weight:350;font-size:clamp(1.9rem,7vw,2.6rem);
  line-height:1.35;letter-spacing:-.02em;padding-block:.35rem;border-bottom:1px solid var(--navy-line);
}
.k-mobile a:not(.k-btn):last-of-type{border-bottom:0}
.k-mobile .k-btn{margin-top:2rem;align-self:flex-start}
body.k-locked{overflow:hidden}

/* ==========================================================================
   08 — HERO
   ========================================================================== */
/* The section is a scroll runway; __pin is the screen that stays put while
   the runway is consumed. Note there is no `overflow:hidden` here — that
   would make this a scroll container and the sticky child would stop
   sticking. The clipping belongs on __pin, which is where it now is. */
.k-hero{position:relative}
/* Only once the script takes over. Without it the section is exactly as tall
   as the one screen inside it, sticky has nothing to travel through, and the
   fold behaves like any other. */
.k-hero.is-staged{height:260svh}
.k-hero__pin{
  /* The photograph is the fold, so the fold takes the screen. The copy stays
     top-weighted inside it rather than centring, which leaves the lower third
     to the building — that is where the glazed floors are, and where the
     pointer has the most to open. */
  position:sticky;top:0;min-height:100svh;
  padding-top:clamp(8rem,11.5vw,12rem);padding-bottom:clamp(4rem,7vw,6.5rem);
  text-align:center;overflow:hidden;
}
.k-hero__bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
/* The header is transparent until it sticks, which was free when the fold
   opened on pale sky. This pair has no sky — the glazing runs to the top edge
   — so the nav would sit straight on the mullions for the one frame before
   the first scroll. This band gives it something quiet to sit on.

   Deliberately not part of .k-hero__haze: the haze is down to 30% at rest,
   which is exactly the moment the header needs this most. As ::after it also
   paints above the picture rather than under it. */
.k-hero__bg::after{
  content:"";position:absolute;inset:0 0 auto;height:clamp(160px,22vh,260px);
  background:linear-gradient(to bottom,
    rgba(250,247,241,.78) 0%,
    rgba(250,247,241,.6) 28%,
    rgba(250,247,241,.3) 58%,
    rgba(250,247,241,.1) 80%,
    rgba(250,247,241,0) 100%);
}
.k-hero__grid{
  position:absolute;inset:-10% -10% auto;height:70%;
  background-repeat:repeat;background-size:70px 70px;opacity:.5;
  -webkit-mask-image:radial-gradient(72% 62% at 50% 26%,#000 0%,transparent 74%);
  mask-image:radial-gradient(72% 62% at 50% 26%,#000 0%,transparent 74%);
}
.k-hero__glow{
  position:absolute;left:50%;top:-16%;width:min(1180px,132%);aspect-ratio:1.55/1;transform:translateX(-50%);
  background:
    radial-gradient(46% 46% at 50% 42%,rgba(212,175,55,.16),transparent 68%),
    radial-gradient(60% 52% at 50% 68%,rgba(4,41,67,.11),transparent 72%);
}

/* Registered so the three of them interpolate. An unregistered custom
   property animates discretely — the drift below would jump at its midpoint
   instead of travelling — and `inherits:true` is what carries the animated
   value down to the masked layer inside the scene. */
@property --k-x{syntax:"<length-percentage>";inherits:true;initial-value:50%}
@property --k-y{syntax:"<length-percentage>";inherits:true;initial-value:50%}
@property --k-r{syntax:"<length>";inherits:true;initial-value:170px}

/* --------------------------------------------------------------------------
   The building, and the pointer that opens it
   --------------------------------------------------------------------------
   Two exposures of one render stacked in perfect register: `__facade`, the
   glazed elevation, and `__cutaway`, the same frame with the walls off and
   the floors at work. The cutaway is masked to a soft circle parked at
   --k-x / --k-y, both driven from the script, so the pointer dissolves the
   windows wherever it goes and the interior shows through.

   Everything reads from custom properties rather than being re-written as
   styles, so a frame costs two property writes and the compositor does the
   rest. The scene is inert until the script adds `is-live`, which is why a
   page without JavaScript simply keeps the facade.
   -------------------------------------------------------------------------- */
.k-hero__scene{
  position:absolute;inset:0;
  /* Sized to open about two floors near the corner. Big enough that the
     cutaway reads as a section through the building rather than a peephole,
     small enough to stay a spotlight rather than just cross-fading the whole
     picture. The frame does contain places with nothing to reveal — the
     stone wall on the left, the plaza along the bottom — which is what the
     drift below is steered around. */
  --k-x:50%; --k-y:60%; --k-r:clamp(165px,19vw,300px);
}
.k-hero__facade,
.k-hero__cutaway{
  position:absolute;inset:0;
  background-repeat:no-repeat;
  /* `cover`, and nothing cleverer — but for a different reason than a tight
     crop would give. This render is the building whole, with sky above and a
     plaza, pool and skyline below, and it is already composed for a wide
     frame: the glazing fills most of the height on its own, leaving only the
     bottom fifth to the steps and the water.

     An earlier establishing shot did need scaling off the height and
     shifting to push its road out of frame. Tried here, that crop takes the
     roofline, the entrance steps, the pool and the skyline with it and
     leaves an anonymous wall of glass — everything that makes this a picture
     of *this* building rather than an office block. Filling the frame and
     centring keeps all of it. */
  background-size:cover;
  background-position:50% 50%;
}
.k-hero__cutaway{
  opacity:0;transition:opacity .5s var(--ease);
  -webkit-mask-image:radial-gradient(circle var(--k-r) at var(--k-x) var(--k-y),#000 0%,#000 34%,rgba(0,0,0,.6) 60%,transparent 100%);
          mask-image:radial-gradient(circle var(--k-r) at var(--k-x) var(--k-y),#000 0%,#000 34%,rgba(0,0,0,.6) 60%,transparent 100%);
}
.k-hero__scene.is-live .k-hero__cutaway{opacity:1}

.k-hero__haze{
  position:absolute;inset:0;
  /* Full-bleed. The base layer never reaches transparent — its lightest stop
     is .66 — so every corner of the fold is covered and the scrim reads as
     one wash coming over the whole picture rather than a bright patch
     floating in the middle of it. The radial on top is no longer doing the
     covering, only adding extra light directly under the copy.

     The base is weighted for the body paragraph, which is --ink-3 slate
     rather than navy and is the first thing to fail over the dark glazing.
     Measured over the darkest glass in the render the base alone holds about
     4.6:1 and the copy sits nearer 8:1 with the radial on top. If you lift
     the picture back up by thinning these, check that grey line, not the H1.

     Note this is opacity-multiplied by --haze from the script, so at rest the
     whole thing is down to 30% and the photograph reads almost clean. These
     numbers describe the fully-arrived state, not the opening frame. */
  background:
    radial-gradient(76% 52% at 50% 36%,
      rgba(250,247,241,.62) 0%,
      rgba(250,247,241,.45) 45%,
      rgba(250,247,241,.16) 75%,
      rgba(250,247,241,0) 100%),
    linear-gradient(to bottom,
      rgba(250,247,241,.76) 0%,
      rgba(250,247,241,.7) 34%,
      rgba(250,247,241,.66) 62%,
      rgba(250,247,241,.72) 88%,
      rgba(250,247,241,.84) 100%);
}

/* A gold ring rides the same circle, so the reveal reads as a deliberate
   instrument rather than a hole in the picture. As ::after it paints above
   every child of the scene, the scrim included — which is the whole reason
   the scrim sits inside the scene rather than beside it. Move it out and the
   ring is buried wherever the pool of light is thickest. */
.k-hero__scene::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  opacity:0;transition:opacity .5s var(--ease);
  background:radial-gradient(circle var(--k-r) at var(--k-x) var(--k-y),
    transparent 0%,transparent 52%,
    rgba(212,175,55,.28) 62%,rgba(212,175,55,.1) 70%,transparent 84%);
}
.k-hero__scene.is-live::after{opacity:1}

/* Coarse pointers get no cursor to follow. Rather than leave the mechanic
   sitting there undiscovered, the circle drifts across the facade on its
   own — the same reveal, just self-driven. */
@media (hover:none){
  .k-hero__scene{animation:k-drift 15s var(--ease) infinite}
}
/* Steered to stay on glass. The building sits centre-right in the frame, so
   a sweep starting further left spends half the loop on the blank stone wall
   with nothing to open, and one running lower ends up in the planting and the
   pool. This arc crosses the middle two floors, which is the part of the
   render with the most going on behind the glazing. */
@keyframes k-drift{
  0%,100%{--k-x:42%; --k-y:60%}
  50%    {--k-x:74%; --k-y:44%}
}

@media (prefers-reduced-motion:reduce){
  .k-hero__scene{animation:none}
  .k-hero__cutaway,.k-hero__scene::after{transition:none}
}

/* The hint sits under the copy and steps aside once the pointer has been
   anywhere near the building. */
/* Two things have an opinion about whether the hint is visible: the scroll
   position that carries it in with the rest of the copy, and whether the
   pointer has already been across the building — once someone has found the
   reveal for themselves the line has nothing left to tell them. Rather than
   let those two fight over `opacity` and leave the later rule to win, they
   are separate numbers that multiply, so whichever says hide, hides.

   --peek is registered so it can be transitioned on its own. That matters:
   --p tracks the scroll and must not be smoothed, while --peek is a discrete
   event that should fade. Animating the property rather than the opacity is
   what lets one be eased and the other stay instant. */
@property --peek{syntax:"<number>";inherits:true;initial-value:1}
.k-hero{transition:--peek .45s var(--ease)}
.k-hero.is-peeked{--peek:0}
.k-hero__peek{
  position:relative;z-index:2;margin-top:clamp(.5rem,1.4vw,1.2rem);
  display:inline-flex;align-items:center;gap:.5rem;
  font-family:var(--f-mono);font-size:var(--t-mono);
  text-transform:uppercase;letter-spacing:.16em;
  color:var(--ink-3);
  opacity:calc(var(--p,1) * var(--peek,1) * .75);
}
.k-hero__peek svg{width:1.15em;height:1.15em;flex:none;color:var(--gold-ink)}
@media (max-width:639.98px){.k-hero__peek{display:none}}

/* --------------------------------------------------------------------------
   The copy, arriving
   --------------------------------------------------------------------------
   The fold opens on the building alone and the copy is carried up into it one
   line at a time as the runway is scrolled. Each element reads a single
   number, --p, that the script writes per frame: 0 is waiting below, 1 is
   home. Opacity and offset both come off it, so a stage costs one property
   write and stays on the compositor.

   All of this is scoped to .is-staged, and --p falls back to 1 everywhere it
   is not set. That is deliberate and load-bearing: with no JavaScript, or
   with reduced motion, the class never lands, every element resolves to
   opacity 1 and no offset, and the fold is simply a fold. The copy is never
   left hidden behind a script that did not run — which is exactly the trap
   the [data-reveal] system falls into, and why the hero no longer uses it.
   -------------------------------------------------------------------------- */
.k-hero.is-staged .k-hero__inner > *{
  opacity:var(--p,1);
  transform:translateY(calc((1 - var(--p,1)) * var(--k-rise,2.8rem)));
  will-change:opacity,transform;
}
/* Transparent is not the same as gone: without this the buttons are still
   clickable while nobody can see them. */
.k-hero.is-staged .k-hero__inner > .is-off{pointer-events:none}
.k-hero.is-staged .k-hero__peek{opacity:calc(var(--p,1) * var(--peek,1) * .75)}

/* The scrim exists to hold type over the picture, so it has no business being
   there before the type is. It blooms in with the copy — at rest the fold is
   the photograph at nearly full contrast, and by the time the body paragraph
   arrives the pool of light is at full strength under it. */
.k-hero.is-staged .k-hero__haze{opacity:var(--haze,1)}

@media (prefers-reduced-motion:reduce){
  .k-hero.is-staged .k-hero__inner > *{opacity:1;transform:none}
}
.k-hero__inner{position:relative;z-index:2;display:grid;justify-items:center;gap:clamp(1.6rem,2.6vw,2.4rem)}
/* justify-items:center makes children max-content sized; keep them inside the wrap. */
.k-hero__inner > *{max-width:100%}
/* 17ch, not 15: the heading has to hold the longest word the accent rolls
   through without re-wrapping, or the whole hero jumps a line every cycle.
   Below 860px the accent takes its own line instead, so the heading is two
   lines whichever word is showing. Both numbers are set with room to spare —
   they have to survive a longer word being added to the list and the display
   face falling back to a system serif with wider metrics. Re-check the line
   count at 860px and just above it if you add a word. */
.k-hero .k-h1{max-width:17ch}
@media (max-width:859.98px){.k-hero .k-h1__lead{display:block}}
.k-hero__support{
  font-family:var(--f-display);font-weight:350;line-height:1.34;letter-spacing:-.012em;
  font-size:clamp(1.18rem,.98rem + .78vw,1.58rem);color:var(--ink);
}
.k-hero__support span{display:block}
.k-hero__body{max-width:60ch;color:var(--ink-3);margin-inline:auto}
.k-hero__cta{display:flex;flex-wrap:wrap;gap:.8rem;justify-content:center}

/* ==========================================================================
   09 — SHOWCASE BAND
   --------------------------------------------------------------------------
   Four tiles in the reference composition. Columns run 1.6 / 1.25 / 1 over
   two equal rows at an overall 2.757:1 ratio, so the collage keeps the exact
   proportions of the reference at every width from 960px up:

     ┌──────────┬───────────┬────────┐
     │          │  status   │  mark  │
     │  media   ├───────────┴────────┤
     │          │        note        │
     └──────────┴────────────────────┘

   Every interior measurement is expressed in cqi — 1% of the tile's own
   content box — so the contents scale with the collage rather than drifting
   out of proportion, with rem clamps holding the type readable as it shrinks.
   Because cqi measures the content box, a tile that needs its interior in
   reference proportion carries no padding of its own.
   ========================================================================== */
/* This fold carries no section padding of its own — the collage is meant to
   sit high under the hero — but it does need room at the top now that the
   hero ends on a full-bleed photograph rather than fading out into paper.
   Against a hard picture edge the tiles were landing flush, with nothing to
   separate two competing images. A little more than one --sect gives the
   photograph somewhere to land without breaking the page's rhythm. */
.k-showcase{padding-top:clamp(6.5rem,4rem + 9vw,13rem);padding-bottom:0}
.k-showcase .k-wrap{max-width:none}
.k-showcase__grid{display:grid;gap:clamp(.5rem,.94vw,1.15rem)}
.k-tile{
  position:relative;overflow:hidden;border-radius:var(--r-lg);
  background:var(--paper-3);container-type:inline-size;
}

/* --- tile 1 · media ---------------------------------------------------- */
.k-tile__media{position:relative;overflow:hidden;border-radius:inherit;aspect-ratio:4/5}
.k-tile__media img,.k-tile__video{
  display:block;width:100%;height:100%;object-fit:cover;
  transition:transform 1.1s var(--ease);
}
.k-tile--media:hover .k-tile__media img{transform:scale(1.045)}

.k-tile__toggle{
  position:absolute;z-index:2;
  right:clamp(.75rem,4.1cqi,1.9rem);bottom:clamp(.75rem,4.1cqi,1.9rem);
  display:grid;place-items:center;
  width:clamp(1.75rem,4.5cqi,2.35rem);height:clamp(1.75rem,4.5cqi,2.35rem);
  border-radius:calc(var(--r-sm) - 1px);border:1px solid rgba(250,247,241,.5);
  background:rgba(250,247,241,.8);color:var(--navy);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:background var(--speed) var(--ease),transform .3s var(--ease);
}
.k-tile__toggle:hover{background:var(--paper);transform:translateY(-2px)}
.k-tile__icon{width:56%;height:56%;fill:currentColor}
.k-tile__icon--play{display:none}
.k-tile__toggle[aria-pressed="false"] .k-tile__icon--pause{display:none}
.k-tile__toggle[aria-pressed="false"] .k-tile__icon--play{display:block}

/* --- tile 2 · engagement status ---------------------------------------- */
.k-tile--status{
  background:
    radial-gradient(96% 118% at 4% 2%,rgba(104,114,158,.62),rgba(104,114,158,0) 52%),
    radial-gradient(88% 116% at 96% 96%,rgba(186,98,40,.58),rgba(186,98,40,0) 60%),
    radial-gradient(76% 96% at 62% 18%,rgba(242,232,213,.9),rgba(242,232,213,0) 62%),
    linear-gradient(126deg,#EFE2C4 0%,#E3C67F 32%,#D4AF37 54%,#E6C88C 74%,#F2E8D5 100%);
}
.k-tile__grain{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background-repeat:repeat;background-size:180px 180px;
  mix-blend-mode:overlay;opacity:.72;
}
.k-status{
  position:relative;z-index:2;height:100%;
  display:flex;flex-direction:column;justify-content:center;
  gap:clamp(.5rem,3.26cqi,1.25rem);
  padding:clamp(1.25rem,7cqi,2.5rem) 21.2%;
  list-style:none;margin:0;
}
.k-status__row{
  display:flex;align-items:center;justify-content:space-between;
  gap:.75rem;
  min-height:clamp(1.9rem,7.2cqi,2.7rem);
  padding-inline:clamp(.6rem,2.75cqi,1.05rem);
  border-radius:clamp(5px,1.4cqi,9px);
  background:rgba(250,247,241,.94);color:var(--ink);
  box-shadow:0 1px 2px rgba(4,41,67,.06);
}
.k-status__label{
  font-size:clamp(.7rem,2.57cqi,.95rem);font-weight:450;letter-spacing:-.005em;line-height:1;
}
/* Sized in cqi so it scales with the aspect-locked tile; everything else
   comes from the shared tag rule above. */
.k-status__state{
  font-size:clamp(.5rem,1.72cqi,.69rem);line-height:1;white-space:nowrap;
  padding:.55em .82em;
}
.k-status__row.is-active{background:var(--navy-deep);color:var(--on-navy);box-shadow:var(--shadow-sm)}
.k-status__row.is-active .k-status__state{
  background:rgba(237,228,212,.13);border-color:rgba(237,228,212,.22);color:var(--gold-light);
}

/* --- tile 3 · signage --------------------------------------------------- */
/* This held the crown mark centred on a tinted panel. It now holds a
   photograph, so the image fills the frame and is cropped to it rather than
   sized inside it. `display:grid` with one child stretches it, which gives
   the image a definite height to resolve `height:100%` against — the tile's
   own height comes from the collage's grid row, not from its content. */
.k-tile--mark{display:grid;overflow:hidden}
.k-tile--mark img{
  display:block;width:100%;height:100%;object-fit:cover;
  transition:transform 1.1s var(--ease);
}
.k-tile--mark:hover img{transform:scale(1.045)}

/* --- tile 4 · engagement note ------------------------------------------- */
.k-tile--note{
  display:grid;place-items:center;
  background:var(--navy-deep);
  background-image:radial-gradient(120% 150% at 50% 0%,#062F4C,#021C2E 68%);
  color:var(--on-navy);
}
/* 38.9% of the tile, centred — the note column's share in the reference.
   The tile carries no padding of its own: cqi below resolves against the
   tile's content box, so padding here would pull the interior out of scale. */
.k-note{width:38.9%;max-width:calc(100% - 2.5rem)}
.k-note__card{
  background:var(--paper);color:var(--ink);
  border-radius:clamp(7px,.94cqi,12px);
  padding:clamp(.6rem,1.55cqi,1.2rem) clamp(.65rem,1.69cqi,1.3rem) clamp(.65rem,1.75cqi,1.35rem);
  box-shadow:0 18px 40px -26px rgba(2,28,46,.9);
}
.k-note__kicker{
  display:flex;align-items:center;gap:.7em;
  font-family:var(--f-mono);font-size:clamp(.48rem,1.03cqi,.72rem);
  letter-spacing:.16em;text-transform:uppercase;line-height:1;color:var(--ink-2);
  padding-bottom:clamp(.45rem,1.15cqi,.9rem);
  border-bottom:1px solid var(--navy-line);
}
.k-note__kicker svg{width:1.25em;height:1.25em;flex:none;color:var(--ink-3)}
.k-note__body{
  margin-top:clamp(.45rem,1.15cqi,.9rem);
  font-size:clamp(.62rem,1.41cqi,.95rem);line-height:1.45;color:var(--ink);
}
.k-note__foot{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  margin-top:clamp(.5rem,1.87cqi,1.35rem);
}
.k-note__sender{
  display:flex;align-items:center;gap:.7em;min-width:0;
  font-family:var(--f-mono);font-size:clamp(.46rem,.99cqi,.69rem);
  letter-spacing:.15em;text-transform:uppercase;line-height:1.3;color:var(--on-navy-2);
}
.k-note__sender svg{width:1.35em;height:1.35em;flex:none;color:var(--gold)}
.k-note__cta{font-size:clamp(.6rem,1.31cqi,.875rem);padding:.8em 1.25em}

/* --- the composition ----------------------------------------------------
   The collage locks to the reference ratio from 960px up. Below that the
   three columns cannot hold the note card at a legible size, so the tiles
   stack instead of squeezing the type.
   ------------------------------------------------------------------------ */
@media (min-width:960px){
  .k-showcase__grid{
    grid-template-columns:minmax(0,1.6fr) minmax(0,1.25fr) minmax(0,1fr);
    grid-template-rows:repeat(2,minmax(0,1fr));
    aspect-ratio:2.757/1;
  }
  .k-showcase__grid > :nth-child(1){grid-column:1;grid-row:1/3}
  .k-showcase__grid > :nth-child(2){grid-column:2;grid-row:1}
  .k-showcase__grid > :nth-child(3){grid-column:3;grid-row:1}
  .k-showcase__grid > :nth-child(4){grid-column:2/4;grid-row:2}
  .k-tile__media{aspect-ratio:auto;height:100%}
}
@media (max-width:959.98px){
  /* Stacked: the portrait crop only earns its height on narrow screens. */
  .k-tile--status,.k-tile--mark{min-height:15rem}
  .k-status{padding-inline:clamp(1.25rem,12%,3rem)}
  .k-tile--note{padding:clamp(1.5rem,7%,2.75rem) clamp(1.25rem,5%,2.5rem)}
  .k-note{width:100%;max-width:100%}
}
@media (min-width:600px) and (max-width:959.98px){
  .k-tile__media{aspect-ratio:16/9}
  .k-note{width:min(100%,30rem);margin-inline:auto}
}

/* ==========================================================================
   10 — ABOUT · FOUNDER
   --------------------------------------------------------------------------
   One two-column composition serving both folds: text one side, a notched
   photograph the other. The Founder fold mirrors it with --flip so the two
   share a language without repeating a layout.

   The notch is a bite out of the photo's top corner, painted in the page
   colour rather than clipped, so the shape survives without clip-path: a
   rounded corner on the covering block reads as a concave corner on the
   photo, and the radial gradient below it rounds the convex corner where the
   photo's edge steps back out. Both folds must therefore sit on a flat
   --paper background for the shape to read.
   ========================================================================== */
.k-split{display:grid;gap:clamp(2.75rem,5vw,4.5rem)}
@media (min-width:1000px){
  .k-split{
    grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
    gap:clamp(2.5rem,4.5vw,5.5rem);align-items:stretch;
  }
  /* The photo runs the full depth of the fold so its bottom edge lands level
     with the last line of copy on the left. The frame keeps its aspect ratio
     as a floor — if the column of type is ever shorter than that, the picture
     holds its own proportions instead of squashing. */
  .k-figure{display:grid;grid-template-rows:1fr}
  /* Both axes are stated so the aspect ratio cannot claim the width back off
     the stretched height — it only sizes the frame when the height is free. */
  .k-figure__frame{width:100%;height:100%}
}
.k-split__col{display:grid;justify-items:start;gap:clamp(1.1rem,1.7vw,1.5rem)}
.k-split__title{margin:0}
.k-split__title-lead{display:block}
.k-split__col .k-body{max-width:54ch}
/* About and Vision/Mission share a continuous light canvas. Split one normal
   section interval between them so the boundary does not read as a doubled
   gap from two full --sect paddings. */
.k-about{padding-bottom:clamp(2.5rem,1.5rem + 4.25vw,4.875rem)}

/* --- the notched figure -------------------------------------------------- */
.k-figure{position:relative;margin:0}
.k-figure__frame{
  --notch-w:10.3%;--notch-h:39.7%;
  position:relative;overflow:hidden;
  aspect-ratio:930/755;
  border-radius:var(--r-xl);border-top-left-radius:0;
  background:var(--paper-3);
}
.k-figure__frame img{display:block;width:100%;height:100%;object-fit:cover}
.k-figure__notch{
  position:absolute;left:0;top:0;z-index:2;
  width:var(--notch-w);height:var(--notch-h);
  background:var(--paper);
  border-bottom-right-radius:var(--r-xl);
}
/* Once the frame stretches past its natural aspect ratio, a notch measured as
   a percentage of the height would grow into a long slot. Sizing it from its
   own width instead holds the reference's bite at one shape however tall the
   picture runs. The ratio is the reference notch: 10.3% × 39.7% of 930 × 755. */
@media (min-width:1000px){
  .k-figure__notch{height:auto;aspect-ratio:95.79/299.74}
}
/* Rounds the photo's outer corner where it steps back out under the notch. */
.k-figure__notch::after{
  content:"";position:absolute;left:0;top:100%;
  width:var(--r-xl);height:var(--r-xl);
  background:radial-gradient(circle at 100% 100%,transparent calc(var(--r-xl) - .5px),var(--paper) var(--r-xl));
}


/* --- caption card -------------------------------------------------------- */
.k-figure__card{
  position:absolute;right:0;bottom:0;z-index:3;
  width:min(52%,23rem);
  display:flex;align-items:center;gap:clamp(.7rem,1.2vw,1rem);
  padding:clamp(.7rem,1.1vw,.95rem);
  background:var(--paper);color:var(--ink);
  border:1px solid rgba(4,41,67,.07);
  border-radius:var(--r-md);border-bottom-right-radius:var(--r-xl);
  box-shadow:0 24px 48px -28px rgba(2,28,46,.5);
}
.k-figure__thumb{
  flex:none;display:grid;place-items:center;
  width:clamp(2.6rem,4.4vw,3.4rem);aspect-ratio:1;
  border-radius:calc(var(--r-md) - 5px);background:var(--paper-2);
}
.k-figure__thumb img{width:56%;height:auto;display:block}
.k-figure__cardbody{display:grid;justify-items:start;gap:.5rem;min-width:0}
.k-figure__name{
  font-family:var(--f-display);font-weight:400;line-height:1.15;letter-spacing:-.015em;
  font-size:clamp(.98rem,.9rem + .35vw,1.18rem);color:var(--ink);
}
/* Inherits the shared tag rule; nothing left to say. */

/* --- founder spotlight ---------------------------------------------------
   One card: a letterboxed photograph with a column of type over its
   right-hand side, and a caption band beneath. The photo's inner grid and the
   band's grid share --aside and --pad, so the right-hand column runs on one
   axis straight down the card.
   ------------------------------------------------------------------------ */
.k-founder{padding-top:0}
.k-spotlight{
  --pad:clamp(1.35rem,2.6vw,2.75rem);
  /* Wider than the reference's 25%: the quote and the biography both wrap to
     four lines here instead of six and seven, which keeps the overlay and the
     caption band shallow. */
  --aside:40%;
  --gutter-x:clamp(1.5rem,3vw,2.75rem);
  overflow:hidden;border-radius:var(--r-xl);
  background:var(--paper-3);box-shadow:var(--shadow-md);
}
.k-spotlight__media{position:relative;aspect-ratio:1732/608;background:var(--navy-deep)}
.k-spotlight__photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.k-spotlight__inner{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,var(--aside));
  gap:var(--gutter-x);padding:var(--pad);
}
.k-spotlight__inner{position:absolute;inset:0;z-index:2}
.k-spotlight__overlay{
  grid-column:2 / 3;align-self:center;justify-self:stretch;min-width:0;
  display:grid;justify-items:start;gap:clamp(.85rem,1.5vw,1.3rem);
  color:var(--on-navy);
}
.k-spotlight__title{margin:0;max-width:20ch;color:var(--on-navy)}
.k-spotlight__title-lead{display:block}
.k-spotlight__overlay .k-body{color:var(--on-navy-2)}

/* The composition needs real width: below this the founder copy column
   becomes too narrow, so the card stacks instead. */
@media (max-width:1099.98px){
  .k-spotlight{--aside:auto}
  .k-spotlight__media{aspect-ratio:4/5}
  .k-spotlight__inner{grid-template-columns:minmax(0,1fr)}
  .k-spotlight__inner{align-content:space-between}
  .k-spotlight__overlay{grid-column:1 / -1;align-self:end}
  .k-spotlight__title{max-width:none}
}

@media (max-width:559.98px){
  .k-figure__card{
    position:static;width:100%;margin-top:.9rem;
    border-radius:var(--r-md);
  }
  .k-figure__frame{aspect-ratio:4/3}
  /* The About photo is a portrait, and 4:3 is the hardest crop it takes on
     the page. Biasing the frame above centre keeps the speaker's head clear
     of the top edge; the wider frames have room and stay centred. */
  .k-figure__frame img{object-position:50% 36%}
}

/* ==========================================================================
   11 — VISION & MISSION
   --------------------------------------------------------------------------
   Open editorial rows pair each statement with a code-native SVG system.
   There are no card frames or image backgrounds; fine rules establish rhythm
   without boxing the content in.
   ========================================================================== */
.k-vm{
  padding-top:clamp(2.5rem,1.5rem + 4.25vw,4.875rem);
  background:linear-gradient(180deg,var(--paper) 0%,var(--paper-2) 100%);
}
.k-vm__head{display:grid;justify-items:start;gap:clamp(.9rem,1.6vw,1.3rem);margin-bottom:var(--stack)}
.k-vm__title{margin:0;max-width:22ch}
.k-vm__title-lead{display:block}

.k-vm__grid{display:grid}
.k-vm-item{
  display:grid;grid-template-columns:minmax(260px,.9fr) minmax(0,1.1fr);
  align-items:center;gap:clamp(2rem,6vw,7rem);
  padding-block:clamp(2.4rem,5.5vw,5.5rem);
  border-top:1px solid var(--navy-line);
}
.k-vm-item:last-child{border-bottom:1px solid var(--navy-line)}
.k-vm-item:nth-child(even) .k-vm-art{order:2}
.k-vm-item:nth-child(even) .k-vm-copy{order:1}

.k-vm-art{display:grid;place-items:center;min-width:0;color:var(--navy)}
.k-vm-art svg{display:block;width:min(100%,34rem);height:auto;overflow:visible}
.k-vm-art__ring,
.k-vm-art__arm,
.k-vm-art__ticks,
.k-vm-art__flow,
.k-vm-art__diamond{
  fill:none;stroke:currentColor;stroke-width:1.35;vector-effect:non-scaling-stroke;
}
.k-vm-art__ring{opacity:.22}
.k-vm-art__ring--wide{stroke-dasharray:3 9;opacity:.28}
.k-vm-art__ring--strong{stroke:var(--gold-ink);opacity:.72}
.k-vm-art__arm{opacity:.34}
.k-vm-art__ticks{opacity:.2}
.k-vm-art__node{fill:var(--navy);stroke:var(--paper);stroke-width:3;vector-effect:non-scaling-stroke}
.k-vm-art__node--gold{fill:var(--gold);stroke:var(--paper-2)}
.k-vm-art__pulse{fill:rgba(212,175,55,.16);stroke:var(--gold-ink);stroke-width:1;vector-effect:non-scaling-stroke}
.k-vm-art__flow{stroke:var(--navy);stroke-dasharray:.08 .05;opacity:.34}
.k-vm-art__flow--out{stroke:var(--gold-ink);opacity:.72}
.k-vm-art__diamond{fill:var(--paper);stroke:var(--gold-ink);stroke-width:1.5}

.k-vm-copy{display:grid;justify-items:start;gap:clamp(.8rem,1.5vw,1.25rem);max-width:42rem}
.k-vm-copy__meta{
  display:flex;align-items:center;justify-content:flex-start;gap:1rem;
  width:100%;padding-bottom:.8rem;border-bottom:1px solid var(--navy-line);
  font-family:var(--f-mono);font-size:var(--t-mono);letter-spacing:.16em;
  text-transform:uppercase;line-height:1;color:var(--ink-2);
}
.k-vm-copy__statement{
  margin:0;font-family:var(--f-display);font-weight:350;
  font-size:clamp(1.65rem,1.12rem + 1.65vw,2.75rem);
  line-height:1.12;letter-spacing:-.025em;color:var(--ink);
}
.k-vm-copy__text{
  font-size:var(--t-body);line-height:1.62;color:var(--ink-3);max-width:56ch;
}

@media (max-width:799.98px){
  .k-vm-item{grid-template-columns:minmax(0,1fr);gap:1.4rem}
  .k-vm-item:nth-child(even) .k-vm-art,
  .k-vm-item:nth-child(even) .k-vm-copy{order:initial}
  .k-vm-art svg{width:min(100%,27rem)}
}

/* ==========================================================================
   12 — CAPABILITIES (slider)
   --------------------------------------------------------------------------
   One discipline per slide, laid out as in the reference: the photograph on
   the left, everything written about that discipline on the right. Four
   disciplines with eight or nine services each would run enormously long
   stacked down the page, so they are moved through instead.

   The track is the shared scroll-snap slider from section 13, with
   --full making each slide fill it rather than peek.
   ========================================================================== */
.k-caps__head{
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;
  gap:2rem;margin-bottom:var(--stack);
}
.k-caps__lead{display:grid;justify-items:start;gap:clamp(.9rem,1.6vw,1.3rem)}
.k-caps__lede{max-width:46ch}

/* --- slider primitives ---------------------------------------------------
   Shared by any slider on the page; Capabilities is currently the only one.
   ------------------------------------------------------------------------ */
.k-arrows{display:flex;gap:.6rem;flex:none}
.k-arrows[hidden]{display:none}
.k-arrow{
  width:52px;height:52px;border-radius:50%;border:1px solid var(--on-navy-line);
  display:grid;place-items:center;color:var(--on-navy);
  transition:border-color .4s var(--ease),background .4s var(--ease),color .4s var(--ease),opacity .4s var(--ease);
}
.k-arrow svg{width:17px;height:17px}
.k-arrow:hover:not(:disabled){border-color:var(--gold);background:rgba(212,175,55,.12);color:var(--gold)}
.k-arrow:disabled{opacity:.28;cursor:default}
.k-arrows--ink .k-arrow{border-color:var(--navy-line);color:var(--ink)}
.k-arrows--ink .k-arrow:hover:not(:disabled){border-color:var(--gold-ink);background:rgba(212,175,55,.1);color:var(--gold-ink)}

.k-track{
  display:flex;gap:clamp(1rem,1.6vw,1.4rem);
  overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;
  padding-bottom:.5rem;
}
.k-track::-webkit-scrollbar{display:none}
.k-slide{display:grid;align-content:start;scroll-snap-align:start}
/* One item at a time: the slide fills the track rather than peeking. */
.k-track--full{align-items:flex-start}
.k-track--full .k-slide{flex:0 0 100%;scroll-snap-align:center}

.k-dots{display:flex;gap:.5rem;justify-content:center;margin-top:2rem}
.k-dots[hidden]{display:none}
.k-dot{width:7px;height:7px;border-radius:50%;background:var(--on-navy-line);transition:background .4s var(--ease),width .4s var(--ease)}
.k-dot.is-active{background:var(--gold);width:24px;border-radius:var(--r-pill)}
.k-dots--ink .k-dot{background:var(--navy-line)}
.k-dots--ink .k-dot.is-active{background:var(--gold-ink)}

.k-cslide{
  gap:clamp(1.5rem,3vw,2.5rem);
  align-content:start;min-width:0;
}
@media (min-width:900px){
  .k-cslide{
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:clamp(2rem,4.5vw,4rem);align-items:stretch;
  }
}
.k-cslide__media{
  overflow:hidden;min-width:0;width:100%;max-width:100%;border-radius:var(--r-lg);
  aspect-ratio:794/408;background:var(--paper-3);
}
.k-cslide__media img{display:block;width:100%;max-width:100%;height:100%;object-fit:cover}

.k-cslide__body{display:grid;justify-items:start;gap:.75rem;align-content:start;min-width:0}
@media (min-width:900px){
  .k-cslide__media{grid-column:1 / 2;grid-row:1;position:relative;aspect-ratio:auto}
  .k-cslide__media img{position:absolute;inset:0}
  .k-cslide__body{grid-column:2 / 3;grid-row:1}
}
.k-cslide__title{
  margin:0;font-family:var(--f-display);font-weight:400;
  font-size:clamp(1.5rem,1.15rem + 1.5vw,2.3rem);
  line-height:1.12;letter-spacing:-.02em;color:var(--ink);
}
p.k-cslide__line{
  font-family:var(--f-display);font-style:italic;font-weight:300;
  font-size:clamp(1.02rem,.95rem + .35vw,1.22rem);
  line-height:1.3;color:var(--gold-ink);
}
p.k-cslide__desc{color:var(--ink-3);max-width:52ch;margin-top:.15rem}
.k-cslide .k-tags{margin-top:.6rem}

/* ==========================================================================
   13 — WHY KRONVALL (open stepped principles)
   --------------------------------------------------------------------------
   A centred head over three unboxed columns, each set lower than the one
   before it. The clean navy gradient is the only visual surface.
   ========================================================================== */
.k-why__head{
  display:grid;justify-items:center;text-align:center;
  gap:clamp(.9rem,1.6vw,1.35rem);margin-bottom:var(--stack);
}
.k-why__head .k-h2{max-width:20ch}
.k-why__lede{max-width:62ch;color:var(--on-navy-2)}

/* --align runs 0 → 1 as the fold scrolls in, and theme.js resolves --step to
   the measured stagger in pixels. At 0 the cards sit in the reference's
   staircase; at 1 they have risen level with each other and stay there. The
   grid pulls its own bottom margin up by the same amount, so the space the
   staircase needed is given back rather than left as a hole. Both default to
   0 / 0px, which leaves the staircase intact when the script never runs. */
.k-why__grid{
  display:grid;gap:clamp(1rem,1.6vw,1.35rem);align-items:start;
  --align:0;--step:0px;
}
@media (min-width:820px){
  .k-why__grid{
    grid-template-columns:repeat(3,minmax(0,1fr));
    margin-bottom:calc(-1 * var(--align) * var(--step) * 2);
  }
  /* The staircase. Percentages resolve against the column width, so the
     step stays proportional rather than drifting as the grid narrows. */
  .k-why__grid > :nth-child(1){--n:0}
  .k-why__grid > :nth-child(2){--n:1;margin-top:16.3%}
  .k-why__grid > :nth-child(3){--n:2;margin-top:32.6%}
  /* The cell carries the alignment; the card inside keeps its own reveal
     transform, so the two never fight over the same property. */
  .k-why__cell{
    transform:translateY(calc(-1 * var(--align) * var(--step) * var(--n,0)));
    will-change:transform;
  }
}

.k-wcard{
  display:grid;grid-template-rows:auto minmax(7rem,1fr) auto;
  justify-items:center;text-align:center;
  min-height:clamp(20rem,29vw,25rem);
  padding:clamp(.75rem,2vw,1.75rem);
}
.k-wcard__head{display:grid;justify-items:center;gap:.3rem}
.k-wcard__title{
  margin:0;font-family:var(--f-display);font-weight:400;
  font-size:clamp(1.25rem,1.05rem + .8vw,1.75rem);
  line-height:1.15;letter-spacing:-.018em;color:var(--on-navy);
}
p.k-wcard__sub{
  font-family:var(--f-display);font-style:italic;font-weight:300;
  font-size:var(--t-small);line-height:1.3;color:var(--gold);
}

/* The mark takes the middle of the card, as in the reference. */
.k-wcard__mark{flex:1;display:grid;place-items:center;padding-block:clamp(1rem,2vw,1.75rem)}
/* The mark is inlined SVG filled with currentColor, so it takes the accent
   from here rather than shipping a colour of its own. */
.k-wcard__icon{
  display:block;width:clamp(2.75rem,31%,6.5rem);height:auto;
  color:#fff;
  transition:transform .6s var(--ease);
}
.k-wcard:hover .k-wcard__icon{transform:scale(1.06)}

p.k-wcard__body{max-width:34ch;color:var(--on-navy-2);font-size:var(--t-small);line-height:1.6}

@media (max-width:819.98px){
  .k-wcard{grid-template-rows:auto;min-height:0;gap:1.5rem;padding:clamp(1rem,4%,1.5rem)}
  .k-wcard__mark{padding-block:.5rem}
  .k-wcard__icon{width:3.25rem}
}

/* ==========================================================================
   14 — APPROACH / PROCESS
   ========================================================================== */
.k-approach__head{
  display:grid;justify-items:center;text-align:center;
  gap:clamp(.9rem,1.6vw,1.35rem);margin-bottom:var(--stack);
}
.k-approach__head .k-h2{max-width:20ch}
.k-approach__head .k-body{max-width:62ch;color:var(--ink-3)}
.k-approach__grid{display:grid;gap:clamp(2.5rem,4vw,4.5rem)}
@media (min-width:960px){.k-approach__grid{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);align-items:start}}
.k-approach__media{border-radius:var(--r-xl);overflow:hidden;box-shadow:var(--shadow-md);position:relative}
@media (min-width:960px){.k-approach__media{position:sticky;top:calc(var(--head-h) + 2.5rem)}}
.k-approach__media img{width:100%;aspect-ratio:4/5;object-fit:cover;object-position:27% 50%}

.k-steps{position:relative;padding-left:0}
.k-steps__line{position:absolute;left:0;top:0;bottom:0;width:1px;background:var(--navy-line)}
.k-steps__fill{position:absolute;left:0;top:0;width:1px;height:0;background:linear-gradient(180deg,var(--gold),var(--gold-ink));transition:height .25s linear}
@media (min-width:560px){.k-steps{padding-left:clamp(1.6rem,3vw,2.6rem)}}
.k-step{
  display:grid;gap:.55rem;padding-block:clamp(1.5rem,2.4vw,2.1rem);
  border-bottom:1px solid var(--navy-line);position:relative;
  transition:opacity .5s var(--ease);
}
.k-step:first-child{padding-top:0}
.k-step:last-child{border-bottom:0;padding-bottom:0}
.k-step__title{font-family:var(--f-display);font-weight:400;font-size:clamp(1.5rem,1.1rem + 1.5vw,2.15rem);line-height:1.1;letter-spacing:-.02em;color:var(--ink)}
.k-step p{color:var(--ink-3);max-width:52ch}

/* ==========================================================================
   15 — CONTACT
   --------------------------------------------------------------------------
   The closing fold, built on the hero's bones: the section is a scroll
   runway, __pin is the screen that stays put while the runway is consumed,
   and the photograph parallaxes inside it as the copy stages in. The content
   is bottom-weighted — heading and mail button down the left, paragraph and
   location rows down the right.

   Note there is no `overflow` on .k-cta. That would make the section a scroll
   container and the sticky child would stop sticking — the same trap the hero
   documents. The clipping and the corner radius both belong on __pin.

   Everything degrades: without the script the runway class never lands, the
   fold is exactly as tall as the one screen inside it, --p and --settle hold
   their resting values, and the copy is simply there.
   ========================================================================== */
.k-cta{
  --settle:0;   /* 0 arriving (corners rounded) → 1 locked (corners flat) */
  --run:0;      /* 0 as the pin locks → 1 as the runway lets go */
  --cta-radius:clamp(2.5rem,6vw,7.5rem);
  /* How far the picture travels each way inside the pin. The media is
     oversized by twice this to cover it, and the source is 2400px wide, so
     there is resolution to spend on a parallax this deep. */
  --cta-travel:clamp(4rem,12svh,11rem);
  position:relative;color:var(--on-navy);padding-block:0;
}
/* Only once the script takes over, exactly as the hero does it. min-height
   rather than a fixed height: if the copy ever outgrows one screen on a short
   viewport the pin grows with it instead of overflowing a fixed box, which
   would leave the sticky child with nowhere to travel. */
.k-cta.is-staged{min-height:200svh}
.k-cta__pin{
  position:sticky;top:0;min-height:100svh;
  overflow:hidden;isolation:isolate;
  border-radius:
    calc(var(--cta-radius) * (1 - var(--settle)))
    calc(var(--cta-radius) * (1 - var(--settle))) 0 0;
  display:grid;align-items:end;
  padding-block:clamp(3.5rem,7vw,7rem);
}
/* Oversized by the travel at both ends and offset up by one, so the picture
   still covers the pin at either extreme of the parallax. */
.k-cta__media{
  position:absolute;z-index:-1;left:0;right:0;
  top:calc(var(--cta-travel) * -1);
  height:calc(100% + var(--cta-travel) * 2);
  /* +travel at the start, -travel at the end: the window pans down the
     picture as the runway is consumed, so the fold opens on sky and cranes
     down the glass. */
  transform:translateY(calc((1 - var(--run) * 2) * var(--cta-travel)));
  will-change:transform;
}
.k-cta__media img{
  width:100%;height:100%;object-fit:cover;object-position:50% 50%;
  /* A slow push in under the pan, for depth. */
  transform:scale(calc(1 + var(--run) * .06));
  will-change:transform;
}
/* The picture is bright glass against open sky and the copy crosses the
   brightest part of it, so the scrim does the whole job of making white type
   legible. It runs bottom-up only: the copy occupies both halves of the fold,
   so darkening one side would leave the other unprotected, and the small type
   on the right is what needs the cover most. Kept in brand navy rather than
   black so the fold still reads as Kronvall. */
.k-cta__scrim{
  position:absolute;inset:0;
  background:linear-gradient(180deg,
    rgba(2,28,46,.10) 0%,
    rgba(2,28,46,.34) 22%,
    rgba(2,28,46,.80) 46%,
    rgba(2,28,46,.91) 72%,
    rgba(2,28,46,.94) 100%);
}
.k-cta__wrap{position:relative;z-index:2}
.k-cta__inner{display:grid;gap:clamp(2rem,4vw,3.25rem);position:relative}
/* The scrim above ramps with the fold, but the copy sits at very different
   heights inside it — two short columns on a wide screen, one tall stack on a
   narrow one — so at 500px the eyebrow lands on the brightest glass and drops
   under 3:1. This second wash is anchored to the content box instead and
   bleeds out past the pin on three sides, so the cover follows the copy at
   every width. It is what actually holds the small type at contrast; the
   scrim only has to set the mood. The feather is a length, not a percentage,
   so the bleed below cannot stretch it.
   Absolutely positioned, so it is not a grid item. */
.k-cta__inner::before{
  --feather:clamp(2.25rem,5vw,4rem);
  content:"";position:absolute;z-index:-1;pointer-events:none;
  top:calc(var(--feather) * -1);bottom:-100vh;left:-100vw;right:-100vw;
  background:linear-gradient(180deg,
    rgba(2,28,46,0) 0,
    rgba(2,28,46,.62) var(--feather),
    rgba(2,28,46,.70) calc(var(--feather) + 5rem),
    rgba(2,28,46,.70) 100%);
}
@media (min-width:900px){
  /* The reference splits 7 of 16 columns to the heading and the last 4 to the
     paragraph, leaving a wide gap between them. Two uneven columns with a
     generous gap gives the same proportion without a column system. */
  .k-cta__inner{
    grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
    gap:clamp(2.5rem,6vw,7rem);align-items:end;
  }
}
.k-cta__lead{display:grid;justify-items:start;gap:clamp(1.4rem,2.4vw,2rem)}
/* --onnavy in the markup switches the eyebrow's leading rule to bright gold;
   the label itself takes full gold rather than that modifier's --on-navy-3,
   which is too faint to hold 4.5:1 over a photograph at 11px. */
.k-cta__lead .k-eyebrow{color:var(--gold)}
.k-cta__title{
  font-family:var(--f-display);font-weight:350;
  font-size:clamp(2.1rem,1.15rem + 3.4vw,3.9rem);
  line-height:1.03;letter-spacing:-.022em;color:var(--on-navy);
  margin:0;max-width:15ch;text-wrap:balance;
}
.k-cta__actions{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.6rem;margin:0}
.k-cta__aside{display:grid;gap:clamp(1.5rem,2.6vw,2.1rem);align-content:end}
/* --on-navy-2 is the muted body tone for flat navy panels; over a photograph
   it drops under 4.5:1 even with the scrim, so this fold takes a stronger
   tint of the same cream. */
.k-cta__body{color:rgba(237,228,212,.88);max-width:46ch}
.k-cta__meta{display:grid;gap:.9rem;margin:0;padding-top:clamp(1.25rem,2vw,1.6rem);border-top:1px solid var(--on-navy-line)}
.k-cta__row{display:grid;gap:.2rem}
.k-cta__row dt{font-family:var(--f-mono);font-size:var(--t-mono);letter-spacing:.19em;text-transform:uppercase;color:var(--gold)}
.k-cta__row dd{margin:0;font-size:var(--t-small);color:var(--on-navy);font-weight:500}

/* --- staged arrival ------------------------------------------------------
   The hero's system, and for the hero's reason: each staged element reads one
   number, --p, that the script writes per frame — 0 waiting below, 1 home —
   so a stage costs one property write and stays on the compositor.

   Scoped to .is-staged, and --p falls back to 1 wherever it is not set. That
   is load-bearing: with no script, or with reduced motion, the class never
   lands, every element resolves to opacity 1 and no offset, and the copy is
   never left hidden behind a script that did not run.
   ------------------------------------------------------------------------ */
.k-cta.is-staged [data-stage]{
  opacity:var(--p,1);
  transform:translateY(calc((1 - var(--p,1)) * var(--k-rise,2.2rem)));
  will-change:opacity,transform;
}
.k-cta.is-staged [data-stage].is-off{pointer-events:none}

@media (prefers-reduced-motion:reduce){
  .k-cta.is-staged [data-stage]{opacity:1;transform:none}
}

/* ==========================================================================
   16 — FOOTER
   ========================================================================== */
.k-footer{
  background:radial-gradient(120% 150% at 50% 0%,#0A3D63 0%,#042943 48%,#021C2E 100%);
  color:var(--on-navy);position:relative;overflow:hidden;
  padding-top:clamp(3.5rem,6vw,6rem);
}
.k-footer__grid{display:grid;gap:clamp(2.25rem,4vw,3.5rem);position:relative;z-index:2}
@media (min-width:820px){.k-footer__grid{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) minmax(0,1fr)}}
.k-footer__logo img{
  height:clamp(20px,1.7vw,25px);width:auto;
  filter:brightness(0) invert(1);
}
.k-footer__brand{display:grid;gap:1.35rem;align-content:start;max-width:34ch}
.k-footer__brand p{color:var(--on-navy-2);font-size:var(--t-small)}
.k-footer__mail{
  width:max-content;color:var(--on-navy-2);font-size:var(--t-small);
  border-bottom:1px solid var(--on-navy-line);
  transition:color .35s var(--ease),border-color .35s var(--ease);
}
.k-footer__mail:hover{color:var(--on-navy);border-color:var(--gold)}
.k-footer__col{display:grid;gap:1rem;align-content:start}
.k-footer__col h3{
  font-family:var(--f-mono);font-size:var(--t-mono);font-weight:500;letter-spacing:.19em;
  text-transform:uppercase;color:var(--gold);
}
.k-footer__col ul{display:grid;gap:.7rem}
.k-footer__col a{font-size:var(--t-small);color:var(--on-navy-2);transition:color .35s var(--ease),padding-left .35s var(--ease)}
.k-footer__col a:hover{color:var(--on-navy);padding-left:.3rem}
.k-footer__bar{
  margin-top:clamp(2.5rem,5vw,4rem);padding-block:1.75rem;
  border-top:1px solid var(--on-navy-line);position:relative;z-index:2;
  display:flex;flex-wrap:wrap;gap:1rem;justify-content:space-between;align-items:center;
}
.k-footer__bar p,.k-footer__bar a{
  font-family:var(--f-mono);font-size:var(--t-mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--on-navy-3);margin:0;
}
.k-footer__bar a:hover{color:var(--gold)}
.k-totop{
  display:inline-flex;align-items:center;gap:.6em;color:var(--on-navy-3);
  font-family:var(--f-mono);font-size:var(--t-mono);letter-spacing:.13em;text-transform:uppercase;
  transition:color .35s var(--ease);
}
.k-totop:hover{color:var(--gold)}
.k-totop svg{width:12px;height:12px;transition:transform .4s var(--ease)}
.k-totop:hover svg{transform:translateY(-3px)}

/* ==========================================================================
   17 — MOTION
   ========================================================================== */
[data-reveal]{opacity:0;transform:translateY(22px);transition:opacity .85s var(--ease),transform .85s var(--ease)}
[data-reveal].is-in{opacity:1;transform:none}
[data-reveal-delay="1"]{transition-delay:.09s}
[data-reveal-delay="2"]{transition-delay:.18s}
[data-reveal-delay="3"]{transition-delay:.27s}
[data-reveal-delay="4"]{transition-delay:.36s}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  [data-reveal]{opacity:1;transform:none}
}

/* ==========================================================================
   18 — WORDPRESS HOUSEKEEPING
   ========================================================================== */
.admin-bar .k-header{top:32px}
@media screen and (max-width:782px){.admin-bar .k-header{top:46px}}
.screen-reader-text{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.alignwide{width:100%;max-width:var(--wrap);margin-inline:auto}
.alignfull{width:100vw;max-width:100vw;margin-left:calc(50% - 50vw)}
.k-fallback{padding-block:calc(var(--sect) + 4rem) var(--sect)}
.k-fallback article{padding-block:2.5rem;border-bottom:1px solid var(--navy-line)}
.k-fallback article:last-child{border-bottom:0}
.k-fallback h2{font-family:var(--f-display);font-weight:400;font-size:var(--t-h3);letter-spacing:-.015em;margin-bottom:.6rem}
.k-fallback time{font-family:var(--f-mono);font-size:var(--t-mono);letter-spacing:.19em;text-transform:uppercase;color:var(--ink-3)}
.k-fallback .k-body{margin-top:.9rem}
.k-pagination{display:flex;gap:1rem;margin-top:3rem}
