:root{
  --navy:#0D1B2E;
  --block:#152A46;
  --blue:#4A90CF;
  --text:#EAF2FA;
  --muted:#9FB3C8;
  --coral:#FF7A59;
  --empty:#1D3A5F;
  --page:1200px;
  --pad:clamp(20px,5vw,60px);
  --inset:min(13%,156px);
  --radius:clamp(18px,2.6vw,31px);
  --stroke:clamp(16px,3vw,36px);
}
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--navy);
  color:var(--text);
  font-family:"Familjen Grotesk",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:1.0625rem;
  line-height:1.55;
  overflow-x:clip;
}
img{display:block;max-width:100%}
a{color:inherit}
a:focus-visible{outline:3px solid var(--coral);outline-offset:4px;border-radius:6px}
main{overflow-x:clip}
.wrap{max-width:var(--page);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}

/* header */
.top{display:flex;align-items:center;justify-content:space-between;gap:16px;padding-top:28px;padding-bottom:28px}
.id{display:flex;align-items:center;gap:12px;text-decoration:none;font-weight:700;font-size:1.125rem}
.id img{width:30px;height:auto}
.nav{display:flex;gap:clamp(16px,3vw,30px)}
.nav a{text-decoration:none;font-size:.95rem}
/* Fun, the personal projects page, sits last and in coral, apart from the professional links. */
.nav a.nav-fun{color:var(--coral)}
.nav a.nav-fun:hover{text-decoration-color:var(--coral)}
.nav a:hover{text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:5px}

/* Work dropdown: opens on hover and on keyboard focus */
/* The header stays at the top of the window while the page scrolls, so the links are always in reach. It spans the
   full width with its own background, padded at the sides so its content stays on the page column. Where the browser supports it, the padding eases down as the page starts to move;
   elsewhere it is simply a little tighter. */
.top{position:sticky;top:0;z-index:30;max-width:none;padding-left:max(var(--pad),calc((100% - var(--page)) / 2 + var(--pad)));padding-right:max(var(--pad),calc((100% - var(--page)) / 2 + var(--pad)));background:rgba(13,27,46,.92);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
html{scroll-padding-top:84px}
@supports (animation-timeline: scroll()){
  .top{animation:top-tuck linear both;animation-timeline:scroll(root);animation-range:0 160px}
  @keyframes top-tuck{to{padding-top:12px;padding-bottom:12px}}
}
@supports not (animation-timeline: scroll()){.top{padding-top:16px;padding-bottom:16px}}
.has-menu{position:relative;display:flex;padding-bottom:12px;margin-bottom:-12px}
.menu{position:absolute;top:100%;left:-18px;min-width:13em;margin:0;padding:10px 0;list-style:none;background:var(--block);border-radius:14px;box-shadow:0 16px 36px rgba(4,10,20,.55);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .15s,transform .15s,visibility .15s}
.has-menu:hover .menu,.has-menu:focus-within .menu{opacity:1;visibility:visible;transform:none}
.menu a{display:block;padding:7px 18px;font-size:.92rem;white-space:nowrap}
.menu a[aria-current="page"]{color:var(--muted)}
@media (max-width: 899px){.nav{position:relative}.has-menu{position:static}.menu{left:auto;right:0}}

/* homepage hero */
.hero{padding-top:clamp(24px,4vw,40px);padding-bottom:clamp(36px,5vw,56px)}
.hero h1{font-size:clamp(2.1rem,5vw,3.2rem);font-weight:600;line-height:1.05;letter-spacing:-.02em;max-width:19em;text-wrap:balance}
.dot{color:var(--coral)}
.hero p{color:var(--muted);font-size:clamp(1rem,1.6vw,1.1rem);max-width:40em;margin-top:.9em}

/* work grid: inside .weave, 1em is 1% of the container, and the svg viewBox is 10 units per em */
.weave-wrap{container-type:inline-size;max-width:var(--page);margin:0 auto}
.weave{
  position:relative;
  font-size:1cqw;
  display:grid;
  grid-template-columns:34.5em 34.5em;
  column-gap:5em;
  row-gap:4em;
  padding:3em 13em;
}
/* With an odd number of blocks, the last one sits centered on the stroke instead of leaving a hole beside it. */
@media (min-width: 900px){.weave>div:last-child:nth-of-type(odd){grid-column:1 / -1;justify-self:center;width:34.5em}}
/* The blocks sit in the page in the order the stroke passes them. The stroke runs the second and fourth rows right to
   left, so on wide screens those rows are placed by hand. (The fourth-row rule applies only when there is a step 8.) */
@media (min-width: 900px){
  .weave>[role=listitem]:has([data-step="3"]){grid-column:2;grid-row:2}
  .weave>[role=listitem]:has([data-step="4"]){grid-column:1;grid-row:2}
  .weave:has([data-step="8"])>[role=listitem]:has([data-step="7"]){grid-column:2;grid-row:4}
  .weave:has([data-step="8"])>[role=listitem]:has([data-step="8"]){grid-column:1;grid-row:4}
}
svg.lead{display:none}
.thread{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.thread path{
  fill:none;
  stroke:var(--blue);
  stroke-width:30;
  stroke-dasharray:1;
  stroke-dashoffset:0;
  animation:draw 1.5s cubic-bezier(.25,.46,.45,.94) both;
}
@keyframes draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}

.block{
  position:relative;
  z-index:1;
  display:flex;
  flex-direction:column;
  height:32em;
  border-radius:2.6em;
  overflow:hidden;
  background:var(--block);
  color:var(--text);
  text-decoration:none;
}
.block:focus-visible{outline:3px solid var(--coral);outline-offset:4px;border-radius:2.6em}
.ph{position:relative;flex:none;height:20em;background:var(--empty);overflow:hidden;isolation:isolate}
.ph img{width:100%;height:100%;object-fit:cover;filter:grayscale(1) contrast(1.15);transition:filter .25s}
/* The conference photo is a dark room, so its tinted state is lifted to sit level with the other blocks. */
.block .ph img[src*="work/conference.jpg"]{filter:grayscale(1) brightness(1.9) contrast(1.1)}
.ph::before,.ph::after{content:"";position:absolute;inset:0;pointer-events:none;transition:opacity .25s}
.ph::before{z-index:1;background:#5FA3DE;mix-blend-mode:multiply}
.ph::after{z-index:2;background:var(--block);mix-blend-mode:lighten}
.ph:not(:has(img))::before,.ph:not(:has(img))::after{display:none}
.tx{flex:1;padding:1.7em 2.4em 0;transition:background-color .2s,color .2s}
.block h2{
  display:flex;
  align-items:center;
  gap:.4em;
  font-size:max(1.25rem,2.15em);
  font-weight:700;
  letter-spacing:-.015em;
  line-height:1.15;
  white-space:nowrap;
}
.block p{font-size:max(.875rem,1.3em);line-height:1.35;color:var(--muted);margin-top:.3em;transition:color .2s}
.go{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  flex:none;
  width:1.05em;
  height:1.05em;
  border-radius:50%;
  background:var(--coral);
  opacity:0;
  transition:opacity .2s;
}
.go svg{width:60%;height:60%;display:block;fill:none;stroke:var(--navy);stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round}
/* The last block is not a project. It closes the list with an invitation, in the stroke's own blue, so the stroke
   appears to run into it. It still lights up like the others when in focus, hovered, or reached by scrolling. */
.block.cta .tx{display:flex;flex-direction:column;justify-content:center;padding:2.4em 2.8em;background:var(--blue);color:var(--navy)}
.block.cta h2{display:block;font-size:max(1.7rem,3.7em);line-height:1.04;letter-spacing:-.025em;white-space:normal;text-wrap:balance}
.block.cta p{display:flex;align-items:center;gap:.45em;margin-top:.75em;font-size:max(1.05rem,1.9em);font-weight:700;color:var(--navy)}
.block.cta .go{opacity:1;width:1.25em;height:1.25em}
.block.cta p.also{display:block;margin-top:1em;font-size:max(.9rem,1.35em);font-weight:500;line-height:1.4;text-wrap:pretty}
.block:focus-visible .ph img,.block.lit .ph img{filter:none}
.block:focus-visible .ph::before,.block:focus-visible .ph::after,.block.lit .ph::before,.block.lit .ph::after{opacity:0}
.block:focus-visible .tx,.block.lit .tx{background:var(--text);color:var(--navy)}
.block:focus-visible p,.block.lit p{color:#34465C}
.block:focus-visible .go,.block.lit .go{opacity:1}
/* hover highlight, for devices with a pointer */
@media (hover: hover){
  .block:hover .ph img{filter:none}
  .block:hover .ph::before,.block:hover .ph::after{opacity:0}
  .block:hover .tx{background:var(--text);color:var(--navy)}
  .block:hover p{color:#34465C}
  .block:hover .go{opacity:1}
}

/* closing section and footer */
.closing{max-width:var(--page);margin:0 auto;padding:clamp(48px,7vw,84px) var(--inset) clamp(20px,3vw,28px)}
.closing h2{font-size:clamp(1.7rem,3.6vw,2.55rem);font-weight:600;line-height:1.08;letter-spacing:-.02em;max-width:17em;text-wrap:balance}
.closing p{color:var(--muted);font-size:clamp(1rem,1.6vw,1.1rem);margin-top:.7em}
.btns{display:flex;flex-wrap:wrap;gap:14px;margin-top:28px}
.btn{display:inline-block;font-weight:700;font-size:1.05rem;text-decoration:none;border-radius:99px;padding:.7em 1.6em;border:2px solid var(--text)}
.btn:hover{background:var(--text);color:var(--navy)}
.btn.primary{background:var(--coral);border-color:var(--coral);color:var(--navy)}
.btn.primary:hover{background:#FF9478;border-color:#FF9478}
.btn:focus-visible{border-radius:99px}
/* A button outlined in coral (not filled), for links to the Fun projects. */
.btn.coral{display:inline-flex;align-items:center;gap:.45em;border-color:var(--coral);transition:background .2s,color .2s}
.btn.coral svg{width:1.15em;height:1.15em;fill:none;stroke:var(--coral);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.btn.coral:hover{background:var(--coral);border-color:var(--coral);color:var(--navy)}
.btn.coral:hover svg{stroke:var(--navy)}
/* Its counterpart, outlined in blue, for the link from the Fun list back to the work portfolio. */
.btn.blue{display:inline-flex;align-items:center;gap:.45em;border-color:var(--blue);transition:background .2s,color .2s}
.btn.blue svg{width:1.15em;height:1.15em;fill:none;stroke:var(--blue);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.btn.blue:hover{background:var(--blue);border-color:var(--blue);color:var(--navy)}
.btn.blue:hover svg{stroke:var(--navy)}
.work-invite{margin-top:clamp(40px,6vw,72px);display:flex;flex-direction:column;align-items:flex-start;gap:18px}
.work-invite p{font-size:clamp(1.2rem,2.4vw,1.6rem);font-weight:600;line-height:1.2;letter-spacing:-.015em}
/* The invitation to the Fun projects, below the homepage’s work blocks. */
.fun-invite{max-width:var(--page);margin:0 auto;padding:clamp(40px,6vw,72px) var(--inset) 0;display:flex;flex-direction:column;align-items:flex-start;gap:18px}
.fun-invite p{font-size:clamp(1.2rem,2.4vw,1.6rem);font-weight:600;line-height:1.2;letter-spacing:-.015em}

/* homepage: the personal greeting popup (shown only for an address ending ?hi=<name>, see tools/hello.mjs) */
.hello{width:min(calc(100vw - 32px),460px);max-height:calc(100dvh - 32px);margin:auto;padding:clamp(26px,6vw,40px);border:0;border-radius:var(--radius);background:var(--block);color:var(--text);box-shadow:0 30px 80px rgba(2,6,14,.6);overflow:auto}
.hello::backdrop{background:rgba(6,13,24,.82);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}
.hello[open]{animation:hello-in .35s cubic-bezier(.25,.46,.45,.94) both}
@keyframes hello-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.hello h2{padding-right:44px;font-size:clamp(1.8rem,6vw,2.3rem);font-weight:600;line-height:1.1;letter-spacing:-.02em;text-wrap:balance}
.hello-logo{display:grid;place-items:center;margin-top:20px;padding:20px 24px;background:#fff;border-radius:16px}
.hello-logo[hidden]{display:none}
.hello-logo.dark{background:var(--navy)}
.hello-logo img{display:block;width:auto;height:auto;max-width:100%;max-height:76px}
.hello p{margin-top:18px;white-space:pre-line}
.hello address{display:grid;justify-items:start;gap:3px;margin-top:14px;font-style:normal}
.hello address b{font-size:1.1rem;font-weight:700}
.hello address a{text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:3px}
.hello address a:hover{text-decoration-color:var(--text)}
.hello .btn{margin-top:24px;font-family:inherit;cursor:pointer}
.hello-close{position:absolute;top:14px;right:14px;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:50%;background:var(--navy);color:var(--text);cursor:pointer}
.hello-close:hover{background:var(--blue);color:var(--navy)}
.hello-close:focus-visible{outline:3px solid var(--coral);outline-offset:3px}
.hello-close svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round}
html:has(.hello[open]){overflow:hidden}
/* While a greeting is up the stroke waits undrawn; removing the class starts its draw-in from the beginning. */
.greeting .thread path,.greeting .lead path{animation:none;stroke-dashoffset:1}
.greeting .weave > [role=listitem]::after{animation:none;transform:scaleY(0)}
.foot{max-width:var(--page);margin:0 auto;display:flex;justify-content:space-between;flex-wrap:wrap;gap:16px;padding:40px var(--inset) 36px;color:var(--muted);font-size:.9rem}

/* case pages */
.case{max-width:var(--page);margin:0 auto;padding:0 var(--inset)}
.case-top,.about-top{position:relative;margin-top:clamp(12px,2vw,24px)}
.bar{
  position:absolute;
  left:calc(50% - 50vw);
  right:calc(50% - 50vw);
  top:50%;
  height:var(--stroke);
  margin-top:calc(var(--stroke) / -2);
  background:var(--blue);
  transform-origin:left;
  animation:wipe 1.2s cubic-bezier(.3,.6,.2,1) both;
}
@keyframes wipe{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.case-top .ph{z-index:1;height:auto;aspect-ratio:16/9;border-radius:var(--radius)}
.case-top .ph::before,.case-top .ph::after{display:none}
.case-top .ph img{filter:none}
.case-top .ph video{display:block;width:100%;height:100%;object-fit:cover}
.kicker{color:var(--muted);font-weight:600;margin-top:clamp(28px,4vw,44px)}
.case h1{font-size:clamp(1.9rem,4.4vw,2.9rem);font-weight:600;line-height:1.08;letter-spacing:-.02em;max-width:18em;text-wrap:balance;margin-top:.2em}
.case-top + h1{margin-top:clamp(28px,4vw,44px)}
.facts{display:grid;grid-template-columns:auto 1fr;gap:6px 18px;margin-top:22px;font-size:.95rem;max-width:44em}
.facts dt{color:var(--muted)}
.problem{margin-top:34px;padding:clamp(22px,3.4vw,38px) clamp(22px,3.6vw,42px) clamp(26px,3.8vw,42px);background:var(--block);border-radius:var(--radius)}
.problem h2{font-size:clamp(1.1rem,2vw,1.3rem);font-weight:700;letter-spacing:-.005em;color:var(--coral)}
.problem p{font-size:clamp(1.35rem,2.8vw,1.85rem);font-weight:600;line-height:1.25;letter-spacing:-.012em;max-width:30em;margin-top:.35em}
.belief{max-width:30em;margin-top:30px;font-size:clamp(1.25rem,2.3vw,1.6rem);font-weight:600;line-height:1.28;letter-spacing:-.012em}
.belief span{display:block;font-size:.9rem;font-weight:600;color:var(--muted);letter-spacing:0;margin-bottom:.4em}
.prose{max-width:40em;margin-top:28px}
.prose p+p{margin-top:1em}
.prose a{text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:3px}
.prose a:hover{text-decoration-color:var(--text)}
.callouts{display:grid;grid-template-columns:repeat(auto-fit,minmax(15em,1fr));gap:14px;margin-top:34px;padding:0;list-style:none}
.section-title + .callouts{margin-top:18px}
.section-title + .prose{margin-top:14px}
.callouts li{background:var(--block);border-radius:18px;padding:1em 1.3em 1.1em}
.callouts b{display:block;color:var(--coral);font-size:clamp(1.15rem,2vw,1.4rem);font-weight:700;line-height:1.15;letter-spacing:-.01em}
.callouts span{display:block;color:var(--muted);font-size:.95rem;line-height:1.4;margin-top:.35em}
.extra{margin-top:34px}
.extra img{width:100%;border-radius:var(--radius)}
/* other work: a one-row version of the homepage grid, with the stroke behind it */
.embed{margin-top:16px;aspect-ratio:16/9;overflow:hidden;border-radius:var(--radius);background:#1b1e22}
.reel + .embed{margin-top:clamp(40px,5.5vw,60px)}
.embed iframe{display:block;width:100%;height:100%;border:0}
@media (max-width: 699px){.embed{aspect-ratio:4/5}}
.kit{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-top:16px;padding:0;list-style:none}
.embed + .kit{margin-top:14px}
.kit li{background:var(--block);border-radius:16px;padding:1em 1.1em 1.1em;border-top:5px solid var(--blue)}
.kit b{display:block;font-size:1rem;font-weight:700;line-height:1.2;letter-spacing:-.005em}
.kit span{display:block;color:var(--muted);font-size:.85rem;line-height:1.35;margin-top:.4em}
/* trail: a stroke through a two-row tile grid. The rows are equal height, so its three lines sit at known
   heights (row 1 center, the gap, row 2 center). --end is where the bottom line stops, measured from the right. */
.kit.trail{--ss:9px;--rg:60px;--cg:22px;--c:calc((100% - var(--rg)) / 4);--end:-28px;position:relative;isolation:isolate;grid-auto-rows:1fr;gap:var(--rg) var(--cg);margin:40px 0 44px}
.kit.trail li{position:relative;z-index:1;border-top:0}
.kit.trail::before,.kit.trail::after{content:"";position:absolute;z-index:0;border:var(--ss) solid var(--blue);pointer-events:none}
.kit.trail::before{left:-28px;right:-56px;top:calc(var(--c) - var(--ss) / 2);bottom:calc(50% - var(--ss) / 2);border-left:0;border-radius:0 999px 999px 0;clip-path:polygon(0 0,100% 0,100% 100%,96px 100%,96px 50%,0 50%)}
.kit.trail::after{left:-56px;right:var(--end);top:calc(50% - var(--ss) / 2);bottom:calc(var(--c) - var(--ss) / 2);border-right:0;border-radius:999px 0 0 999px;clip-path:polygon(0 0,calc(100% - 96px) 0,calc(100% - 96px) 50%,100% 50%,100% 100%,0 100%)}
.kit.trail li:first-child::before,.kit.trail li:last-child::after{content:"";position:absolute;top:50%;width:22px;height:22px;margin-top:-11px;border-radius:50%;background:var(--blue)}
.kit.trail li:first-child::before{left:-39px}
.kit.trail li:last-child::after{left:calc(100% + 17px)}
/* A single row of steps (.row): one straight stroke through the row, with a dot at each end. */
@media (min-width: 900px){
  .kit.trail.row::before{left:-28px;right:-28px;top:calc(50% - var(--ss) / 2);bottom:auto;height:var(--ss);border:0;border-radius:0;clip-path:none;background:var(--blue)}
  .kit.trail.row::after{display:none}
}
/* the seven process steps: four across, numbered, with the bottom line ending after the third tile */
/* Four tiles to a row (.four), for a list of eight. */
.kit.four{grid-template-columns:repeat(4,1fr)}
/* Three tiles to a row (.three), for a list of six. */
.kit.three{grid-template-columns:repeat(3,1fr)}
/* Two wide tiles to a row (.two), for tiles that carry a few sentences each. */
.kit.two{grid-template-columns:1fr 1fr;gap:16px}
.kit.two li{padding:1.2em 1.4em 1.2em}
.kit.two b{font-size:1.1rem}
.kit.two span{font-size:.95rem;line-height:1.5}
.kit.steps{--cg:28px;--end:calc(25% - 21px);grid-template-columns:repeat(4,1fr);counter-reset:step}
.kit.steps li{counter-increment:step}
.kit.steps b::before{content:counter(step) ". ";color:var(--blue)}
/* Tiles with an icon and no stroke (.icons), for lists that are not a sequence. Only a real sequence (.trail) is joined by the stroke. */
.kit.icons{gap:14px;margin-top:18px}
.kit.icons li{border-top:0}
/* Either kind carries its icon bottom right on wide screens, and at the right edge beside the text on phones. */
.kit.trail li,.kit.icons li{display:flex;flex-direction:column}
.kit .ico{flex:none;width:26px;height:26px;margin-top:auto;padding-top:.7em;box-sizing:content-box;align-self:flex-end;fill:var(--blue);opacity:.5}
.reel .kinds{margin-top:.7em;padding:0;list-style:none;display:grid;gap:.35em}
.reel .kinds li{position:relative;padding-left:1.1em;font-size:.92rem;line-height:1.35}
.reel .kinds li::before{content:"";position:absolute;left:0;top:.5em;width:.45em;height:.45em;border-radius:50%;background:var(--blue)}
@media (max-width: 899px){
  .kit{grid-template-columns:repeat(2,1fr)}
  .kit.trail{grid-template-columns:1fr;grid-auto-rows:auto;gap:26px;margin:58px 0 72px}
  .kit.trail::before{left:50%;right:auto;top:-30px;bottom:-30px;width:var(--ss);margin-left:calc(var(--ss) / -2);border:0;border-radius:0;clip-path:none;background:var(--blue)}
  .kit.trail::after{display:none}
  .kit.trail li:first-child::before{left:50%;top:-41px;margin:0 0 0 -11px}
  .kit.trail li:last-child::after{left:50%;top:auto;bottom:-41px;margin:0 0 0 -11px}
  .kit.icons{grid-template-columns:1fr;gap:12px}
  .kit.trail li,.kit.icons li{display:grid;grid-template-columns:1fr auto;column-gap:16px;align-items:center}
  .kit.trail li>b,.kit.trail li>span,.kit.icons li>b,.kit.icons li>span{grid-column:1}
  .kit.trail .ico,.kit.icons .ico{grid-column:2;grid-row:1 / span 2;width:30px;height:30px;margin:0;padding:0;align-self:center}
}
.guide-shot{margin-top:28px;border-radius:var(--radius);overflow:hidden}
.guide-shot img{display:block;width:100%;height:auto}
.reel{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:16px;padding:0;list-style:none}
.reel .yt,.clip .yt{position:relative;display:block;width:100%;aspect-ratio:16/9;border:0;border-radius:14px;overflow:hidden;background:var(--block)}
.reel a.yt img,.clip a.yt img{width:100%;height:100%;object-fit:cover;transition:transform .3s}
.reel a.yt:hover img,.clip a.yt:hover img{transform:scale(1.03)}
.reel .play,.clip .play,.shots .play{position:absolute;left:50%;top:50%;width:52px;height:52px;margin:-26px 0 0 -26px;border-radius:50%;background:var(--coral);display:grid;place-items:center}
.reel .play svg,.clip .play svg,.shots .play svg{width:24px;height:24px;fill:var(--navy)}
.reel a.yt:focus-visible,.clip a.yt:focus-visible{border-radius:14px}
.reel h3{font-size:1.1rem;font-weight:700;letter-spacing:-.01em;margin-top:12px}
.reel p{color:var(--muted);font-size:.92rem;line-height:1.45;margin-top:.3em}
@media (max-width: 899px){.reel{grid-template-columns:1fr;gap:24px}}
.more{margin-top:clamp(48px,7vw,80px)}
.more h2{font-size:1.5rem;font-weight:600;letter-spacing:-.01em;text-align:center}
.more-strip{position:relative;margin:4px calc(-1 * var(--inset)) 0}
.more .bar{animation:none;height:12px;margin-top:-6px;opacity:.75}
.more-row{display:grid;grid-template-columns:repeat(6,1fr);gap:14px;padding:14px 0}
.more .block{height:auto;border-radius:14px}
.more .block:focus-visible{border-radius:14px}
.more .ph{height:auto;aspect-ratio:16/9}
.more .tx{padding:9px 12px 11px}
.more .block h3{font-size:.9rem;font-weight:700;line-height:1.2;letter-spacing:-.01em}

/* rebrand case page: brand family */
/* The clean logo sits exactly where the logo sits in the construction diagram below it:
   same panel padding, and the diagram viewBox (226 x 90 with the logo at 24,20 sized 170 x 50) as percentages. */
.guide{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:16px}
.guide img{display:block;width:100%;height:auto;border-radius:12px}
@media (max-width: 699px){.guide{grid-template-columns:1fr}}
.logo-panel{margin-top:20px;padding:clamp(8px,1.6vw,18px);background:#F4F6F8;border-radius:var(--radius)}
.logo-panel img{display:block;width:75.2212%;height:auto;margin:8.8496% 0 8.8496% 10.6195%}
.construct{margin-top:16px;padding:clamp(8px,1.6vw,18px);background:var(--block);border-radius:var(--radius)}
.construct svg{display:block;width:100%;height:auto;font-family:inherit}
/* Two tiles above and two below the logo diagram (.around), in the launch-kit tile style, with no connecting stroke.
   The wrapper's equal outer rows keep the two pairs the same height. */
.around{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:1fr auto 1fr;gap:16px;margin:18px 0 0}
.around>.kit{grid-template-columns:1fr 1fr;gap:16px;margin:0}
.around>.kit li{border-top:0;display:flex;flex-direction:column}
.around>.kit span{font-size:.92rem;line-height:1.45}
.around>.construct{margin:0}
@media (max-width: 899px){
  .around{display:block}
  .around>.kit{grid-template-columns:1fr;gap:14px}
  .around>.kit li{display:grid;grid-template-columns:1fr auto;column-gap:16px;align-items:center}
  .around>.kit li>b,.around>.kit li>span{grid-column:1}
  .around>.kit .ico{grid-column:2;grid-row:1 / span 2;width:30px;height:30px;margin:0;padding:0;align-self:center}
  .around>.construct{margin:14px 0}
}
@media (max-width: 699px){.construct .lbl{display:none}}

/* conference case page: one logo per year on a white panel. Two across, or three across once there are five
   or more. A wide lockup (.wide) takes a whole row on phones so its lettering stays readable. */
.years{display:flex;flex-wrap:wrap;justify-content:center;margin-top:18px;padding:clamp(10px,2vw,22px);background:#fff;border-radius:var(--radius);list-style:none}
.years li{flex:0 0 50%;display:flex;flex-direction:column;align-items:center;gap:12px;padding:clamp(14px,2.6vw,28px)}
@media (min-width: 700px){.years li:first-child:nth-last-child(n+5),.years li:first-child:nth-last-child(n+5) ~ li{flex-basis:33.333%}}
.years img{display:block;width:100%;height:clamp(104px,17vw,176px);object-fit:contain}
.years li.banner{justify-content:center}
.years li.banner img{height:auto;border-radius:10px}
.years + .prose{margin-top:22px}
/* A small video floated to the right of the paragraph that mentions it; on phones it follows that paragraph. */
.prose .with-clip{display:flow-root}
.prose p + .with-clip{margin-top:1em}
.prose .with-clip + p{margin-top:1em}
.clip{float:right;width:min(46%,300px);margin:.35em 0 .6em 1.5em}
.clip>img{display:block;width:100%;height:auto;border-radius:14px}
/* A logo set straight on the page, a little smaller than a picture and with square corners. */
.clip.logo{width:min(40%,240px)}
.clip.logo>img{border-radius:0}
/* .wide: a landscape picture gets more room. .lead: on phones the picture comes before its text, not after. */
.clip.wide{width:min(52%,360px)}
.clip.wide>img{border-radius:0}
.clip a.yt{text-decoration:none}
.clip .play{width:44px;height:44px;margin:-22px 0 0 -22px}
.clip .play svg{width:20px;height:20px}
.clip figcaption,.shots figcaption,.pair figcaption,.frame figcaption,.map figcaption,.duo figcaption{color:var(--muted);font-size:.82rem;line-height:1.35;margin-top:.55em}
/* A small browser-style window that scrolls through a capture of a live web page (for sites that refuse to be framed). */
.peek{border-radius:12px;overflow:hidden;background:#fff}
.peek-bar{display:flex;align-items:center;gap:5px;height:26px;padding:0 10px;background:#E4E8EE;color:#5B6B7D;font-size:.68rem;line-height:1}
.peek-bar i{flex:none;width:7px;height:7px;border-radius:50%;background:#B4BDC9}
.peek-bar span{margin-left:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.peek-view{height:210px;overflow-y:auto;scrollbar-width:thin}
.peek-view img{display:block;width:100%;height:auto}
.peek-view:focus-visible{outline:3px solid var(--coral);outline-offset:-3px}
.clip figcaption a,.pair figcaption a{text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:3px}
/* Two scrollable windows side by side (.pair), and a single screenshot in a window frame (.frame). */
.pair{display:grid;grid-template-columns:1fr 1fr;gap:14px 16px;margin-top:24px}
.pair>div{min-width:0}
.pair h3{font-size:1rem;font-weight:700;letter-spacing:-.01em;margin-bottom:.55em}
.pair .peek-view{height:clamp(300px,36vw,440px)}
.pair figcaption{grid-column:1 / -1}
.frame{margin-top:24px}
.frame + .list-title,.pair + .list-title{margin-top:30px}
.frame .peek>img{display:block;width:100%;height:auto}
.pair + .prose,.frame + .prose{margin-top:22px}
/* Two pictures side by side at the same height (.duo), whatever their shapes: each takes width in proportion to its
   own aspect ratio (--a and --b, set per figure). They stack on phones. */
.duo{display:grid;grid-template-columns:minmax(0,var(--a,1fr)) minmax(0,var(--b,1fr));gap:14px;align-items:start;margin-top:24px}
.duo img{display:block;width:100%;height:auto;border-radius:14px}
.duo figcaption{grid-column:1 / -1;margin-top:0}
.duo + .prose{margin-top:22px}
/* creative operations: a task's lifespan. Eight statuses on a thin line. A second copy of the list (.flow-lit), in the
   highlight colors, lies exactly on top; a moving clip-path window reveals one row of it at a time, so the highlight
   slides from status to status with the text changing color as it passes. Built by scratch script task-flow.mjs. */
.clip.flow{width:min(46%,264px)}
.flow-box{padding:16px 14px 14px;background:var(--block);border-radius:18px}
.flow-box b{display:block;padding:0 10px 10px;font-size:.95rem;font-weight:700;letter-spacing:-.005em}
.flow-list{position:relative}
.flow ol{position:relative;display:grid;gap:3px;margin:0;padding:0;list-style:none}
.flow ol:first-child::before{content:"";position:absolute;left:15px;top:15px;bottom:15px;width:2px;background:rgba(74,144,207,.4)}
.flow li{position:relative;display:flex;align-items:center;gap:11px;height:30px;padding:0 10px;color:var(--muted);font-size:.88rem;font-weight:600;line-height:1;white-space:nowrap}
.flow li i{flex:none;width:12px;height:12px;border-radius:50%;background:var(--dot);box-shadow:0 0 0 3px var(--block)}
.flow .s-intake{--dot:#9FB3C8}
.flow .s-planned{--dot:#4F86E8}
.flow .s-progress{--dot:#3CC3D0}
.flow .s-creative{--dot:#F2CB4B}
.flow .s-revision{--dot:#E5484D}
.flow .s-department{--dot:#F08A3C}
.flow .s-ready{--dot:#A765DC}
.flow .s-complete{--dot:#3FB96B}
.flow-lit{position:absolute !important;inset:0;clip-path:inset(0px 0 231px round 9px);background-color:var(--text);color:var(--navy);animation:flow-slide 13.1s cubic-bezier(.65,0,.35,1) infinite}
.flow-lit li{color:inherit}
.flow-lit li i{box-shadow:none}
.flow-lit .s-intake i{background:#6F8499}
.flow-lit .s-revision i,.flow-lit .s-complete i{background:#fff}
.flow-lit .tick{flex:none;width:18px;height:18px;margin-left:auto;fill:none;stroke:var(--navy);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
@keyframes flow-slide{0%,6.49%{clip-path:inset(0px 0 231px round 9px);background-color:var(--text);color:var(--navy)}9.92%,16.41%{clip-path:inset(33px 0 198px round 9px);background-color:var(--text);color:var(--navy)}19.85%,26.34%{clip-path:inset(66px 0 165px round 9px);background-color:var(--text);color:var(--navy)}29.77%,36.26%{clip-path:inset(132px 0 99px round 9px);background-color:var(--text);color:var(--navy)}39.69%,46.18%{clip-path:inset(99px 0 132px round 9px);background-color:#E5484D;color:#fff}49.62%,56.11%{clip-path:inset(132px 0 99px round 9px);background-color:var(--text);color:var(--navy)}59.54%,66.03%{clip-path:inset(165px 0 66px round 9px);background-color:#95D6B3;color:var(--navy)}69.47%,75.95%{clip-path:inset(198px 0 33px round 9px);background-color:#3FB96B;color:var(--navy)}79.39%,94.66%{clip-path:inset(231px 0 0px round 9px);background-color:#3FB96B;color:var(--navy)}100%{clip-path:inset(0px 0 231px round 9px);background-color:var(--text);color:var(--navy)}}
@media (max-width: 699px){.clip.flow{order:0;width:100%;margin:16px 0 0}.flow + p{order:-1}}
@media (prefers-reduced-motion: reduce){.flow-lit{display:none}}
/* creative operations: the integration map. A wide drawing, and a tall one for phones, built by the same script. */
.map{margin-top:24px}
.map-box{padding:clamp(10px,2vw,22px);background:var(--block);border-radius:var(--radius)}
.map svg{display:block;width:100%;height:auto;font-family:inherit}
.map .tall{display:none}
.map .layer{fill:rgba(74,144,207,.1);stroke:var(--blue);stroke-width:2;stroke-dasharray:7 7}
.map .layer-t{font-size:15px;font-weight:700;fill:var(--text)}
.map .layer-s{font-size:12.5px;fill:var(--muted)}
.map .spark{fill:var(--coral)}
.map .link{fill:none;stroke:var(--blue);stroke-width:8;stroke-linecap:round}
.map .hub{fill:var(--text)}
.map .hub-t{font-size:23px;font-weight:700;fill:var(--navy)}
.map .hub-s{font-size:12.5px;font-weight:600;fill:#34465C}
.map .hub-i{fill:var(--navy)}
.map .node{fill:var(--navy)}
.map .node-t{font-size:15px;font-weight:600;fill:var(--text)}
.map .node-i{fill:var(--blue)}
.map + .prose{margin-top:22px}
@media (max-width: 699px){.map .wide{display:none}.map .tall{display:block}}
/* A small title above a row of tiles. */
.list-title{font-size:1rem;font-weight:700;letter-spacing:-.01em;margin-top:26px}
/* A compact grid of event photos, three across (two on phones, where an odd last photo takes a full row);
   each opens in the viewer below. */
.shots{margin-top:22px}
.shots ul{display:grid;grid-template-columns:repeat(12,1fr);gap:10px;padding:0;list-style:none}
.shots li{grid-column:span 4}
.shots a{position:relative;display:block;border-radius:12px;overflow:hidden;cursor:zoom-in}
.shots a:focus-visible{border-radius:12px}
.shots img{display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;transition:transform .3s}
.shots img[src$="nf-badges.jpg"]{object-position:50% 42%}
/* A document shown page by page (.pages): three across, two on phones, every page at the sheet's own shape. */
.shots.pages li:nth-child(n){grid-column:span 4}
.shots.pages li:nth-child(n) img{aspect-ratio:1584/1224}
/* A plain three-across photo grid (.three), two across on phones. Tall photos are cropped from the top, where their headline is. */
.shots.three li:nth-child(n){grid-column:span 4}
.shots.three li:nth-child(n) img{aspect-ratio:4/3}
.shots.three img[height="850"]{object-position:50% 26%}
.shots.three img[height="1138"]{object-position:50% 9%}
.shots figcaption{margin-top:.8em}
.shots + .prose{margin-top:22px}
@media (hover: hover){.shots a:hover img{transform:scale(1.03)}}
/* photo viewer */
.lightbox{width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;border:0;background:transparent;overflow:auto}
.lightbox[open]{display:grid;place-items:center}
.lightbox::backdrop{background:rgba(6,13,24,.93)}
.lightbox figure{display:grid;justify-items:center;gap:14px;margin:0}
.lightbox img,.lightbox video{display:block;width:auto;height:auto;max-width:min(92vw,1400px);max-height:74dvh;border-radius:14px}
.lightbox img[hidden],.lightbox video[hidden]{display:none}
.lightbox video{background:#000}
.lb-caption{max-width:min(86vw,46em);color:var(--text);font-size:.98rem;line-height:1.45;text-align:center;text-wrap:balance}
.lb-caption:empty{display:none}
.lightbox button{position:fixed;width:48px;height:48px;padding:0;border:0;border-radius:50%;background:var(--block);color:var(--text);display:grid;place-items:center;cursor:pointer;transition:background-color .2s,color .2s}
.lightbox button:hover{background:var(--blue);color:var(--navy)}
.lightbox button:focus-visible{outline:3px solid var(--coral);outline-offset:3px}
.lightbox svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.lb-close{top:16px;right:16px}
.lb-prev{left:16px;top:50%;margin-top:-24px}
.lb-next{right:16px;top:50%;margin-top:-24px}
html:has(.lightbox[open]){overflow:hidden}
@media (max-width: 699px){.duo{grid-template-columns:1fr}.pair{grid-template-columns:1fr}.pair .peek-view{height:340px}.shots.pages li:nth-child(n),.shots.three li:nth-child(n){grid-column:span 6}.peek-view{height:300px}.shots li{grid-column:span 6}.shots li:last-child:nth-child(odd){grid-column:1 / -1}.shots li:last-child:nth-child(odd) img{aspect-ratio:16/9}.lightbox figure{padding:76px 0 88px}.lightbox img,.lightbox video{max-width:100vw;max-height:52dvh;border-radius:0}.lightbox video{max-height:60dvh}.lb-caption{max-width:none;padding:0 18px;font-size:.92rem}.lb-prev,.lb-next{top:auto;bottom:20px;margin-top:0}.prose .with-clip{display:flex;flex-direction:column}.clip,.clip.wide{float:none;order:1;width:100%;margin:16px 0 0}.with-clip.lead .clip{order:0;margin:0 0 18px}.clip.logo{width:100%}.clip.logo>img{width:min(62%,230px)}}
@media (max-width: 699px){.years li.wide{flex-basis:100%}}
.pull{margin-top:28px;font-size:clamp(1.6rem,3.6vw,2.4rem);font-weight:600;line-height:1.12;letter-spacing:-.02em;max-width:16em;text-wrap:balance}
.note{color:var(--muted);font-size:.95rem;margin-top:.6em}
.note a{text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:3px}
.lockup{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:18px 34px;margin:28px 0 4px;padding:24px 28px;background:#141414;border-radius:var(--radius)}
.lockup img{height:22px;width:auto}

/* about */
.panel{position:relative;z-index:1;display:grid;gap:clamp(22px,3vw,36px);background:var(--block);border-radius:var(--radius);padding:clamp(24px,4vw,44px)}
.panel:has(.portrait){grid-template-columns:minmax(160px,250px) 1fr;align-items:center}
.portrait img{width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:calc(var(--radius) - 8px)}
.panel h1{font-size:clamp(1.9rem,4.4vw,2.9rem);font-weight:600;line-height:1.08;letter-spacing:-.02em}
.panel p{margin-top:.9em;max-width:38em}
.section-title{font-size:1.5rem;font-weight:600;letter-spacing:-.01em;margin-top:clamp(44px,6vw,68px)}
.career{display:grid;gap:14px;margin-top:18px;padding:0;list-style:none}
.career b{display:block}
.career span{color:var(--muted)}

/* contact form */
.form{display:grid;grid-template-columns:1fr 1fr;gap:18px 20px;margin-top:26px;max-width:44em}
.form .full{grid-column:1 / -1}
.field label{display:block;font-weight:600;font-size:.95rem;margin-bottom:6px}
.field label span{color:var(--muted);font-weight:400}
.field input,.field textarea{display:block;width:100%;font:inherit;color:var(--text);background:var(--navy);border:2px solid #6384A8;border-radius:12px;padding:.65em .9em}
.field textarea{min-height:10em;resize:vertical}
.field input:focus-visible,.field textarea:focus-visible{outline:3px solid var(--coral);outline-offset:2px}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
button.btn{font-family:inherit;line-height:inherit;cursor:pointer}
.cf-turnstile{min-height:65px}
.direct{color:var(--muted);margin-top:24px}
.direct a,.panel p a{color:var(--text);text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:3px}
@media (max-width: 699px){.form{grid-template-columns:1fr}}

/* phone and tablet: one column, straight stroke in the gaps */
@media (min-width: 521px) and (max-width: 700px){.weave{--lead-from:.74 !important}}
@media (min-width: 701px) and (max-width: 899px){.weave{--lead-from:.93 !important}}
@media (max-width: 899px){
  :root{--inset:var(--pad)}
  .weave{font-size:1rem;display:flex;flex-direction:column;align-items:center;gap:28px;padding:84px var(--pad)}
  .weave > [role=listitem]{width:100%;max-width:620px}
  .thread{display:none}
  /* Phone stroke: in from the left edge, curving down above the first block; down the middle; curving out to the right below the last.
     --ms is its thickness, about the same share of a block's width as the desktop stroke. */
  .weave{--ms:clamp(24px,7.5vw,36px)}
  .weave > [role=listitem]{position:relative}
  /* Each piece grows down from its top, one after another (--n is the block's place in the list), starting as the curve
     above the first block finishes: .75s in, then .28s a block. */
  .weave > [role=listitem]::after{content:"";position:absolute;left:50%;top:-28px;bottom:-28px;width:var(--ms);margin-left:calc(var(--ms) / -2);background:var(--blue);transform-origin:50% 0;animation:grow .28s linear both;animation-delay:calc(.75s + var(--n,0) * .28s)}
  @keyframes grow{from{transform:scaleY(0)}to{transform:scaleY(1)}}
  .weave > [role=listitem]:nth-of-type(1){--n:0}
  .weave > [role=listitem]:nth-of-type(2){--n:1}
  .weave > [role=listitem]:nth-of-type(3){--n:2}
  .weave > [role=listitem]:nth-of-type(4){--n:3}
  .weave > [role=listitem]:nth-of-type(5){--n:4}
  .weave > [role=listitem]:nth-of-type(6){--n:5}
  .weave > [role=listitem]:nth-of-type(7){--n:6}
  .weave > [role=listitem]:nth-of-type(8){--n:7}
  .weave > svg + [role=listitem]::after{top:0}
  .weave > [role=listitem]:last-child::after{bottom:0}
  /* Above the first block the stroke is an SVG path, drawn in along its curve when the page loads. It is sized in units
     of --ms (2.3 high, a quarter turn of radius 1.5), and the curve out below the last block matches it.
     --lead-from is how much of the path starts out undrawn: the part that begins off the left edge is skipped. */
  svg.lead{display:block;position:absolute;bottom:100%;left:50%;width:calc(14 * var(--ms));height:calc(2.3 * var(--ms));margin-left:calc(-13.5 * var(--ms));overflow:visible;pointer-events:none}
  svg.lead path{fill:none;stroke:var(--blue);stroke-width:1;stroke-dasharray:1;stroke-dashoffset:0;animation:lead .9s cubic-bezier(.3,.1,.3,1) both}
  .weave{--lead-from:.56}
  @keyframes lead{from{stroke-dashoffset:var(--lead-from)}to{stroke-dashoffset:0}}
  .weave > [role=listitem]:last-child::before{content:"";position:absolute;top:100%;left:calc(50% - var(--ms) / 2);right:-100vw;height:calc(2.3 * var(--ms));border:0 solid var(--blue);border-bottom-width:var(--ms);border-left-width:var(--ms);border-bottom-left-radius:calc(2 * var(--ms))}
  .block{height:auto;border-radius:var(--radius)}
  .block:focus-visible{border-radius:var(--radius)}
  .ph{height:auto;aspect-ratio:16/9}
  .tx{padding:18px 22px 22px}
  .block h2{font-size:1.35rem;white-space:normal}
  .block p{font-size:.95rem}
  .block.cta .tx{min-height:210px;padding:30px 26px}
  .block.cta h2{font-size:2.1rem}
  .block.cta p{font-size:1.15rem}
  .block.cta p.also{font-size:.98rem}
  .more-row{display:flex;gap:12px;overflow-x:auto;padding:14px var(--pad);scrollbar-width:thin}
  .more .block{flex:0 0 150px}
  .panel:has(.portrait){grid-template-columns:1fr}
  .portrait{max-width:260px}
}
@media (max-width: 699px){
}
/* The Fun page: personal projects, apart from the professional work. Each is a wide card with its picture beside its
   text, the picture alternating sides down the page; on phones the picture sits on top. A project without a photo
   yet shows an icon in its place. */
.fun-page h1{margin-top:clamp(24px,4vw,40px)}
.lede{color:var(--muted);font-size:clamp(1rem,1.6vw,1.1rem);max-width:40em;margin-top:.9em}
.fun{display:grid;gap:clamp(18px,2.4vw,26px);margin-top:clamp(28px,4vw,44px);padding:0;list-style:none}
.fun li{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);min-height:clamp(250px,27vw,340px);background:var(--block);border-radius:var(--radius);overflow:hidden}
.fun li:nth-child(even) .pic{order:1}
.fun .pic{position:relative;display:block;background:#000}
.fun a.pic img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover;transition:transform .3s}
.fun a.pic:hover img{transform:scale(1.03)}
.fun .pic.top img{object-position:left top}
.fun .pic.icon{display:grid;place-items:center;background:#0A1626}
.fun .pic.icon svg{width:clamp(72px,11vw,120px);height:auto;fill:var(--blue);opacity:.5}
/* A project's logo, shown at icon size in the picture panel of its card and at the top of its page. */
.fun .pic.logo img{position:static;width:clamp(72px,11vw,120px);height:auto;object-fit:contain;transform:none}
.fun .tx{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;padding:clamp(22px,3.4vw,42px)}
.fun .tag{font-size:.74rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--blue);border:1.5px solid var(--blue);padding:.2em .75em;border-radius:99px}
.fun h2{font-size:clamp(1.4rem,2.6vw,1.9rem);font-weight:600;line-height:1.1;letter-spacing:-.02em;margin-top:.6em}
.fun p{color:var(--muted);margin-top:.75em}
.fun .tx a{margin-top:1em;font-weight:700;text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:4px}
.fun .tx a:hover{text-decoration-color:var(--text)}
.more-link,.back{display:inline-flex;align-items:center;gap:.4em}
.more-link svg,.back svg{width:1.15em;height:1.15em;fill:none;stroke:var(--coral);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* A project's own page: its video sits where a case study's header photo does, and a link leads back to the list. */
/* The stroke is coral on these pages, to set them apart from the professional case studies. */
.fun-case .bar{background:var(--coral)}
/* A picture or looping clip across the text column of a project page, with its caption. */
.fun-fig{max-width:44em;margin-top:24px}
.fun-fig img,.fun-fig video{display:block;width:100%;height:auto;border-radius:14px}
.fun-fig figcaption{color:var(--muted);font-size:.82rem;line-height:1.35;margin-top:.55em}
.fun-fig + .prose{margin-top:24px}
/* A row of photos at one height: three upright (3:4) and one wide (4:3), so the columns are 9 : 9 : 16 : 9.
   On phones the three upright photos share a row and the wide one sits beneath them. */
.costumes{display:grid;grid-template-columns:9fr 9fr 16fr 9fr;gap:14px;margin-top:24px}
.costumes figure{min-width:0}
.costumes img{display:block;width:100%;height:auto;border-radius:14px}
.costumes figcaption{color:var(--muted);font-size:.82rem;line-height:1.35;margin-top:.55em}
/* The finished costume in use: two landscape photos and a portrait one, at one height. On a phone the first spans the width. */
.costumes.played{grid-template-columns:16fr 16fr 9fr}
@media (max-width: 699px){.costumes{grid-template-columns:repeat(3,1fr);gap:10px}.costumes .wide{grid-column:1 / -1;order:1}.costumes.played{grid-template-columns:16fr 9fr}.costumes.played figure:first-child{grid-column:1 / -1}}
/* A group of labeled renders or pictures, three across (one per row on phones). */
.models{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:24px}
.models div{background:#0A1626;border-radius:14px;overflow:hidden}
.models img{display:block;width:100%;height:auto}
.models b{display:block;padding:.1em 1em 1em;font-size:.9rem;font-weight:700;line-height:1.3}
.models figcaption{grid-column:1 / -1;color:var(--muted);font-size:.82rem;line-height:1.35}
@media (max-width: 699px){.models{grid-template-columns:1fr}}
/* A tall phone screenshot set to the right of a project page, with the sections after it (tiles and text) beside it.
   On phones it sits on its own between the sections, at a comfortable width. */
.with-shot{display:flow-root}
.clip.shot{width:min(32%,270px);margin:clamp(44px,6vw,68px) 0 1em 2em}
.clip.shot>img{box-shadow:0 0 0 1px rgba(159,179,200,.18)}
@media (max-width: 899px){.with-shot .kit.icons.two{grid-template-columns:1fr}}
@media (max-width: 699px){.clip.shot{width:min(100%,320px);margin:28px auto 0}}
/* Two pictures side by side on a project page (.narrow for two phone screens). */
.fun-duo{max-width:52em}
.fun-duo.narrow{max-width:34em}
.fun-duo figcaption{color:var(--muted);font-size:.82rem;line-height:1.35}
.fun-duo img{box-shadow:0 0 0 1px rgba(159,179,200,.18)}
.fun-case .prose + .fun-duo,.fun-case .kit + .fun-duo{margin-top:28px}
.fun-case .kit.trail.row::before{background:var(--coral)}
.fun-case .kit.trail li:first-child::before,.fun-case .kit.trail li:last-child::after{background:var(--coral)}
.fun-case .kit.steps b::before{color:var(--coral)}
.fun-case .kit.steps span{font-size:.9rem;line-height:1.45}
.fun-case .kit.steps + .prose{margin-top:0}
.case-top .fun-hero{background:#000}
.case-top .fun-hero.icon{display:grid;place-items:center;aspect-ratio:3/1;background:#0A1626}
.case-top .fun-hero.icon img{width:clamp(64px,10vw,120px);height:auto;object-fit:contain}
/* A banner-shaped cover image keeps its own wide shape, so nothing is cropped. */
.case-top .fun-hero.banner{aspect-ratio:1024/500}
.fun-hero.icon svg{width:clamp(64px,10vw,120px);height:auto;fill:var(--coral);opacity:.6}
.fun-hero .yt{position:absolute;inset:0;display:block;width:100%;height:100%;border:0}
.fun-hero a.yt img{display:block;width:100%;height:100%;object-fit:contain}
.fun-hero .play{position:absolute;right:clamp(14px,2.4vw,28px);bottom:clamp(14px,2.4vw,28px);width:64px;height:64px;border-radius:50%;background:var(--coral);display:grid;place-items:center;transition:transform .2s}
.fun-hero .play svg{width:30px;height:30px;fill:var(--navy)}
.fun-hero a.yt:hover .play{transform:scale(1.08)}
.back-row{margin-top:clamp(40px,6vw,64px)}
.back{font-weight:700;text-decoration:none;border:2px solid var(--coral);border-radius:99px;padding:.6em 1.4em .6em 1.1em;transition:background .2s,color .2s}
.back:hover{background:var(--coral);color:var(--navy)}
.back:hover svg{stroke:var(--navy)}
.back:focus-visible{border-radius:99px}
/* With four links in the header, narrow phones need it a little tighter; on the very narrowest the logo stands alone. */
@media (max-width: 389px){.nav{gap:12px}.id{gap:9px;font-size:1rem}.id span{white-space:nowrap}}
@media (max-width: 349px){.id span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}}
.panel p a{text-decoration:underline;text-decoration-color:var(--blue);text-decoration-thickness:2px;text-underline-offset:3px}
.panel p a:hover{text-decoration-color:var(--text)}
@media (max-width: 699px){.fun li{grid-template-columns:1fr;min-height:0}.fun li:nth-child(even) .pic{order:0}.fun .pic{aspect-ratio:16/9}.fun .pic.icon{aspect-ratio:3/1}.fun .pic.icon svg,.fun .pic.logo img{width:56px}}
@media (prefers-reduced-motion: reduce){
  .thread path,.bar,svg.lead path,.hello[open],.weave > [role=listitem]::after{animation:none}
  *,*::before,*::after{transition:none !important}
  .menu{transform:none}
}
