/* ============================================================
   VĀK STUDIOS — SITE STYLES
   Colours and type follow the Vāk brand guidelines. Every colour
   and motion value is a custom property written by render.js from
   config.js — nothing is hardcoded twice.
   ============================================================ */

:root{
  /* render.js overwrites these from config.js; they are fallbacks. */
  --paper:    #f4f1ea;
  --ink:      #11110f;
  --muted:    #5d5b55;
  --line:     #d7d1c5;
  --soft:     #e9e4da;
  --charcoal: #262522;
  --oxide:    #a63d2f;

  --disp-w: 500;
  --base: 100%;

  --marquee: 44s;
  --reveal-shift: 26px;
  --reveal-speed: .9s;

  /* Instrument Sans is the brand face and covers Latin. Noto Sans
     Devanagari sits behind it only to supply glyphs Instrument Sans
     does not have, so Devanagari inside a heading or sentence renders
     in the brand's Devanagari face instead of a system default.
     Latin rendering is unchanged. */
  --font-sans: "Instrument Sans", "Noto Sans Devanagari", Arial, Helvetica, sans-serif;
  --font-deva: "Noto Sans Devanagari", "Nirmala UI", sans-serif;

  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --rule: 1px;
  --ease: cubic-bezier(.22, 1, .36, 1);
}

*,*::before,*::after{ box-sizing:border-box; }
html{ font-size:var(--base); }

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-sans);
  font-size:clamp(.95rem,1.02vw,1.06rem);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
h1,h2,h3,p,ul,ol{ margin:0; padding:0; }
ul,ol{ list-style:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }

:focus-visible{ outline:2px solid var(--oxide); outline-offset:3px; }
::selection{ background:var(--oxide); color:var(--paper); }

/* ---- shared ------------------------------------------------ */
.wrap{ padding-inline:var(--pad); }

.mono{
  font-size:.7rem; font-weight:500;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--muted);
}

/* Display type: Instrument Sans, mid weight, tight tracking. */
.display, .sec__title, .svc__title,
.contact__heading, .kin__loud, .pre__mark{
  font-family:var(--font-sans);
  font-weight:var(--disp-w);
  letter-spacing:-.05em;
  line-height:.98;
  text-wrap:balance;
}

/* ---- reveals ----------------------------------------------- */
.js [data-rv]{
  opacity:0;
  transform:translateY(var(--reveal-shift));
  transition:opacity var(--reveal-speed) var(--ease),
             transform var(--reveal-speed) var(--ease);
  transition-delay:var(--d,0s);
}
.js [data-rv].in{ opacity:1; transform:none; }
.js.no-reveal [data-rv]{ opacity:1; transform:none; }

/* ---- mask reveal -------------------------------------------- */
.js [data-mask]{ overflow:hidden; display:block; }
.js [data-mask] > span{
  display:block;
  transform:translateY(105%);
  transition:transform calc(var(--reveal-speed) * 1.2) var(--ease);
  transition-delay:var(--d,0s);
}
.js [data-mask].in > span{ transform:none; }
.js.no-mask [data-mask]{ overflow:visible; }
.js.no-mask [data-mask] > span{ transform:none; }

/* will-change is applied by motion.js only while these are actually
   moving. Leaving it on permanently promotes the whole document to
   its own compositor layer for the life of the page, which costs
   memory and can cause paint artifacts. */
[data-para]{ will-change:transform; }

/* ---- progress rail ------------------------------------------ */
.rail{ position:fixed; top:0; left:0; right:0; height:2px; z-index:95; pointer-events:none; }
.rail i{ display:block; height:100%; width:100%; background:var(--oxide);
  transform:scaleX(var(--p,0)); transform-origin:left; }
.rail[hidden]{ display:none; }

/* ---- cursor -------------------------------------------------- */
.cur{
  position:fixed; top:0; left:0; z-index:400;
  width:10px; height:10px; border-radius:50%;
  background:var(--ink); pointer-events:none;
  mix-blend-mode:difference;
  transform:translate3d(-100px,-100px,0);
  transition:width .3s var(--ease), height .3s var(--ease);
  will-change:transform;
}
.cur.big{ width:56px; height:56px; }
.cur[hidden]{ display:none; }
@media (hover:none){ .cur{ display:none !important; } }

/* ---- preloader ----------------------------------------------- */
.pre{
  position:fixed; inset:0; z-index:200;
  background:var(--paper); display:grid; place-items:center;
  transition:opacity .7s var(--ease), visibility .7s;
}
.pre[hidden]{ display:none; }
.pre.gone{ opacity:0; visibility:hidden; pointer-events:none; }
.pre__mark{ font-size:clamp(2.2rem,7vw,4rem); text-align:center; }
.pre__bar{ margin-top:1rem; height:2px; width:min(38vw,14rem);
  background:var(--line); position:relative; overflow:hidden; }
.pre__bar i{ position:absolute; inset:0 100% 0 0; background:var(--oxide);
  animation:load var(--pre-hold,1.1s) var(--ease) forwards; }
@keyframes load{ to{ right:0; } }

/* ---- nav ------------------------------------------------------ */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:90;
  display:flex; justify-content:space-between; align-items:center;
  padding:1rem var(--pad);
  border-bottom:var(--rule) solid transparent;
  transition:border-color .4s var(--ease);
}
/* The blur lives on a pseudo-element, not on .nav itself. backdrop-filter
   makes an element the containing block for its position:fixed children,
   which would size the mobile menu panel to the header bar instead of the
   viewport. Keeping it here leaves .nav a plain positioned box. */
.nav::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter:blur(10px);
}
.nav.stuck{ border-bottom-color:var(--line); }
.nav__links{ display:flex; gap:clamp(.9rem,2vw,2rem); }

/* ---- the mark -------------------------------------------------
   The official logo artwork, used as delivered. Sized by height so
   the lockup's own proportions are never distorted. */
.mark{ display:inline-flex; align-items:center; line-height:0; }
.mark__img{
  display:block; width:auto; height:100%;
  transition:opacity .35s var(--ease);
}
.mark:hover .mark__img{ opacity:.7; }

.nav .mark{ height:clamp(1.5rem,2.2vw,1.9rem); }
.foot .mark{ height:1.4rem; }
.pre .mark, .pre__mark{ height:auto; }
.pre__mark .mark__img{ height:auto; width:clamp(9rem,26vw,16rem); }
.nav__links a{ transition:color .3s var(--ease); }
.nav__links a:hover{ color:var(--oxide); }

/* Menu button: hidden on desktop, the only navigation on phones.
   Hiding the links below a breakpoint with nothing in their place
   is a hole, not a responsive strategy. */
.nav__toggle{ display:none; position:relative; z-index:2; }

@media (max-width:640px){
  .nav__toggle{ display:block; }
  .nav__links{
    position:fixed; inset:0; z-index:1;
    background:var(--paper);
    flex-direction:column; justify-content:center; align-items:flex-start;
    gap:.6rem; padding:var(--pad);
    font-size:clamp(1.9rem,9vw,2.6rem);
    letter-spacing:-.04em; text-transform:none; font-weight:500;
    color:var(--ink);
    transform:translateY(-100%);
    transition:transform .5s var(--ease);
    overflow-y:auto;
  }
  .nav[data-open="true"] .nav__links{ transform:none; }
  /* Keep the panel out of the tab order while it is closed. */
  .nav:not([data-open="true"]) .nav__links{ visibility:hidden; }
  .nav[data-open="true"] .nav__links{ visibility:visible; }
}

/* ---- buttons --------------------------------------------------- */
.btn{
  display:inline-flex; align-items:center; gap:.5rem;
  padding:.8rem 1.3rem; border:var(--rule) solid var(--ink);
  border-radius:100px; font-size:.82rem; font-weight:500;
  transition:background .35s var(--ease), color .35s var(--ease),
             border-color .35s var(--ease);
}
.btn::after{ content:"↗"; font-size:.9em; }
.btn:hover{ background:var(--ink); color:var(--paper); }
.btn--solid{ background:var(--ink); color:var(--paper); }
.btn--solid:hover{ background:var(--oxide); border-color:var(--oxide); }

/* ---- hero ------------------------------------------------------
   The headline sets the scale, then copy and buttons sit on one
   line beneath it so the fold carries content rather than air. */
.hero{ padding-top:clamp(5.5rem,13vh,7.5rem); padding-bottom:clamp(1.8rem,5vh,3rem); }
.hero__meta{
  display:flex; justify-content:space-between; gap:1rem;
  padding-bottom:.85rem; border-bottom:var(--rule) solid var(--line);
}
.hero__title{
  font-size:clamp(3.4rem,15.5vw,11.5rem);
  margin-block:clamp(.8rem,2.5vh,1.6rem) clamp(1.2rem,3vh,2rem);
}
.hero__foot{
  display:grid; grid-template-columns:1fr auto;
  gap:clamp(1.2rem,4vw,3rem); align-items:end;
  padding-top:clamp(1rem,2.5vh,1.6rem);
  border-top:var(--rule) solid var(--line);
}
.hero__body{
  display:grid; grid-template-columns:1fr 1fr; gap:clamp(1.2rem,3vw,2.5rem);
}
.hero__intro{ color:var(--muted); max-width:44ch; }
.hero__acts{ display:flex; flex-wrap:wrap; gap:.6rem; }
@media (max-width:900px){
  .hero__foot{ grid-template-columns:1fr; align-items:start; }
}
@media (max-width:640px){ .hero__body{ grid-template-columns:1fr; } }

/* ---- marquee band ---------------------------------------------- */
.band{
  border-block:var(--rule) solid var(--line);
  overflow:hidden; padding-block:.8rem; display:flex;
}
.band__move{ display:flex; will-change:transform; }
.band__track{ display:flex; flex-shrink:0; }
html:not(.js) .band__track{ animation:slide var(--marquee) linear infinite; }
@keyframes slide{ to{ transform:translateX(-100%); } }
.no-motion .band__move{ transform:none !important; }
.band__unit{
  display:flex; align-items:baseline; gap:1.2rem;
  padding-right:1.2rem; white-space:nowrap;
}
.band__unit b{
  font-weight:var(--disp-w); letter-spacing:-.04em;
  font-size:clamp(1.1rem,2.2vw,1.55rem);
}
.band__unit span{
  font-size:.72rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--muted);
}
.band__dot{ color:var(--oxide) !important; }

/* ---- generic section --------------------------------------------
   Sections run title-left / content-right so the heading and the
   text share a band instead of stacking with dead space beside
   each. Vertical rhythm is deliberately tight. */
.sec{ padding-block:clamp(2.4rem,6vh,4.2rem); }
.sec--tight{ padding-block:clamp(1.8rem,4.5vh,3rem); }
.sec__head{
  display:flex; justify-content:space-between; align-items:baseline;
  gap:1rem; padding-bottom:.85rem; border-bottom:var(--rule) solid var(--line);
}
.sec__grid{
  display:grid; grid-template-columns:minmax(12rem,28%) 1fr;
  gap:clamp(1.2rem,4vw,3.5rem);
  margin-top:clamp(1.2rem,3vh,2rem);
  align-items:start;
}
.sec__title{
  font-size:clamp(1.55rem,3.2vw,2.5rem);
  text-wrap:balance;
}
.sec__note{ color:var(--muted); max-width:46ch; }
.sec__grid--note{ align-items:baseline; }

@media (max-width:820px){
  .sec__grid{ grid-template-columns:1fr; gap:1rem; }
}

.prose{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
  gap:clamp(1rem,2.4vw,2rem);
}
.prose__p{ color:var(--muted); max-width:46ch; }

/* ---- services ---------------------------------------------------- */
.svc__list{ border-top:var(--rule) solid var(--line); margin-top:clamp(1.5rem,4vh,2.5rem); }
.svc{
  position:relative; display:grid;
  grid-template-columns:3.5rem 1fr auto;
  gap:1rem; align-items:start;
  padding-block:clamp(1.1rem,2.8vh,1.7rem);
  border-bottom:var(--rule) solid var(--line);
  overflow:hidden;
}
.svc__n{ padding-top:.45rem; }
.svc__main{ display:flex; flex-direction:column; gap:.3rem; }
.svc__title{ font-size:clamp(1.3rem,3.4vw,2.1rem); }
.svc__desc{ color:var(--muted); max-width:52ch; font-size:.95rem; }
.svc__arrow{ color:var(--muted); transition:transform .35s var(--ease), color .35s var(--ease); }
.svc:hover .svc__arrow{ transform:translate(3px,-3px); color:var(--oxide); }

/* roll: the repeated title slides across on hover */
.svc__roll{
  position:absolute; inset:0; z-index:1;
  display:flex; align-items:center; gap:1.2rem;
  padding-inline:var(--pad);
  background:var(--oxide); color:var(--paper);
  opacity:0; pointer-events:none;
  transition:opacity .3s var(--ease);
}
.svc__roll span{
  font-size:clamp(1.3rem,3.4vw,2.1rem); font-weight:var(--disp-w);
  letter-spacing:-.04em; white-space:nowrap;
  animation:slide calc(var(--marquee) / 5) linear infinite;
}
.roll-on .svc:hover .svc__roll{ opacity:1; }
@media (hover:none){ .svc__roll{ display:none; } }

/* ---- ribbons intro: token mapping -----------------------------------
   The ribbons package reads --bone, --gold, --font-display, --font-ui
   and --track-label. Rather than editing its stylesheet or inventing a
   second palette, those names are defined on the section itself and
   pointed at the Vāk tokens. --ink and --pad already match by name. */
.vak-name{
  --bone:         var(--paper);
  --gold:         var(--oxide);
  --font-display: var(--font-sans);
  --font-ui:      var(--font-sans);
  --track-label:  .14em;
}
/* ---- seamless ribbons across section boundaries ---------------------
   The package clips its stage to the section (overflow:hidden), so the
   ribbons stop dead at the edge. Three changes let them run through:

   1. Stop clipping.
   2. Extend the stage past the section, top and bottom. WebGL only
      draws inside the canvas, so the canvas itself has to reach into
      the neighbouring sections — a negative margin alone would not do
      it. The engine re-reads the stage on resize and re-lays out.
   3. Lift the neighbouring sections above the canvas. The stage is a
      positioned element, so a static section would paint *underneath*
      it and its text would disappear behind the ribbons. Giving each
      one z-index:1 puts the text over the cloth, which is the
      intention — they stay transparent so the ribbons show through. */
.vak-name{ overflow:visible; margin-bottom:0; }
.vak-name__stage{ inset:-10vh 0 -35vh 0; }

main > section,
main > .band{ position:relative; z-index:1; }

/* The copy column still sits above the canvas inside its own section. */
.vak-name__copy{ z-index:2; }

/* This section's heading is a full sentence rather than a short title, so
   it gets the wide track and the short note takes the narrow one — the
   reverse of the other sections, whose headings are two or three words. */
#voices .sec__grid{ grid-template-columns:1.7fr 1fr; }
#voices .sec__title{ font-size:clamp(1.3rem,2.4vw,1.9rem); line-height:1.12; }
@media (max-width:820px){
  #voices .sec__grid{ grid-template-columns:1fr; }
}

/* ---- meaning in many languages ----------------------------------------
   Rules live on the cells, not as a background behind a gap. A tinted
   container showing through would paint the unfilled slots of the last
   row as one large block. */
.voi__grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));
  border-top:var(--rule) solid var(--line);
  border-left:var(--rule) solid var(--line);
  margin-top:clamp(1.5rem,4vh,2.5rem);
}
.voi__cell{
  border-right:var(--rule) solid var(--line);
  border-bottom:var(--rule) solid var(--line);
  padding:clamp(.9rem,2vw,1.3rem);
  display:flex; flex-direction:column; gap:.35rem;
  min-height:5.5rem; justify-content:space-between;
  transition:background .35s var(--ease);
}
.voi__cell:hover{ background:var(--soft); }
.voi__word{
  font-size:clamp(1.5rem,3.2vw,2.1rem);
  line-height:1.15; letter-spacing:-.01em;
  /* Latin falls back to the brand face; other scripts pick their Noto */
  font-family:var(--font-sans), "Noto Sans Devanagari", "Noto Sans Tamil",
    "Noto Sans Bengali", "Noto Sans Kannada", "Noto Sans Arabic",
    "Noto Sans Hebrew", "Noto Sans JP", "Noto Sans KR", sans-serif;
}
.voi__cell:first-child .voi__word{ color:var(--oxide); }
.voi__meta{ font-size:.64rem; }

/* ---- scenarios ---------------------------------------------------- */
.scen{ border-top:var(--rule) solid var(--line); margin-top:clamp(1.8rem,5vh,3rem); }
.scen__row{
  display:grid; grid-template-columns:3.5rem 1fr; gap:1rem;
  padding-block:clamp(1rem,2.6vh,1.5rem);
  border-bottom:var(--rule) solid var(--line);
}
.scen__n{ padding-top:.3rem; color:var(--oxide); }
.scen__t{ max-width:56ch; font-size:clamp(1rem,1.6vw,1.2rem); }

/* ---- kinetic wordmark ---------------------------------------------- */
.kin{ padding-block:clamp(2.6rem,7vh,4.5rem); text-align:center; }
.kin__loud{
  font-size:clamp(4rem,22vw,16rem);
  display:flex; justify-content:center; flex-wrap:wrap;
}
.kin__loud i{
  font-style:normal; display:inline-block;
  opacity:0; transform:translateY(.35em);
  transition:opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay:var(--d,0s);
}
.kin__loud i.in{ opacity:1; transform:none; }
.no-kinetic .kin__loud i{ opacity:1; transform:none; }
.kin__loud i.sp{ width:.28em; }
.kin__script{
  font-family:var(--font-deva); font-weight:400;
  font-size:clamp(1.6rem,6vw,3.6rem);
  color:var(--oxide); margin-top:.4rem;
}

/* ---- contact ------------------------------------------------------------ */
.sec__grid--contact{ grid-template-columns:1.2fr .8fr; }
@media (max-width:820px){ .sec__grid--contact{ grid-template-columns:1fr; } }
.contact__heading{
  font-size:clamp(1.8rem,4.2vw,3rem);
  max-width:20ch;
}
.contact__body{ color:var(--muted); max-width:44ch; }
.contact__mailrow{ margin-top:1.2rem; }
.contact__side > * + *{ margin-top:1.2rem; }
.contact__mail{
  font-size:clamp(1.1rem,3vw,1.9rem); font-weight:var(--disp-w);
  letter-spacing:-.03em; color:var(--oxide);
  border-bottom:var(--rule) solid currentColor; padding-bottom:.1em;
}
.contact p + p{ margin-top:1.2rem; }

/* Sticky/stacking sections were removed deliberately. Pinning a
   section while the next one slides over it works for short visual
   blocks, not for paragraphs — two bodies of text share the screen
   and neither can be read. Sections now scroll normally. */

/* ---- footer ---------------------------------------------------------------- */
.foot{
  display:flex; justify-content:space-between; align-items:center;
  gap:1rem 1.5rem; flex-wrap:wrap;
  padding:1.2rem var(--pad);
  border-top:var(--rule) solid var(--line);
}
.foot__links{ margin-right:auto; }
.foot__links{ display:flex; gap:1.2rem; flex-wrap:wrap; }
.foot__links a:hover{ color:var(--oxide); }

/* ---- reduced motion --------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important; animation-iteration-count:1!important;
    transition-duration:.001ms!important;
  }
  .js [data-rv], .js [data-mask] > span{ opacity:1; transform:none; }
  .kin__loud i{ opacity:1; transform:none; }
}
