/* =========================================================================
   salmantahir.net: design system
   -------------------------------------------------------------------------
   COLOUR      one accent, one hover accent, nothing else tinted
   SHAPE       corner-shape:squircle over border-radius, one radius scale
   INTERACTION every clickable thing: lift + accent bleeding from the cursor
   MOTION      scale-in reveals, reversible on scroll back
   ========================================================================= */
@font-face{
  font-family:'Onest';src:url('/assets/fonts/onest-var.woff2') format('woff2-variations');
  font-weight:400 900;font-style:normal;font-display:swap;
}

:root{
  /* ---- ground ---- */
  /* Two grounds, alternating, derived in CIELAB rather than picked by eye.
       paper  #FFFEF9  L* 99.6  chroma 2.6   cream, the hero and every other band
       alt    #FBF6F1  L* 97.1  chroma 3.1   a deeper paper tone, still warm
     paper -> alt  dE2000 2.46
     Both are warm on purpose. The accent is a warm maroon, so a neutral grey
     would leave it as the only warm thing on the page; keeping both grounds
     warm puts it at the saturated end of one family instead.

     Two tones, not three. Three warm grounds cannot all sit near white and all
     stay distinguishable: the usable range is about 5 L* wide, two boundaries
     need roughly 2.5 each, and the third tone still has to clear the white
     header card. There is no solution. The hero earns its distinction from
     full viewport height, centred composition, the largest type on the site
     and the accent wash below, none of which cost the system its clarity.

     --white is not a ground. It is reserved for elevated surfaces, the header
     bar, cards, buttons and form fields, which is what lets them read as
     lifted (dE2000 2.49 on paper, 3.43 on alt). */
  --white:#FFFFFF;
  --paper:#FFFEF9;
  --alt:#FBF6F1;
  --dark:#191416;

  /* ---- ink: one ramp, faintly warmed toward the accent ---- */
  --ink:#221A1C;        /* headings and primary text */
  --ink-2:#5A5052;      /* body copy */
  --ink-3:#6F6467;      /* meta, labels, captions  (AA on every ground) */
  --ink-dark:#F7F6F6;   /* primary text on dark, neutral rather than warm */
  --ink-dark-2:#AEA9A9; /* body copy on dark */

  --line:#E7E3E1;
  --line-2:#DAD4D2;

  /* ---- accent: exactly two values, used everywhere ---- */
  --accent:#8B3A47;
  --accent-hover:#6F2E39;
  --accent-live:#A8384A;   /* same family, shifted red, only for "now" states */
  --accent-wash:rgba(139,58,71,.09);
  --accent-line:rgba(139,58,71,.22);

  /* ---- shape ----
     CSS cannot express "always 45% of the short side" for arbitrary boxes:
     percentage radii resolve per axis and turn wide elements into ellipses.
     So the ratio is held by tier instead. Each value below is ~45% of that
     tier's own short side, which is the One UI / app icon proportion, and
     corner-shape turns the arc into a superellipse. Five values, whole site. */
  --r-xs:17px;   /* chips, icon buttons   ~38px short side  → 45% */
  --r-sm:21px;   /* buttons               ~46px             → 46% */
  --r-md:29px;   /* medium surfaces       ~64px             → 45% */
  --r-lg:42px;   /* cards, media          ~94px+            → 45% */
  --r-xl:35px;   /* header bar            ~78px             → 45% */

  --font:'Onest',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --maxw:1180px;
  --pad:clamp(20px,4vw,40px);
  --ease:cubic-bezier(.22,1,.36,1);
  --lift:translateY(-2px);
}

*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;scroll-behavior:smooth;scroll-padding-top:120px}
body{
  font-family:var(--font);background:var(--paper);color:var(--ink-2);
  font-size:17px;line-height:1.6;font-weight:400;overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3{color:var(--ink)}
::selection{background:var(--accent);color:#fff}
html.selpaint ::selection{background:transparent;color:var(--ink)}
html.selpaint ::-moz-selection{background:transparent;color:var(--ink)}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:6px}

.wrap,.hdr-in,.ftr-in{width:min(var(--maxw),100% - var(--pad) * 2);margin-inline:auto}

/* --------------------------------------------------------------------------
   SHAPE: real squircles, not rounded rectangles.
   corner-shape draws a superellipse; border-radius is the fallback curve for
   engines that do not support it, so nothing breaks without it.
   -------------------------------------------------------------------------- */
.sq-xs{border-radius:var(--r-xs);corner-shape:squircle}
.sq-sm{border-radius:var(--r-sm);corner-shape:squircle}
.sq-md{border-radius:var(--r-md);corner-shape:squircle}
.sq-lg{border-radius:var(--r-lg);corner-shape:squircle}
.sq-xl{border-radius:var(--r-xl);corner-shape:squircle}

/* --------------------------------------------------------------------------
   INTERACTION: one behaviour for everything clickable.
   A circle of accent grows from the pointer's position, so the colour arrives
   from where the cursor is rather than flooding the whole box at once.
   -------------------------------------------------------------------------- */
.act{position:relative;isolation:isolate;overflow:hidden;
  transition:transform .55s var(--ease),border-color .5s var(--ease),
             color .45s var(--ease),box-shadow .55s var(--ease)}
.act::before{
  content:'';position:absolute;z-index:-1;
  left:var(--mx,50%);top:var(--my,50%);
  width:0;aspect-ratio:1;border-radius:50%;
  background:var(--bleed,var(--accent-wash));
  transform:translate(-50%,-50%);opacity:0;
  transition:width 1.35s var(--ease),opacity .6s var(--ease);
}
.act:hover{transform:var(--lift)}
.act:hover::before{width:250%;opacity:1}
/* Bare marks: an icon or arrow with no surrounding surface has nothing for a
   fill to fill, so those only lift and recolour their own stroke. */
.act-bare::before{content:none}
.act-bare:hover{color:var(--accent)}

/* --------------------------------------------------------------------------
   TYPE
   -------------------------------------------------------------------------- */
.label{font-size:.74rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;line-height:1.4}
/* two levels of label, same type treatment, separated only by colour:
   accent marks a section, neutral names a card inside one */
/* Two levels, and only two.
   L1 .eyebrow  names a section of the page. Accent, sits above a section heading.
   L2 .eyebrow-2 names a card inside one. Neutral, never accent, so a card never
      competes with the section it lives in. .b-k is the same thing on the bento. */
.eyebrow{display:inline-block;margin-bottom:16px;color:var(--accent)}
.eyebrow-2{display:inline-flex;align-items:center;gap:8px;color:var(--ink-3);margin-bottom:20px}
/* L2 always carries an icon. The icon is what separates it from body text at
   this size, and it is the rule the bento already followed. */
.eyebrow-2 svg,.b-k svg{width:14px;height:14px;flex:none}
.h-display{font-size:clamp(2.1rem,5.2vw,4rem);font-weight:800;line-height:1.06;letter-spacing:-.04em}
.h-sec{font-size:clamp(1.8rem,4vw,2.9rem);font-weight:800;letter-spacing:-.038em;line-height:1.1;max-width:20ch}
.h-case{font-size:clamp(1.6rem,3.4vw,2.5rem);font-weight:800;letter-spacing:-.035em;line-height:1.14}

/* hand drawn stroke, sits under the words that carry the meaning */
.ul{position:relative;display:inline-block;white-space:nowrap}
.ul svg{position:absolute;left:0;bottom:-.14em;width:100%;height:.2em;color:var(--accent);overflow:visible}
.ul svg path{stroke:currentColor;stroke-width:5;fill:none;stroke-linecap:round;
  stroke-dasharray:320;stroke-dashoffset:320}
/* drawn only once the heading has finished landing */
.rv.in .ul svg path,.stg.in .ul svg path{animation:draw .95s var(--ease) .75s forwards}
@keyframes draw{to{stroke-dashoffset:0}}

/* --------------------------------------------------------------------------
   BUTTONS: one primary, one secondary, both squircle, both with the arrow
   -------------------------------------------------------------------------- */
.btn{display:inline-flex;align-items:center;gap:9px;font-size:.98rem;font-weight:600;
  padding:13px 24px;white-space:nowrap}
.btn-primary{background:var(--accent);color:#fff;--bleed:var(--accent-hover)}
.btn-secondary{background:var(--white);border:1px solid var(--line-2);color:var(--ink);
  --bleed:var(--accent-wash)}
.btn-secondary:hover{border-color:var(--accent-line);color:var(--accent)}
.btn-ondark{border:1px solid rgba(247,246,246,.26);color:var(--ink-dark);--bleed:rgba(139,58,71,.55)}
.arw{width:15px;height:15px;flex:none;transition:transform .4s var(--ease)}
.btn:hover .arw{transform:translate(2px,-2px)}

/* --------------------------------------------------------------------------
   HEADER
   -------------------------------------------------------------------------- */
.hdr{position:fixed;top:0;left:0;right:0;z-index:120;padding:16px 0;display:flex;justify-content:center}
.hdr-in{
  height:78px;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:20px;
  padding:0 14px 0 22px;background:var(--white);border:1px solid var(--line);
  box-shadow:0 2px 10px rgba(34,26,28,.04);transition:box-shadow .45s var(--ease);
}
.hdr.stuck .hdr-in{box-shadow:0 4px 18px rgba(34,26,28,.07)}
.mark{
  display:block;width:60px;height:50px;background-color:var(--accent);
  -webkit-mask:url(/assets/img/logo-mark.svg) no-repeat left center/contain;
  mask:url(/assets/img/logo-mark.svg) no-repeat left center/contain;
  transition:background-color .35s var(--ease),transform .4s var(--ease);
}
.mark:hover{background-color:var(--accent-hover);transform:var(--lift)}
/* Written on, on every load. The signature is filled outlines rather than open
   stroked paths, so stroke-dashoffset has no centreline to run along. Until a
   stroked source exists this is a reveal paced like a pen instead of a constant
   sweep: quick through the long strokes, slower through the loops and joins. */
.mark.write{animation:write 1.3s linear .12s backwards}
@keyframes write{
  0%   {clip-path:inset(0 100% 0 0)}
  14%  {clip-path:inset(0 68% 0 0)}
  26%  {clip-path:inset(0 61% 0 0)}
  42%  {clip-path:inset(0 44% 0 0)}
  56%  {clip-path:inset(0 38% 0 0)}
  72%  {clip-path:inset(0 19% 0 0)}
  84%  {clip-path:inset(0 12% 0 0)}
  100% {clip-path:inset(0 0 0 0)}
}
.hnav{display:flex;gap:4px;justify-content:center}
.hnav a{font-size:1.05rem;font-weight:500;color:var(--ink-2);padding:11px 16px}
.hnav a:hover{color:var(--accent)}
.hdr-end{display:flex;justify-content:flex-end}
.burger{width:46px;height:46px;border:1px solid var(--line-2);background:var(--white);
  cursor:pointer;position:relative;justify-self:end;display:none}
.burger i{position:absolute;left:14px;right:14px;height:1.7px;background:var(--ink);border-radius:2px;
  transition:transform .35s var(--ease)}
.burger i:nth-child(1){top:18px}
.burger i:nth-child(2){top:25px}
.burger.on i:nth-child(1){transform:translateY(3.5px) rotate(45deg)}
.burger.on i:nth-child(2){transform:translateY(-3.5px) rotate(-45deg)}

/* --------------------------------------------------------------------------
   HERO: sized so the whole banner sits inside one viewport
   -------------------------------------------------------------------------- */
.hero{
  position:relative;isolation:isolate;background:var(--paper);
  min-height:100svh;display:grid;align-content:center;text-align:center;
  padding:clamp(118px,15vh,150px) 0 clamp(74px,10vh,96px);
}
.hero::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(76% 56% at 50% 34%,rgba(139,58,71,.065),transparent 72%)}

.hero h1{max-width:17ch;margin:0 auto}
.lead{margin:clamp(22px,3vw,32px) auto 0;max-width:56ch;
  font-size:clamp(1rem,1.25vw,1.1rem);color:var(--ink-2)}
.hero-btns{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-top:clamp(28px,3.6vw,38px)}
.socials{display:flex;gap:14px;justify-content:center;margin-top:clamp(24px,3.2vw,34px)}
.socials a{width:42px;height:42px;display:grid;place-items:center;color:var(--ink-3);
  --bleed:var(--accent-wash)}
.socials a svg{width:20px;height:20px}

/* --------------------------------------------------------------------------
   TAGS: one taxonomy, one style, used by cards and by the filter
   -------------------------------------------------------------------------- */
/* Two pill sizes only. Content tags (featured cases and grid tiles) are the
   smaller of the two; the filter sits a step up because it is a control. */
.tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px}
.mini .tags{margin-top:16px}
/* Content tags are labels, not controls, so no pointer and no hover state.
   The filter chips below are the interactive half of the same taxonomy: same
   type size, more padding, because a control needs the bigger target. */
.tag{
  display:inline-flex;align-items:center;gap:7px;color:var(--ink-2);
  background:var(--white);border:1px solid var(--line);padding:7px 14px;
  font-size:.72rem;letter-spacing:.09em;
}
.tag svg{width:13px;height:13px;flex:none;color:var(--accent)}
/* As a button the tag becomes a control: same shape, now with a hover. The
   filterable work index is what these will link to. */
button.tag{font-family:inherit;cursor:pointer;--bleed:var(--accent-wash)}
button.tag:hover{color:var(--accent);border-color:var(--accent-line)}
/* a pill on a card selects that discipline in the filter above it */
button.tag[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#fff;
  --bleed:var(--accent-hover)}
button.tag[aria-pressed="true"] svg{color:#fff}
.band .tag{background:rgba(255,255,255,.75)}

/* filter chips, same component, selectable */
/* Full width row under the heading rather than crammed beside it: the chips get
   an even, predictable rhythm and the row scales to any number of disciplines,
   which is what the full case studies page will need. */
.filters{display:flex;flex-wrap:wrap;gap:9px;align-items:center;
  margin-top:clamp(24px,3vw,34px);padding-top:22px;border-top:1px solid var(--line-2)}
.filters-k{color:var(--ink-3);margin-right:4px}
.chip{
  display:inline-flex;align-items:center;gap:7px;color:var(--ink-2);
  background:var(--white);border:1px solid var(--line);padding:9px 16px;
  font-size:.72rem;letter-spacing:.09em;cursor:pointer;--bleed:var(--accent-wash);
}
.chip svg{width:13px;height:13px;flex:none;color:var(--accent);transition:color .3s}
.chip:hover{color:var(--accent);border-color:var(--accent-line)}
.chip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#fff;
  --bleed:var(--accent-hover)}
.chip[aria-pressed="true"] svg{color:#fff}

/* --------------------------------------------------------------------------
   CASE STUDIES
   -------------------------------------------------------------------------- */
.case{padding:clamp(72px,9vw,116px) 0}
/* the recessed half of the body alternation */
.band{background:var(--alt)}
/* Wide enough to hold the discipline pills on one line. They wrap to a second
   row below that, which reads as an overflow rather than a set. */
.case-head{max-width:74ch}
.case-p{color:var(--ink-2);font-size:clamp(1rem,1.2vw,1.08rem);margin-top:18px}
.shot{
  display:block;position:relative;overflow:hidden;margin-top:clamp(30px,4vw,46px);
  aspect-ratio:16/10;background:var(--alt);
  transition:transform .6s var(--ease),box-shadow .6s var(--ease);
}
.band .shot{background:var(--white)}
.shot img{width:100%;height:100%;object-fit:cover;object-position:top center;
  transition:transform 1.6s var(--ease)}
.shot--mark img{object-fit:contain;object-position:center;padding:11%}
.shot:hover{transform:translateY(-4px);box-shadow:0 26px 58px rgba(34,26,28,.12)}
.shot:hover img{transform:scale(1.02)}
.chip-follow{position:absolute;top:0;left:0;z-index:3;pointer-events:none;opacity:0;
  transition:opacity .3s var(--ease)}
.shot:hover .chip-follow,.mini-shot:hover .chip-follow{opacity:1}
.chip-follow span{
  /* Centred horizontally on the pointer and lifted so the arrow lands in the
     lower band of the button: it reads as pointing at the control, and it sits
     on the accent rather than on top of the words. */
  display:inline-flex;align-items:center;gap:8px;transform:translate(-50%,-78%);
  background:var(--accent);color:#fff;white-space:nowrap;border-radius:14px;corner-shape:squircle;
  font-size:.85rem;font-weight:600;padding:10px 16px;box-shadow:0 8px 24px rgba(34,26,28,.25);
}
.chip-follow svg{width:13px;height:13px}

/* --------------------------------------------------------------------------
   MORE WORK
   -------------------------------------------------------------------------- */
.more{padding:clamp(72px,9vw,116px) 0}
.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(24px,3vw,38px);
  margin-top:clamp(30px,3.6vw,44px)}
.mini{display:block}
.mini[hidden]{display:none}
.mini-shot{display:block;position:relative;overflow:hidden;aspect-ratio:16/10;background:var(--white);
  transition:transform .6s var(--ease),box-shadow .6s var(--ease)}
.mini-shot img{width:100%;height:100%;object-fit:cover;object-position:top center;
  transition:transform 1.6s var(--ease)}
.mini-shot--mark img{object-fit:contain;object-position:center;padding:9%}
.mini:hover .mini-shot{transform:translateY(-4px);box-shadow:0 20px 44px rgba(34,26,28,.11)}
.mini:hover .mini-shot img{transform:scale(1.02)}
.mini-t{font-size:1.22rem;font-weight:700;letter-spacing:-.025em;margin-top:20px;color:var(--ink);
  transition:color .3s}
.mini:hover .mini-t{color:var(--accent)}
.mini-p{color:var(--ink-2);font-size:.95rem;margin-top:8px;max-width:46ch}
.more-foot{display:flex;justify-content:center;margin-top:clamp(36px,4.4vw,54px)}
.empty{grid-column:1/-1;padding:44px 0;text-align:center;color:var(--ink-3)}

/* --------------------------------------------------------------------------
   ABOUT
   -------------------------------------------------------------------------- */
.about{padding:clamp(72px,9vw,116px) 0}
.bento{display:grid;grid-template-columns:repeat(6,1fr);gap:16px;margin-top:clamp(32px,4vw,46px)}
/* The card surface. .b is the bento on the home page; .surf is the same thing
   anywhere else, so a card looks identical whichever page it is on. */
.b,.surf{background:rgba(34,26,28,.022);border:1px solid rgba(34,26,28,.07);
  --bleed:var(--accent-wash)}
.b{padding:28px}
.b:hover,.surf:hover{border-color:var(--accent-line)}
.b-bio{grid-column:span 4;display:flex;flex-direction:column;align-items:flex-start}
.b-photo{grid-column:span 2;padding:0;min-height:290px}
.b-photo img{width:100%;height:100%;object-fit:cover}
.b-edu{grid-column:span 2;display:flex;flex-direction:column;align-items:flex-start}
.b-photo{--bleed:transparent}
.b-photo:hover{box-shadow:0 20px 46px rgba(34,26,28,.14)}
.b-work{grid-column:span 2;display:flex;flex-direction:column;align-items:flex-start}
.b-kit{grid-column:span 2}
/* every card is top aligned; the tools list is trimmed so the three sit level
   rather than being padded out to match */
.b-k{display:inline-flex;align-items:center;gap:8px;color:var(--ink-3);margin-bottom:20px}
.b-k svg{width:14px;height:14px}
.b-bio p{color:var(--ink-2);font-size:1rem}
.b-bio p+p{margin-top:14px}
.cert{margin-top:22px;display:inline-flex;align-items:center;gap:11px;background:var(--white);
  border:1px solid var(--line);padding:10px 18px;font-size:.9rem;color:var(--ink-2);font-weight:500}
.cert img{width:18px;height:18px;border-radius:4px}

.entry{display:flex;gap:13px;align-items:flex-start}
.entry+.entry{margin-top:18px;padding-top:18px;border-top:1px solid rgba(34,26,28,.08)}
.entry-logo{width:36px;height:36px;flex:none;display:grid;place-items:center;overflow:hidden;
  background:var(--white);border:1px solid var(--line)}
.entry-logo img{width:100%;height:100%;object-fit:contain;padding:4px}
.entry-logo img.bleed{padding:0;object-fit:cover}
.entry-t{font-size:.98rem;font-weight:600;letter-spacing:-.015em;line-height:1.3;color:var(--ink);
  display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.entry-s{font-size:.87rem;color:var(--ink-2);margin-top:3px}
/* One badge treatment for both: an accent tint with accent text, so a status
   and a credential read as the same kind of note. The live one carries a
   slightly deeper, redder tint to separate "now" from "already earned". */
.badge,.award{
  display:inline-flex;align-items:center;gap:5px;
  font-size:.58rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  padding:3px 9px;border-radius:9px;corner-shape:squircle;
}
.badge{background:rgba(168,56,74,.19);border:1px solid rgba(168,56,74,.34);color:var(--accent-live)}
.award{margin-top:6px;background:rgba(139,58,71,.13);border:1px solid rgba(139,58,71,.28);
  color:var(--accent)}
.award svg{width:10px;height:10px;flex:none}

.kit{display:grid;grid-template-columns:1fr 1fr;gap:14px 16px}
.kit li{display:flex;align-items:center;gap:10px;font-size:.92rem;color:var(--ink-2);list-style:none}
.kit span{width:29px;height:29px;flex:none;display:grid;place-items:center;background:var(--white);
  border:1px solid var(--line);border-radius:10px;corner-shape:squircle}
.kit img{width:16px;height:16px;object-fit:contain}
/* Adobe pulled their marks from the open icon sets, so the current CC icons are
   reproduced here as they actually are: a brand coloured tile with the letters */
.kit .adobe{font-size:.6rem;font-weight:700;letter-spacing:.01em;border:0}
.adobe-ps{background:#001E36;color:#31A8FF}
.adobe-ai{background:#330000;color:#FF9A00}
.adobe-ae{background:#00005B;color:#9999FF}
.about-foot{display:flex;justify-content:center;margin-top:clamp(32px,4vw,46px)}

/* --------------------------------------------------------------------------
   CTA
   -------------------------------------------------------------------------- */
/* The dark card needs air above it wherever it lands, otherwise it reads as
   glued to the band it follows. */
.cta-sec{padding:clamp(72px,9vw,116px) 0 clamp(28px,3.6vw,42px)}
.cta{
  position:relative;isolation:isolate;overflow:hidden;
  background:var(--dark);color:var(--ink-dark-2);
  padding:clamp(58px,8vw,104px) clamp(24px,5vw,56px);text-align:center;
}
/* Wide enough that a two line heading stays two lines. The home page copy is
   short so it never needed the room; a case study CTA does. */
.cta h2{color:var(--ink-dark);max-width:30ch;margin:0 auto}
.cta-p{margin:18px auto 0;max-width:46ch;font-size:1.02rem}
.cta-actions{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-top:34px}

/* --------------------------------------------------------------------------
   FOOTER
   -------------------------------------------------------------------------- */
.ftr{padding:8px 0 36px}
.ftr-in{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:14px}
.ftr-c{color:var(--ink-3)}
.ftr-n{display:flex;gap:8px}
.ftr-n a{width:40px;height:40px;display:grid;place-items:center;color:var(--ink-3);
  --bleed:var(--accent-wash)}
.ftr-n a:hover{color:var(--accent)}
.ftr-n svg{width:19px;height:19px}

/* --------------------------------------------------------------------------
   MOTION: scale-in, and reversible so it replays on the way back up
   -------------------------------------------------------------------------- */
/* Scale in on approach, scale back out on the way past. Children stage off the
   parent so a heading lands first and its stroke draws once it has settled.
   These use the standalone translate/scale properties rather than transform,
   so the hover lift composes with them instead of being overridden by them. */
.rv{opacity:0;translate:0 28px;scale:.9;
  transition:opacity 1.1s var(--ease),translate 1.1s var(--ease),scale 1.1s var(--ease)}
.rv.in{opacity:1;translate:none;scale:none}
/* Sideways variant: the case study rail arrives from the edge it lives on
   rather than rising like the column of text beside it. Only above 900, where
   the rail is actually to one side; below that it is a full width block and
   the offset would push the document wider than the viewport. */
@media (min-width:901px){ .rv-x{translate:38px 0} }
.rv.d1{transition-delay:.12s}.rv.d2{transition-delay:.24s}
.rv.d3{transition-delay:.36s}.rv.d4{transition-delay:.48s}

.stg > *{opacity:0;translate:0 24px;scale:.92;
  transition:opacity .95s var(--ease),translate .95s var(--ease),scale .95s var(--ease)}
.stg.in > *{opacity:1;translate:none;scale:none}
.stg.in > :nth-child(1){transition-delay:0s}
.stg.in > :nth-child(2){transition-delay:.13s}
.stg.in > :nth-child(3){transition-delay:.26s}
.stg.in > :nth-child(4){transition-delay:.39s}
.stg.in > :nth-child(5){transition-delay:.52s}

/* pointer extras */
html.has-cursor,html.has-cursor *{cursor:none}
.cursor{position:fixed;top:0;left:0;z-index:300;pointer-events:none;width:22px;height:22px;
  color:var(--accent);opacity:0;transition:opacity .25s var(--ease),color .25s var(--ease);
  will-change:transform}
.cursor.on{opacity:1}
.cursor.invert{color:#fff}
/* Over project media the chip is a label, not the pointer. The arrow stays on
   so there is still something to aim with, and goes white because the chip
   underneath it is accent filled. */
.cursor.over-media{opacity:1;color:#fff}
.cursor svg{width:100%;height:100%;filter:drop-shadow(0 1px 2px rgba(0,0,0,.28));
  transform-origin:3.7px 2px;transition:transform .16s var(--ease)}
.cursor.press svg{transform:scale(.76)}
.ripple{position:fixed;z-index:299;pointer-events:none;width:34px;height:34px;border-radius:50%;
  background:rgba(139,58,71,.22);border:1.5px solid rgba(139,58,71,.55);
  animation:ripple .62s var(--ease) forwards}
@keyframes ripple{
  from{transform:translate(-50%,-50%) scale(.3);opacity:1}
  to{transform:translate(-50%,-50%) scale(1.7);opacity:0}}
.marquee{position:fixed;z-index:298;pointer-events:none;background:rgba(139,58,71,.09);
  border:1px solid var(--accent);border-radius:4px}
.sel-layer{position:absolute;top:0;left:0;z-index:5;pointer-events:none}
/* Selection is painted rather than native so it can carry a squircle. The wash
   has to flip on dark ground: maroon on near-black is invisible, so rects over
   a dark section get a light wash instead. */
.sel-rect{position:absolute;background:rgba(139,58,71,.30)}
.sel-rect.on-dark{background:rgba(255,247,248,.34)}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .rv,.stg > *{opacity:1;translate:none;scale:none;transition:none}
  .ul svg path{animation:none;stroke-dashoffset:0}
  .ripple{display:none}
  *{transition-duration:.01ms!important}
}

/* --------------------------------------------------------------------------
   RESPONSIVE
   -------------------------------------------------------------------------- */
@media (max-width:940px){
  .hdr-in{grid-template-columns:1fr auto;height:64px}
  .hdr-end{display:none}
  .burger{display:block}
  .mark{width:50px;height:42px}
  .hnav{position:fixed;top:88px;left:var(--pad);right:var(--pad);flex-direction:column;gap:2px;
    padding:10px;display:none;background:var(--white);border:1px solid var(--line);
    border-radius:var(--r-lg);corner-shape:squircle;box-shadow:0 16px 40px rgba(34,26,28,.12)}
  .hnav.open{display:flex}
  .hnav a{padding:14px;font-size:1.02rem}
  .filters{justify-content:flex-start}
  .bento{grid-template-columns:repeat(4,1fr)}
  .b-bio{grid-column:span 4}
  .b-photo{grid-column:span 4;min-height:250px}
  .b-edu,.b-work{grid-column:span 2}
  .b-kit{grid-column:span 4}
}
@media (max-width:640px){
  body{font-size:16px}
  .bento{display:flex;flex-direction:column;gap:12px}
  /* Stacked, the portrait leads. Reading three paragraphs before meeting the
     person they are about is the wrong way round on a phone. */
  .b-photo{order:-1;min-height:0;aspect-ratio:4/3}
  .b{padding:22px}
  .grid2{grid-template-columns:1fr;gap:30px}
  .shot,.mini-shot{aspect-ratio:4/3}
  .hero-btns .btn{padding:13px 18px}
  /* Two columns, tighter. One column turned the toolkit into a very long
     scroll for what is really a glanceable list. */
  .kit{grid-template-columns:1fr 1fr;gap:11px 12px}
  .kit li{font-size:.85rem;gap:8px}
  .kit span{width:26px;height:26px}
  .kit img{width:14px;height:14px}
}

/* the page you are on, marked in the nav */
.hnav a.on{color:var(--accent)}

/* --------------------------------------------------------------------------
   INNER PAGES: work, about, contact share one top block
   -------------------------------------------------------------------------- */
.page-top{padding:calc(var(--pad) + 104px) 0 clamp(40px,5vw,64px);background:var(--paper)}
.page-lead{margin-top:20px;max-width:62ch;color:var(--ink-2);font-size:clamp(1rem,1.25vw,1.1rem)}
.page-top .filters{margin-top:clamp(28px,3.4vw,38px)}
.work-sec{padding:clamp(54px,6vw,76px) 0 clamp(60px,7vw,90px);background:var(--alt)}

/* the tile media is a link only when there is somewhere to go */
.mini-media{display:block}
.mini-y{display:block;margin-top:16px;color:var(--ink-3)}
.mini-y + .mini-t{margin-top:6px}
.mini-t a{transition:color .35s var(--ease)}
.mini:hover .mini-t a{color:var(--accent)}

/* held back rather than removed, so the filter still counts them */
.mini.batched-out{display:none}
.more-wrap{display:flex;justify-content:center;margin-top:clamp(34px,4.4vw,48px)}
.empty{text-align:center;color:var(--ink-3);padding:44px 0}

/* --------------------------------------------------------------------------
   CONTACT
   -------------------------------------------------------------------------- */
.contact-sec,.about-sec{background:var(--alt)}
.contact-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;
  gap:clamp(32px,5vw,64px);align-items:start;padding:clamp(48px,6vw,72px) 0 clamp(60px,7vw,90px)}
.field{display:block;margin-top:20px}
.field:first-of-type{margin-top:0}
.field-k{display:block;margin-bottom:9px;color:var(--ink-3)}
.field input,.field textarea{
  width:100%;font:inherit;font-size:1rem;color:var(--ink);background:var(--white);
  border:1px solid var(--line-2);padding:14px 18px;
  border-radius:var(--r-sm);corner-shape:squircle;
  transition:border-color .35s var(--ease),box-shadow .35s var(--ease)}
.field textarea{min-height:170px;resize:vertical;line-height:1.55}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-wash)}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-3);opacity:.7}
/* honeypot: a real person never fills this, a bot fills everything */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-foot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:26px}
.form-note{color:var(--ink-3);font-size:.88rem}
.form-msg{margin-top:18px;padding:14px 18px;font-size:.94rem;
  border-radius:var(--r-sm);corner-shape:squircle;display:none}
.form-msg.on{display:block}
.form-msg.ok{background:var(--accent-wash);border:1px solid var(--accent-line);color:var(--accent)}
.form-msg.bad{background:rgba(34,26,28,.04);border:1px solid var(--line-2);color:var(--ink-2)}
button[disabled]{opacity:.6;cursor:progress}

.contact-side{display:grid;gap:12px}
.side-card{padding:22px 24px}
.side-card .eyebrow-2{margin-bottom:12px}
.side-card p{color:var(--ink-2);font-size:.95rem}
.side-card a{color:var(--accent);text-decoration:underline;text-underline-offset:3px;
  word-break:break-word}

/* --------------------------------------------------------------------------
   ABOUT
   -------------------------------------------------------------------------- */
.about-body{padding:clamp(48px,6vw,72px) 0 clamp(60px,7vw,90px);
  display:grid;grid-template-columns:minmax(0,1fr) 292px;
  gap:clamp(36px,5vw,68px);align-items:start}
.about-main{max-width:70ch}
.about-main h2{font-size:clamp(1.6rem,3.4vw,2.5rem);font-weight:800;letter-spacing:-.035em;
  line-height:1.14;margin-top:clamp(46px,5.5vw,72px)}
.about-main h2:first-child{margin-top:0}
.about-main p{margin-top:16px;color:var(--ink-2)}
.about-main h2 + p{margin-top:12px}
.about-portrait{overflow:hidden;--bleed:transparent}
.about-portrait img{width:100%;height:auto}

@media (max-width:900px){
  .contact-grid,.about-body{grid-template-columns:1fr;gap:34px}
  .contact-side{order:-1;grid-template-columns:1fr 1fr}
}
@media (max-width:640px){
  .contact-side{grid-template-columns:1fr}
}

/* --------------------------------------------------------------------------
   CASE STUDY PAGE
   Text left, meta rail right. The rail is sticky because the reader refers
   back to role and scope while moving through the argument, and losing it
   off the top means scrolling up to answer "who did what" again.
   -------------------------------------------------------------------------- */
.cs-top{padding:calc(var(--pad) + 104px) 0 clamp(40px,5vw,64px);background:var(--paper)}
.back{display:inline-flex;align-items:center;gap:8px;color:var(--ink-3);
  font-size:.9rem;font-weight:600;padding:8px 14px;margin-bottom:26px;--bleed:var(--accent-wash)}
.back svg{width:15px;height:15px}

/* One measure for the whole opening block, the way .case-head holds the
   featured blocks on the home page. Without it the heading, the standfirst
   and the tags each found their own width and nothing lined up. */
.cs-head{max-width:960px}
.cs-h1{font-size:clamp(1.9rem,4.2vw,3.1rem);font-weight:800;letter-spacing:-.04em;line-height:1.08}
.cs-lead{margin-top:22px;max-width:60ch;color:var(--ink-2);font-size:clamp(1rem,1.25vw,1.12rem)}

/* feature image: same treatment as the home tile so a visitor arriving from
   there lands on something they recognise */
.cs-feature{display:block;margin-top:clamp(30px,4vw,46px);overflow:hidden;aspect-ratio:16/10}
.cs-feature img{width:100%;height:100%;object-fit:cover;object-position:center}

.cs-body-sec{background:var(--alt)}
.cs-body{padding:clamp(54px,7vw,86px) 0 clamp(64px,8vw,104px);
  display:grid;grid-template-columns:minmax(0,1fr) 292px;gap:clamp(36px,5vw,68px);align-items:start}
.cs-main{max-width:70ch}

/* the rail: same surface as the bento cards on the home page */
.rail{position:sticky;top:110px;display:grid;padding:8px;overflow:hidden}
.rail-row{padding:13px 15px}
.rail-row + .rail-row{border-top:1px solid rgba(34,26,28,.08)}
.rail-k{display:block;margin-bottom:5px}
.rail-v{color:var(--ink);font-weight:600;font-size:.95rem;line-height:1.4}
.rail-v a{color:var(--accent);text-decoration:underline;text-underline-offset:3px}

/* prose */
.cs-main h2{font-size:clamp(1.6rem,3.4vw,2.5rem);font-weight:800;letter-spacing:-.035em;
  line-height:1.14;margin-top:clamp(46px,5.5vw,72px)}
.cs-main h3{font-size:1.12rem;font-weight:700;color:var(--ink);margin-top:34px;letter-spacing:-.015em}
.cs-main p{margin-top:16px;color:var(--ink-2)}
.cs-main h2 + p,.cs-main h3 + p{margin-top:12px}
.cs-main strong{color:var(--ink);font-weight:650}

/* At a glance. Deliberately not another squircle card: the page already has
   the rail and the client cards in that shape, and a third would flatten the
   hierarchy. An accent rule carries the emphasis instead. */
.glance{border-left:3px solid var(--accent);padding:2px 0 2px 26px;
  margin-top:clamp(30px,4vw,42px)}
.glance p{margin-top:14px;font-size:1.06rem;color:var(--ink-2)}
.glance p:first-of-type{margin-top:0}
.glance .eyebrow-2{margin-bottom:14px}

/* in-page evidence */
figure{margin-top:clamp(30px,4vw,44px)}
.fig-img{display:block;overflow:hidden;border:1px solid var(--line);--bleed:transparent}
.fig-img img{width:100%;height:auto}
.fig-img:hover{box-shadow:0 22px 50px rgba(34,26,28,.13)}
figcaption{margin-top:14px;color:var(--ink-3);font-size:.88rem;line-height:1.5}
figcaption a{color:var(--accent);text-decoration:underline;text-underline-offset:3px}

/* social collateral: square, so a 3 up reads as a feed rather than a gallery */
.social{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:26px}
.social-item{display:block;overflow:hidden;aspect-ratio:1;border:1px solid var(--line);--bleed:transparent}
.social-item img{width:100%;height:100%;object-fit:cover}
.social-item:hover{box-shadow:0 18px 40px rgba(34,26,28,.13)}
.cs-main .cap{margin-top:14px;color:var(--ink-3);font-size:.88rem;line-height:1.5}

/* client roll */
.clients{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:12px;margin-top:26px}
.client{display:flex;gap:14px;align-items:flex-start;padding:18px 20px}
.client-logo{width:56px;height:56px;flex:none;overflow:hidden;background:#191919;
  display:grid;place-items:center}
.client-logo img{width:100%;height:100%;object-fit:contain}
.client b{display:block;color:var(--ink);font-size:.98rem;font-weight:700}
.client span span{display:block;margin-top:6px;color:var(--ink-3);font-size:.87rem;line-height:1.45}

/* The outcome, stated once in a sentence instead of split across four boxes.
   Four cards under four client cards read as a second grid, not a result. */
.tally{margin-top:clamp(34px,4.4vw,50px);padding:clamp(24px,3vw,32px) 0;
  border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2)}
.tally-lead{font-size:clamp(1.15rem,2vw,1.5rem);line-height:1.45;letter-spacing:-.02em;
  color:var(--ink);font-weight:500}
.tally-lead b{font-weight:800;color:var(--accent)}
.tally-sub{margin-top:12px;color:var(--ink-3);font-size:.92rem}


/* related work, three across, above the CTA */
/* its own band, the way .more is banded on the home page */
.related{padding:clamp(72px,9vw,116px) 0;background:var(--paper)}
.related .rel-shot{background:var(--alt)}
.rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;
  margin-top:clamp(26px,3.4vw,36px)}
.rel-shot{display:block;overflow:hidden;aspect-ratio:16/10;background:var(--alt);--bleed:transparent}
.rel-shot img{width:100%;height:100%;object-fit:cover;object-position:top center;
  transition:transform 1.6s var(--ease)}
.rel:hover .rel-shot img{transform:scale(1.02)}
.rel{display:block}
.rel-t{display:block;font-size:1.02rem;font-weight:700;letter-spacing:-.02em;
  color:var(--ink);margin-top:16px}
.rel .tags{margin-top:14px}
.rel-s{display:block;font-size:.88rem;color:var(--ink-3);margin-top:5px}

@media (max-width:900px){
  .cs-body{grid-template-columns:1fr;gap:34px}
  .rail{position:static;order:-1}
  .cs-feature{aspect-ratio:4/3}
  .rel-grid{grid-template-columns:1fr}
  .social{grid-template-columns:1fr 1fr}
}
