/* Toxuesure — toxuesure.in */

@font-face{font-family:Grotesk;src:url(fonts/grotesk-500.woff2) format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:Grotesk;src:url(fonts/grotesk-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:Archivo;src:url(fonts/archivo-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:Archivo;src:url(fonts/archivo-500.woff2) format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:Archivo;src:url(fonts/archivo-600.woff2) format('woff2');font-weight:600;font-display:swap}

:root{
  --ground:#F5F4F0;
  --ink:#111111;
  --soft:#6F6B63;
  --rule:#DDDAD3;
  --accent:#E2661F;
  --display:Grotesk,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  --text:Archivo,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  --pad:clamp(22px,6vw,120px);
  --ease:cubic-bezier(.22,.61,.36,1);
  /* content edge → viewport edge. 100vw includes the scrollbar, so this
     over-reports slightly; every consumer below floors well under it. */
  --gutter:calc((100vw - min(1180px,100vw))/2 + var(--pad));
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--text);font-size:17px;line-height:1.55;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
::selection{background:var(--ink);color:var(--ground)}
img{max-width:100%;height:auto;display:block}

.skip{position:absolute;left:-9999px}
.skip:focus{left:var(--pad);top:12px;background:var(--ink);color:var(--ground);padding:8px 12px;z-index:99}

.wrap{max-width:1180px;margin:0 auto;padding:0 var(--pad)}

/* ─── masthead ─────────────────────────────────────────── */
.mast{display:flex;justify-content:space-between;align-items:baseline;padding-top:clamp(24px,4vw,44px)}
.mark{font-family:var(--display);font-weight:700;font-size:17px;letter-spacing:-.03em;text-decoration:none;color:inherit}
.mast nav{display:flex;gap:clamp(16px,2.4vw,30px)}

/* link underline wipe */
a.u,.mast nav a,.meta a,.tag.link{
  position:relative;text-decoration:none;color:var(--soft);
}
.mast nav a{font-size:13.5px;letter-spacing:-.01em}
.mast nav a::after,.meta a::after{
  content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:left;
  transition:transform .42s var(--ease);
}
.mast nav a:hover,.meta a:hover{color:var(--ink)}
.mast nav a:hover::after,.meta a:hover::after{transform:scaleX(1)}

/* ─── hero ─────────────────────────────────────────────── */
.hero{
  padding:clamp(70px,14vh,180px) 0 clamp(58px,10vh,132px);
  /* 200px, not minmax(150px,200px): the graphic canvas below is
     position:absolute (it bleeds past this column on purpose), so it no
     longer contributes intrinsic width to the track — a minmax here would
     collapse to its floor and hand the freed width back to the h1's text
     column, reflowing the hand-broken lines. Pin it instead. */
  display:grid;grid-template-columns:minmax(0,1fr) 200px;
  gap:clamp(24px,4vw,44px);align-items:start;
}
h1{
  font-family:var(--display);font-weight:500;
  font-size:clamp(30px,5.4vw,64px);line-height:1.12;letter-spacing:-.035em;
  margin:0;max-width:20ch;
}
h1 span{display:block;overflow:hidden}
h1 span i{
  display:block;font-style:normal;
  transform:translateY(105%);
}
.ready h1 span i{transform:translateY(0)}

.hero-sub{margin:clamp(26px,4vw,40px) 0 0;max-width:56ch;font-size:clamp(16px,1.35vw,19px);color:var(--soft)}
.hero-meta{display:flex;flex-wrap:wrap;gap:8px 26px;margin-top:clamp(24px,3.5vw,36px);font-size:14px;color:var(--soft)}
.hero-meta span::before{content:"—  ";opacity:.5}

/* ─── structure ────────────────────────────────────────── */
section{padding:0 0 clamp(52px,8vw,104px)}
.rule{height:1px;background:var(--rule);transform:scaleX(0);transform-origin:left}
.rule.in{transform:scaleX(1)}

.label{
  font-family:var(--display);font-size:11.5px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--soft);
  margin:clamp(40px,6vw,72px) 0 clamp(26px,4vw,44px);
}
.label.sticky{position:sticky;top:20px;z-index:2;padding-block:6px}
/* The label only spans .wrap's content width, but the services/approach
   canvases now bleed into the margins beside it — without this, the
   bled portion would show through above the label as a mismatched band
   as it scrolls underneath. Extend the same ground colour past the
   label's own box, behind its text (z-index:-1, but still inside this
   element's own z-index:2 stacking context, so it stays above the art). */
.label.sticky::before{
  content:"";position:absolute;top:0;bottom:0;left:-50vw;right:-50vw;
  background:var(--ground);z-index:-1;
}

.cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.55fr);gap:clamp(24px,5vw,72px)}
h2{font-family:var(--display);font-weight:500;font-size:clamp(23px,2.9vw,36px);line-height:1.2;letter-spacing:-.03em;margin:0;max-width:17ch}
h3{font-family:var(--display);font-weight:700;font-size:15.5px;letter-spacing:-.01em;margin:0 0 7px}
p{margin:0 0 1.05em}
p:last-child{margin-bottom:0}
.lede{font-size:clamp(17px,1.5vw,20px);line-height:1.55}
.muted{color:var(--soft)}
.stack{display:grid;gap:clamp(26px,3.4vw,40px)}
.item p{color:var(--soft);max-width:60ch}
.lead{display:flex;flex-direction:column;gap:clamp(28px,4vw,44px)}

/* ─── case ─────────────────────────────────────────────── */
.case-head{display:flex;flex-wrap:wrap;gap:14px 22px;align-items:baseline;margin-bottom:clamp(26px,4vw,42px)}
.case-head h2{max-width:none}
.tags{display:flex;flex-wrap:wrap;gap:8px}
.tag{
  font-family:var(--display);font-size:11px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--soft);border:1px solid var(--rule);
  padding:5px 9px;border-radius:2px;white-space:nowrap;
}
.tag.link{transition:border-color .3s var(--ease),color .3s var(--ease)}
.tag.link:hover{color:var(--ink);border-color:var(--ink)}

.shot img{border:1px solid var(--rule);border-radius:2px}

.figs{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:clamp(28px,4vw,48px);margin-top:clamp(40px,6vw,64px)}
.fig .n{display:block;overflow:hidden}
.fig .n em{
  font-family:var(--display);font-weight:700;font-style:normal;
  font-size:clamp(34px,4.4vw,56px);letter-spacing:-.045em;line-height:1.06;
  display:block;transform:translateY(105%);
}
.fig.in .n em{transform:translateY(0)}
.fig .k{display:block;margin-top:11px;font-size:14px;color:var(--soft);max-width:24ch;line-height:1.4}

/* 300px, not minmax(200px,320px) — same reasoning as .hero above: the
   work-graphic canvas is now position:absolute and bleeds past this
   column, so the track must be pinned rather than sized to content. */
.steps-wrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:clamp(24px,4vw,56px);align-items:start;margin-top:clamp(40px,6vw,60px)}
.steps{display:grid;gap:clamp(24px,3vw,34px)}
.step{display:grid;grid-template-columns:52px minmax(0,1fr);gap:clamp(14px,2vw,26px);align-items:start}
.step .idx{font-family:var(--display);font-size:12.5px;font-weight:500;color:var(--soft);padding-top:4px}
.step p{color:var(--soft);max-width:62ch}

.note{margin-top:clamp(38px,5vw,56px);padding:clamp(20px,3vw,28px);border:1px solid var(--rule);border-radius:2px;max-width:66ch}
.note p{font-size:15.5px;color:var(--soft)}
.note strong{color:var(--ink);font-weight:600}

/* ─── loop ─────────────────────────────────────────────── */
#loop .lede{color:var(--soft);align-self:end}
.loop-diagram{margin:clamp(40px,6vw,64px) auto 0;max-width:640px}
.loop-diagram svg{display:block;width:100%;height:auto;overflow:visible}
.loop-path{fill:none;stroke:var(--accent);stroke-width:2.5;stroke-linejoin:round}
.loop-node circle{fill:var(--ground);stroke:var(--ink);stroke-width:1.25}
.loop-node text{
  font-family:var(--display);font-weight:700;font-size:26px;
  fill:var(--ink);text-anchor:middle;dominant-baseline:central;
}

/* flex + wrap, not grid: with five stages the last one wraps onto
   its own row, and justify-content centers it there instead of
   stranding it flush left under stage one. */
.stages{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(24px,3vw,34px);margin-top:clamp(40px,6vw,60px)}
.stage{flex:1 1 190px;max-width:260px;display:flex;gap:12px;align-items:baseline}
.stage .idx{font-family:var(--display);font-size:12.5px;font-weight:500;color:var(--accent)}
.stage p{color:var(--soft);max-width:38ch}

/* ─── generative graphics ─────────────────────────────────
   Round 2 removed the visible box (border/background) but the art was
   still confined to it — a soft-edged small box is still a small box.
   Round 3: each canvas now bleeds past its own container via absolute
   inset custom properties (--bt/--br/--bb/--bl), into the section's own
   whitespace and the page's outer margin, while the container itself
   stays exactly where it was in the grid so text layout is untouched.
   The mask is now a thin uniform dissolve rind (66-84% opaque core) —
   composition-level freedom (drifting centres, over-scanned crops,
   figures that bleed past their own frame) lives in main.js now, not
   in an off-centre gradient doing the art's job for it. Hidden below
   820px; hero hidden below 1180px — both unchanged, see the media
   queries at the bottom of this file for why. */
.hero-graphic,.work-graphic,.services-graphic,
.approach-graphic,.contact-graphic{
  position:relative;z-index:0;pointer-events:none;
  --bt:0px;--br:0px;--bb:0px;--bl:0px;
}
.hero-graphic canvas,.work-graphic canvas,.services-graphic canvas,
.approach-graphic canvas,.contact-graphic canvas{
  display:block;position:absolute;
  /* <canvas> is a REPLACED element: with width/height:auto an absolutely
     positioned one resolves to its 300x150 intrinsic size and ignores the
     insets entirely, so every sketch was drawing into a fixed 300x150 box
     adrift in a much larger container. Size it explicitly instead. */
  top:calc(-1 * var(--bt));left:calc(-1 * var(--bl));
  width:calc(100% + var(--bl) + var(--br));
  height:calc(100% + var(--bt) + var(--bb));
  opacity:0;transition:opacity .6s var(--ease);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-image:radial-gradient(ellipse closest-side at 50% 50%,#000 var(--core,70%),transparent 100%);
          mask-image:radial-gradient(ellipse closest-side at 50% 50%,#000 var(--core,70%),transparent 100%);
}
canvas[data-graphic].ready{opacity:1}

canvas[data-graphic="section"]     {--core:82%}
canvas[data-graphic="harmonograph"]{--core:70%}
canvas[data-graphic="isopleth"]    {--core:84%}
canvas[data-graphic="fork"]        {--core:84%}
canvas[data-graphic="development"] {--core:74%}

.hero-graphic{
  height:clamp(260px,30vw,440px);
  --bt:clamp(30px,5.5vw,78px);
  --br:clamp(40px,calc(var(--gutter) - 28px),240px);
  --bb:clamp(24px,4.5vw,64px);
  /* --bl stays 0: the h1 ink sits directly to the left with only a
     44px gap at its narrowest — never bleed toward it. */
}
.work-graphic{
  position:sticky;top:100px;
  height:min(clamp(320px,36vw,500px),62vh);
  --bt:clamp(20px,3vw,44px);
  --br:clamp(40px,calc(var(--gutter) - 28px),260px);
  --bb:clamp(24px,3.6vw,52px);
  --bl:clamp(0px,3vw,44px);
}
.services-graphic{
  height:clamp(220px,26vw,360px);
  --bt:clamp(16px,2.5vw,36px);
  --br:clamp(0px,3.5vw,50px);
  --bb:clamp(30px,10vw,144px);
  --bl:clamp(40px,calc(var(--gutter) - 28px),240px);
}
.approach-graphic{
  height:clamp(260px,30vw,420px);
  --bt:clamp(16px,2.5vw,36px);
  --bb:clamp(24px,6vw,86px);
  --bl:clamp(40px,calc(var(--gutter) - 40px),180px);
  /* --br stays 0: keeps the plate close to 1:1 rather than stretching it
     toward the text column. */
}
.contact-graphic{
  height:clamp(220px,25vw,340px);
  --bt:clamp(20px,3vw,44px);
  --br:clamp(40px,calc(var(--gutter) - 28px),240px);
  --bb:clamp(30px,6vw,86px);
  --bl:clamp(0px,3.5vw,50px);
}

/* The GSAP reveal (main.js) leaves an inline transform on every .r
   element, which makes each one its own stacking context at effective
   z-index 0 — so DOM order alone would decide whether a bled canvas
   paints over or under its text siblings. Pin the text content above
   the art explicitly rather than leaving that to source order. */
.mast,.hero-copy,.case-head,.figs,.steps,.stack,.note,.contact-copy{
  position:relative;z-index:1;
}

/* 240px, not minmax(160px,240px) — same reasoning: the contact-graphic
   canvas is position:absolute now and bleeds past this column. */
.contact-grid{display:grid;grid-template-columns:minmax(0,1fr) 240px;gap:clamp(24px,5vw,60px);align-items:center}

/* ─── contact ──────────────────────────────────────────── */
.contact .big{
  font-family:var(--display);font-weight:500;
  font-size:clamp(19px,3vw,38px);letter-spacing:-.03em;
  text-decoration:none;color:inherit;display:inline-block;
  border-bottom:1px solid var(--rule);padding-bottom:4px;word-break:break-word;
  transition:border-color .35s var(--ease);
}
.contact .big:hover{border-color:var(--ink)}
.meta{display:flex;flex-wrap:wrap;gap:10px 26px;margin-top:clamp(26px,4vw,38px);font-size:14.5px;color:var(--soft)}

footer{
  border-top:1px solid var(--rule);padding:30px 0 46px;
  display:flex;flex-wrap:wrap;gap:8px 20px;justify-content:space-between;
  font-size:13px;color:var(--soft);
}

/* ─── cursor ───────────────────────────────────────────── */
.dot-on,.dot-on a,.dot-on button{cursor:none}
#dot{
  position:fixed;top:0;left:0;z-index:9999;pointer-events:none;
  width:9px;height:9px;margin:-4.5px 0 0 -4.5px;border-radius:50%;
  background:var(--ink);
  transition:width .3s var(--ease),height .3s var(--ease),
             margin .3s var(--ease),background .3s var(--ease),
             border-width .3s var(--ease),opacity .25s linear;
  border:0 solid var(--ink);opacity:0;
  will-change:transform;
}
#dot.live{opacity:1}
/* over a link: becomes a ring */
#dot.on-link{
  width:36px;height:36px;margin:-18px 0 0 -18px;
  background:transparent;border-width:1px;
}
/* over a content block: small solid growth */
#dot.on-block{width:16px;height:16px;margin:-8px 0 0 -8px}

/* ─── hover focus ──────────────────────────────────────── */
.pop{transition:transform .34s var(--ease),opacity .34s var(--ease)}
@media (hover:hover) and (pointer:fine){
  .figs:hover .fig:not(:hover),
  .steps:hover .step:not(:hover),
  .stack:hover .item:not(:hover){opacity:.42}
  .fig:hover,.step:hover,.item:hover{transform:translateY(-3px)}
  .shot:hover img{transform:scale(1.012)}
  .shot img{transition:transform .5s var(--ease)}
  .note{transition:border-color .34s var(--ease)}
  .note:hover{border-color:var(--ink)}
}

/* ─── reveal ───────────────────────────────────────────── */
.r{opacity:0;transform:translateY(14px)}
.r.in{opacity:1;transform:none}

/* the hero's three lines are hand-broken in the markup, not just
   wrapped by max-width — they need more spare room than the other
   boxes before a graphic column is worth reserving, or "fix the"
   folds onto its own line and the crafted break is lost. */
@media (max-width:1180px){
  .hero{grid-template-columns:1fr}
  .hero-graphic{display:none}
}

@media (max-width:820px){
  .cols{grid-template-columns:1fr;gap:26px}
  h2{max-width:22ch}
  .label.sticky{position:static}
  .label.sticky::before{display:none}
  .shot{order:2}
  .steps-wrap{grid-template-columns:1fr}
  .contact-grid{grid-template-columns:1fr}
  .work-graphic,.services-graphic,.approach-graphic,.contact-graphic{display:none}
}
@media (max-width:520px){
  .mast nav a:first-child{display:none}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{transition:none!important;animation:none!important}
  .r{opacity:1;transform:none}
  h1 span i,.fig .n em{transform:none}
  .rule{transform:scaleX(1)}
  #dot{display:none}
  .dot-on,.dot-on a,.dot-on button{cursor:auto}
  .figs:hover .fig:not(:hover),
  .steps:hover .step:not(:hover),
  .stack:hover .item:not(:hover){opacity:1}
  .fig:hover,.step:hover,.item:hover{transform:none}
}
