/* =========================================================
   Simon Selvam — Premium portfolio
   Minimalist, editorial, icon-driven
   ========================================================= */

:root{
  --bg:#F3F0EA;
  --bg-2:#EAE5DC;
  --surface:#FFFFFF;
  --ink:#17150F;
  --ink-2:#3D382E;
  --muted:#6B6455;
  --line:rgba(23,21,15,.10);
  --line-2:rgba(23,21,15,.18);
  --accent:#17150F;
  --accent-ink:#F3F0EA;
  --hi:#C7B594;        /* warm gold for accents */
  --serif:'Fraunces', ui-serif, Georgia, serif;
  --sans:'Inter', ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif;
  --container:1400px;
  --thumb-ratio:808/632;     /* standard portfolio thumbnail aspect */
  --thumb-min:202px;         /* standard thumbnail display width */
  --r-sm:10px;
  --r:18px;
  --r-lg:28px;
  --gap:clamp(16px, 2.2vw, 28px);
  --ease:cubic-bezier(.22,.61,.36,1);
  --shadow-sm:0 1px 0 rgba(23,21,15,.04), 0 6px 18px rgba(23,21,15,.04);
  --shadow:0 1px 0 rgba(23,21,15,.05), 0 22px 48px -28px rgba(23,21,15,.18);
  color-scheme:light;
}
html[data-theme="dark"]{
  color-scheme:dark;
  --bg:#0E0D0A;
  --bg-2:#16140F;
  --surface:#1B1915;
  --ink:#F3F0EA;
  --ink-2:#D8D2C3;
  --muted:#8E8675;
  --line:rgba(243,240,234,.10);
  --line-2:rgba(243,240,234,.18);
  --accent:#F3F0EA;
  --accent-ink:#0E0D0A;
  --hi:#D5BE8E;
  --shadow-sm:0 1px 0 rgba(0,0,0,.3), 0 6px 18px rgba(0,0,0,.35);
  --shadow:0 1px 0 rgba(0,0,0,.3), 0 22px 48px -28px rgba(0,0,0,.6);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  transition:background .4s var(--ease), color .4s var(--ease);
}
img,svg,video{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font-family:inherit;color:inherit;background:none;border:0;cursor:pointer}

.container{max-width:var(--container);margin:0 auto;padding:0 clamp(20px, 4vw, 40px)}

/* Visually hidden but accessible to screen readers + SEO */
.sr-only{
  position:absolute !important;
  width:1px;height:1px;
  padding:0;margin:-1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
  border:0;
}

/* -------- Icon helpers -------- */
.ic{
  width:18px;height:18px;
  fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
  flex:none;
}
.ic[viewBox]{}
svg use{pointer-events:none}
/* Filled-glyph icons (Behance, LinkedIn, WhatsApp, play) live as
   <symbol> defs without an inline fill; without this they'd render
   as broken outlines because of the global .ic { fill:none } above. */
svg.ic:has(use[href="#i-behance"]),
svg.ic:has(use[href="#i-linkedin"]),
svg.ic:has(use[href="#i-whatsapp"]),
svg.ic:has(use[href="#i-play"]){
  fill:currentColor;
  stroke:none;
}
.foot-soc svg, .soc svg{stroke-width:1.4}

/* Scroll progress */
.scroll-progress{
  position:fixed;top:0;left:0;height:2px;width:0;
  background:var(--ink);z-index:200;transition:width .15s linear;
}

/* =========================================================
   NAV
   ========================================================= */
#nav{
  position:fixed;top:18px;left:50%;transform:translateX(-50%);
  z-index:100;
  display:flex;align-items:center;gap:18px;
  padding:10px 14px;
  background:color-mix(in oklab, var(--bg) 78%, transparent);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border:1px solid var(--line);
  border-radius:999px;
  box-shadow:var(--shadow-sm);
  max-width:calc(100vw - 24px);
  transition:padding .35s var(--ease), top .35s var(--ease);
}
#nav.scrolled{padding:8px 12px}

.brand{
  font-family:var(--serif);
  font-weight:500;
  font-size:1.2rem;
  letter-spacing:-.02em;
  padding:0 8px 0 10px;
  color:var(--ink);
}
.brand span{color:var(--hi)}

.nav-dots{display:flex;align-items:center;gap:4px}
.nav-dots a{
  position:relative;
  font-family:var(--sans);
  font-size:.72rem;font-weight:500;
  letter-spacing:.08em;
  color:var(--muted);
  padding:8px 10px;border-radius:999px;
  transition:color .25s var(--ease), background .25s var(--ease);
}
.nav-dots a:hover{color:var(--ink);background:var(--line)}
.nav-dots a.is-active{color:var(--ink);background:var(--bg-2)}
.nav-dots a[data-tip]:hover::after{
  content:attr(data-tip);
  position:absolute;left:50%;top:calc(100% + 8px);transform:translateX(-50%);
  font-size:.65rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap;
}

.nav-actions{display:flex;align-items:center;gap:6px;padding-left:6px;border-left:1px solid var(--line)}
.icon-btn{
  width:38px;height:38px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid transparent;color:var(--ink);
  transition:background .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
}
.icon-btn:hover{background:var(--bg-2);border-color:var(--line)}
.icon-btn:active{transform:scale(.95)}
.icon-btn .ic{width:18px;height:18px}

#themeBtn .ic-moon{display:none}
html[data-theme="dark"] #themeBtn .ic-sun{display:none}
html[data-theme="dark"] #themeBtn .ic-moon{display:block}

.pill-cta{
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 16px 9px 14px;
  background:var(--ink);color:var(--bg);
  border-radius:999px;
  font-size:.82rem;font-weight:500;letter-spacing:.01em;
  transition:transform .25s var(--ease), opacity .25s var(--ease);
}
.pill-cta:hover{transform:translateY(-1px);opacity:.95}
.pill-cta .ic{stroke:var(--bg)}

.nav-text-btn{
  display:inline-flex;align-items:center;
  padding:9px 16px;
  border-radius:999px;
  background:transparent;color:var(--ink);
  border:1px solid var(--line-2);
  font-size:.82rem;font-weight:500;letter-spacing:.01em;
  transition:background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
  white-space:nowrap;
}
.nav-text-btn:hover{background:var(--ink);color:var(--bg);border-color:var(--ink);transform:translateY(-1px)}

/* =========================================================
   HERO
   ========================================================= */
.hero{
  position:relative;
  min-height:100vh;
  min-height:100svh;
  padding:140px 0 80px;
  display:flex;align-items:center;
  overflow:hidden;
}
.hero::before,.hero::after{
  content:"";position:absolute;border-radius:50%;filter:blur(80px);opacity:.55;z-index:0;pointer-events:none;
}
.hero::before{width:420px;height:420px;background:radial-gradient(circle,var(--hi),transparent 70%);top:-10%;right:-6%}
.hero::after{width:360px;height:360px;background:radial-gradient(circle,#A9B89D,transparent 70%);bottom:-12%;left:-8%;opacity:.4}
html[data-theme="dark"] .hero::before{opacity:.18}
html[data-theme="dark"] .hero::after{opacity:.14}

.hero-inner{
  position:relative;z-index:1;
  width:100%;max-width:var(--container);
  margin:0 auto;padding:0 clamp(20px,4vw,40px);
  display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(24px,5vw,72px);
  align-items:center;
}

.status{
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 12px 6px 10px;border-radius:999px;
  background:var(--bg-2);border:1px solid var(--line);
  font-size:.75rem;letter-spacing:.06em;color:var(--ink-2);
}
.status-dot{
  width:8px;height:8px;border-radius:50%;background:#5DC57A;
  box-shadow:0 0 0 4px color-mix(in oklab, #5DC57A 30%, transparent);
  animation:pulse 2.2s infinite;
}
@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.15)}}

.hero h1{
  font-family:var(--serif);
  font-weight:400;
  font-size:clamp(3.5rem, 9vw, 7.2rem);
  line-height:.92;
  letter-spacing:-.035em;
  margin:18px 0 14px;
  color:var(--ink);
}
.hero h1 em{font-style:italic;color:var(--ink);font-weight:300;display:block}

.role{
  display:flex;align-items:center;flex-wrap:wrap;gap:10px;
  color:var(--ink-2);font-size:.95rem;
  margin:0 0 28px;
}
.role .ic{width:16px;height:16px;color:var(--hi)}
.dot-sep{width:4px;height:4px;border-radius:50%;background:var(--line-2)}

.hero-actions{display:flex;flex-wrap:wrap;gap:10px}

.btn{
  display:inline-flex;align-items:center;gap:10px;
  padding:12px 20px;border-radius:999px;
  font-size:.88rem;font-weight:500;letter-spacing:.01em;
  border:1px solid transparent;
  transition:transform .25s var(--ease), background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.btn .ic{width:16px;height:16px}
.btn-solid{background:var(--ink);color:var(--bg);}
.btn-solid:hover{transform:translateY(-1px);box-shadow:0 14px 28px -16px rgba(23,21,15,.5)}
.btn-solid .ic{stroke:var(--bg)}
.btn-ghost{background:transparent;border-color:var(--line-2);color:var(--ink)}
.btn-ghost:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.btn-ghost:hover .ic{stroke:var(--bg)}
.btn-lg{padding:16px 26px;font-size:.95rem}

.hero-stats{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:14px;margin-top:42px;
  padding-top:28px;border-top:1px solid var(--line);
}
.stat{display:flex;flex-direction:column;gap:4px}
.stat .ic{width:18px;height:18px;color:var(--hi);margin-bottom:4px}
.stat b{
  font-family:var(--serif);
  font-weight:400;
  font-size:clamp(1.7rem, 3.4vw, 2.4rem);
  line-height:1;letter-spacing:-.02em;
  color:var(--ink);
}
.stat span{font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}

.hero-right{position:relative;display:flex;justify-content:center}
.portrait{
  position:relative;margin:0;
  width:clamp(240px, 30vw, 380px);
  aspect-ratio:4/5;
  border-radius:var(--r-lg);
  overflow:hidden;
  background:var(--bg-2);
  box-shadow:var(--shadow);
  border:1px solid var(--line);
}
.portrait img{width:100%;height:100%;object-fit:cover}
.portrait-fallback{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-size:7rem;color:var(--hi);font-style:italic;
}
.portrait-tag{
  position:absolute;left:14px;bottom:14px;
  display:inline-flex;align-items:center;gap:8px;
  padding:8px 12px;border-radius:999px;
  background:color-mix(in oklab, var(--surface) 88%, transparent);
  backdrop-filter:blur(8px);
  border:1px solid var(--line);
  font-size:.72rem;letter-spacing:.06em;color:var(--ink);
}

.scroll-cue{
  position:absolute;left:50%;bottom:24px;transform:translateX(-50%);
  z-index:1;color:var(--muted);
}
.mouse{
  display:block;width:22px;height:34px;
  border:1.5px solid var(--line-2);border-radius:14px;
  position:relative;
}
.mouse::after{
  content:"";position:absolute;left:50%;top:6px;transform:translateX(-50%);
  width:3px;height:7px;border-radius:2px;background:var(--ink);
  animation:scrollDown 1.6s var(--ease) infinite;
}
@keyframes scrollDown{0%{opacity:0;transform:translate(-50%,0)}30%{opacity:1}70%{opacity:1}100%{opacity:0;transform:translate(-50%,12px)}}

/* =========================================================
   TICKER
   ========================================================= */
.ticker{
  border-block:1px solid var(--line);
  background:var(--bg-2);
  overflow:hidden;
  padding:18px 0;
}
.ticker-track{
  display:flex;align-items:center;gap:32px;
  white-space:nowrap;width:max-content;
  animation:ticker 38s linear infinite;
  /* iOS Safari: promote to its own GPU layer so the marquee keeps
     running smoothly during touch scrolling (otherwise WebKit runs
     it on the main thread and it stutters or appears frozen). */
  will-change:transform;
  transform:translate3d(0,0,0);
  -webkit-backface-visibility:hidden;
  backface-visibility:hidden;
}
.ticker-track span{
  font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:clamp(1.4rem,3vw,2.1rem);
  color:var(--ink);letter-spacing:-.01em;
}
.ticker-track i{
  width:8px;height:8px;border-radius:50%;background:var(--hi);flex:none;
}
/* translate3d keeps the animation on the compositor thread on iOS */
@keyframes ticker{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(-50%,0,0)}
}

/* =========================================================
   COMMON SECTION TYPE
   ========================================================= */
section{padding:clamp(80px,11vw,140px) 0}
.eyebrow{
  display:inline-flex;align-items:center;gap:10px;
  font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--muted);
}
.eyebrow i{
  font-style:normal;
  font-family:var(--serif);font-weight:400;font-size:.9rem;letter-spacing:0;
  color:var(--hi);
  border:1px solid var(--line-2);border-radius:999px;
  padding:2px 8px;
}
.eyebrow--center{justify-content:center}
.display{
  font-family:var(--serif);
  font-weight:300;
  font-size:clamp(2.3rem, 5.5vw, 4.4rem);
  line-height:1;letter-spacing:-.025em;
  margin:14px 0 0;color:var(--ink);
}
.display em{font-style:italic;font-weight:400;color:var(--ink)}

.sec-head{margin-bottom:48px}
.sec-head--row{display:flex;align-items:end;justify-content:space-between;gap:24px;flex-wrap:wrap}

.text-link{
  display:inline-flex;align-items:center;gap:6px;
  font-size:.85rem;color:var(--ink);
  padding-bottom:2px;border-bottom:1px solid var(--line-2);
  transition:gap .25s var(--ease), border-color .25s var(--ease);
}
.text-link:hover{gap:10px;border-color:var(--ink)}

/* =========================================================
   ABOUT
   ========================================================= */
.about{background:var(--bg)}
.about-grid{
  display:grid;grid-template-columns:1.1fr 1fr;gap:clamp(28px,5vw,80px);
  align-items:end;
}
.about-cards{
  display:grid;grid-template-columns:1fr 1fr;gap:14px;
}
.fact{
  display:flex;align-items:center;gap:14px;
  padding:18px 20px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line);
  transition:transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.fact:hover{transform:translateY(-2px);border-color:var(--line-2);box-shadow:var(--shadow-sm)}
.fact .ic{width:22px;height:22px;color:var(--hi);flex:none}
.fact span{display:block;font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin-bottom:2px}
.fact b{font-family:var(--serif);font-weight:400;font-size:1rem;letter-spacing:-.005em;color:var(--ink);font-style:italic}

/* =========================================================
   SKILLS / TOOLKIT
   ========================================================= */
.skills{background:var(--bg-2)}
.tool-grid{
  display:grid;
  grid-template-columns:repeat(6,1fr);
  gap:14px;
}
.tool{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:12px;
  padding:26px 14px 20px;
  position:relative;
  transition:transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.tool:hover{transform:translateY(-3px);border-color:var(--line-2);box-shadow:var(--shadow)}
.logo-label{
  display:block;
  font-family:var(--sans);
  font-size:.7rem;
  font-weight:500;
  letter-spacing:.04em;
  color:var(--ink-2);
  text-align:center;
  line-height:1.25;
  max-width:100%;
  opacity:0;
  transform:translateY(-4px);
  transition:opacity .25s var(--ease), transform .25s var(--ease);
  pointer-events:none;
}
.tool:hover .logo-label{
  opacity:1;
  transform:translateY(0);
}
/* Tool logo tiles — small, uniform mark size capped in px so the
   row reads calm and premium at any viewport width. */
.logo{
  width:clamp(42px, 3.6vw, 52px);
  aspect-ratio:1;
  border-radius:11px;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  position:relative;
  flex:none;
}

/* Product-mark monograms — coloured chip, glyph sized to the chip */
.logo-mono{
  background:var(--bg, var(--bg-2));
  color:var(--fg, var(--ink));
  width:100%;height:100%;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--sans);
  font-weight:700;
  font-size:clamp(.95rem, 1.15vw, 1.15rem);
  letter-spacing:-.03em;
  line-height:1;
}

/* Standalone shape logos — image sits inside with a small inset margin
   so the brand mark doesn't run to the edges */
.logo-plain{background:transparent;width:100%;height:100%}
.logo-plain svg,
.logo-plain img{
  width:88%;height:88%;
  object-fit:contain;
  display:block;
}

/* =========================================================
   WORK
   ========================================================= */
.work{background:var(--bg)}
/* Image-size spec reference — quiet caption row */
.size-spec{
  list-style:none;
  display:flex;flex-wrap:wrap;gap:8px;
  margin:0 0 28px;padding:0;
}
.size-spec li{
  display:flex;flex-direction:column;gap:2px;
  padding:10px 16px;
  background:var(--bg-2);
  border:1px solid var(--line);
  border-radius:12px;
  min-width:160px;
}
.size-label{
  font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
}
.size-value{
  font-family:var(--sans);font-size:.85rem;color:var(--ink-2);
}
.size-value b{
  font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:1rem;color:var(--ink);letter-spacing:-.01em;margin-right:4px;
}

.filters{
  display:flex;flex-wrap:wrap;gap:8px;
  padding:6px;border-radius:999px;
  background:var(--bg-2);border:1px solid var(--line);
  width:max-content;max-width:100%;
  margin-bottom:36px;
}
.chip{
  height:38px;padding:0 16px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--ink-2);
  font-family:var(--sans);font-size:.82rem;font-weight:500;letter-spacing:.01em;
  white-space:nowrap;
  transition:background .25s var(--ease), color .25s var(--ease), transform .25s var(--ease);
}
.chip:hover{background:var(--surface);color:var(--ink)}
.chip.active{background:var(--ink);color:var(--bg)}

/* =========================================================
   Portfolio work grid — CMS-driven (admin → Grid layout)
   · Cols / gap / radius / aspect come from CSS vars set by
     js/cms/portfolioGrid.js apply().
   · Per-card sizing via data-size (small/medium/large/wide/
     tall/featured) creates the bento layout.
   · Masonry mode swaps to CSS columns for natural heights.
   ========================================================= */
.work-grid{
  display:grid;
  grid-template-columns:repeat(var(--pg-cols-desktop, 5), 1fr);
  grid-auto-flow:dense;
  gap:var(--pg-gap, 14px);
}
.card{
  position:relative;overflow:hidden;
  border-radius:var(--pg-radius, 8px);
  background:var(--bg-2);border:1px solid var(--line);
  cursor:pointer;
  aspect-ratio:var(--pg-aspect, var(--thumb-ratio));
  transition:transform .35s var(--ease), box-shadow .35s var(--ease);
}
.card:hover{transform:translateY(-3px);box-shadow:var(--shadow)}
.card img{width:100%;height:100%;object-fit:cover;transition:transform .9s var(--ease), filter .35s var(--ease)}
.card:hover img{transform:scale(1.06)}
/* Disable image zoom when admin toggles it off */
.work-grid.no-zoom .card:hover img{transform:none}
.work-grid.no-title .card .card-name{display:none}

/* -------- Card size variants (bento) -------- */
/* small + medium = default 1×1 footprint */
.card[data-size="large"],
.card[data-size="featured"]{ grid-column:span 2; grid-row:span 2; }
.card[data-size="wide"]    { grid-column:span 2; }
.card[data-size="tall"]    { grid-row:span 2; }

/* Featured badge */
.card[data-size="featured"]::after{
  content:"Featured";
  position:absolute;right:10px;top:10px;z-index:3;
  font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink);background:var(--hi);
  padding:4px 10px;border-radius:999px;font-weight:600;
}

/* -------- Masonry mode -------- */
.work-grid.is-masonry{
  display:block;
  column-count:var(--pg-cols-desktop, 5);
  column-gap:var(--pg-gap, 14px);
}
.work-grid.is-masonry .card{
  display:block;width:100%;
  break-inside:avoid;
  margin:0 0 var(--pg-gap, 14px);
  aspect-ratio:auto;            /* let the image dictate height */
  grid-column:auto;grid-row:auto;
}
.work-grid.is-masonry .card img,
.work-grid.is-masonry .card video{
  height:auto;width:100%;display:block;
  aspect-ratio:var(--pg-aspect, var(--thumb-ratio));
}
/* In masonry, all size variants collapse to natural height — but we
   still respect "wide" by giving it a wider aspect, and "tall" by
   giving it a taller one, so the layout visually varies. */
.work-grid.is-masonry .card[data-size="wide"] img,
.work-grid.is-masonry .card[data-size="wide"] video{ aspect-ratio:16/9 }
.work-grid.is-masonry .card[data-size="tall"] img,
.work-grid.is-masonry .card[data-size="tall"] video{ aspect-ratio:3/4 }
.work-grid.is-masonry .card[data-size="large"] img,
.work-grid.is-masonry .card[data-size="featured"] img,
.work-grid.is-masonry .card[data-size="large"] video,
.work-grid.is-masonry .card[data-size="featured"] video{ aspect-ratio:1/1 }

/* Hover-only project name pill — appears at top-left on hover */
.card .card-name{
  position:absolute;left:10px;top:10px;z-index:2;
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 12px;border-radius:999px;
  background:rgba(15,14,10,.78);
  backdrop-filter:blur(10px);
  color:#fff;
  font-size:.72rem;letter-spacing:.01em;
  white-space:nowrap;max-width:calc(100% - 20px);
  overflow:hidden;text-overflow:ellipsis;
  opacity:0;transform:translateY(-4px);
  transition:opacity .25s var(--ease), transform .25s var(--ease);
  pointer-events:none;
}
.card:hover .card-name{opacity:1;transform:translateY(0)}

/* Reel cards still get a subtle play marker so videos read as videos */
.card .play{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  z-index:1;color:#fff;pointer-events:none;
}
.card .play .ic{
  width:48px;height:48px;
  stroke:#fff;fill:rgba(255,255,255,.15);
  filter:drop-shadow(0 4px 12px rgba(0,0,0,.4));
}

.card video{width:100%;height:100%;object-fit:cover}

/* Reel card */
.card.reel{
  background:var(--ink);
}
.card.reel video{opacity:.85}
.card.reel .play{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  z-index:2;color:#fff;pointer-events:none;
}
.card.reel .play .ic{width:42px;height:42px;stroke:#fff;fill:rgba(255,255,255,.1)}

.work-empty{text-align:center;color:var(--muted);margin-top:24px}

/* =========================================================
   EXPERIENCE / TIMELINE
   ========================================================= */
.path{background:var(--bg-2)}
.timeline{
  display:flex;flex-direction:column;gap:10px;
  margin-top:8px;
}
.tl-row{
  display:grid;grid-template-columns:64px 1fr;gap:18px;
  padding:22px 24px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  align-items:center;
  transition:transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.tl-row:hover{transform:translateX(4px);border-color:var(--line-2);box-shadow:var(--shadow-sm)}
.tl-mono{
  width:48px;height:48px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-style:italic;font-weight:500;font-size:1rem;
  letter-spacing:-.01em;
  background:var(--bg-2);color:var(--ink-2);
  border:1px solid var(--line);
}
.tl-mono[data-on]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.tl-body{display:flex;flex-direction:column;gap:4px;min-width:0}
.tl-top{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.tl-top b{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:1.15rem;color:var(--ink);letter-spacing:-.01em;
}
.tl-when{
  display:inline-flex;align-items:center;gap:6px;
  font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
}
.tl-when .ic{width:14px;height:14px;color:var(--hi)}
.tl-co{font-size:.88rem;color:var(--ink-2)}

/* =========================================================
   SERVICES
   ========================================================= */
.services{background:var(--bg)}
.svc-grid{
  display:grid;grid-template-columns:repeat(6,1fr);gap:14px;
}
.svc{
  aspect-ratio:1;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  padding:18px;text-align:center;
  transition:transform .3s var(--ease), background .3s var(--ease), color .3s var(--ease), box-shadow .3s var(--ease);
}
.svc:hover{transform:translateY(-3px);background:var(--ink);color:var(--bg);box-shadow:var(--shadow)}
.svc .ic{width:30px;height:30px;color:var(--hi);transition:color .3s var(--ease)}
.svc:hover .ic{color:var(--bg)}
.svc b{
  font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:1rem;letter-spacing:-.005em;
}

/* =========================================================
   CONTACT
   ========================================================= */
.contact{
  background:var(--bg-2);
  position:relative;overflow:hidden;
}
.contact::before{
  content:"";position:absolute;inset:auto -10% -50% -10%;height:420px;
  background:radial-gradient(ellipse,var(--hi),transparent 70%);opacity:.35;filter:blur(50px);
  pointer-events:none;
}
html[data-theme="dark"] .contact::before{opacity:.16}

.contact-inner{position:relative;z-index:1;text-align:center}
.contact-title{margin:14px auto 36px;max-width:18ch}
.contact-actions{display:flex;justify-content:center;flex-wrap:wrap;gap:12px;margin-bottom:48px}

.social-row{
  display:flex;justify-content:center;gap:10px;flex-wrap:wrap;
  padding-top:28px;border-top:1px solid var(--line);
}
.soc{
  width:52px;height:52px;border-radius:50%;
  background:var(--surface);border:1px solid var(--line);
  display:inline-flex;align-items:center;justify-content:center;color:var(--ink);
  transition:transform .3s var(--ease), background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.soc:hover{transform:translateY(-3px);background:var(--ink);color:var(--bg);border-color:var(--ink)}
.soc .ic{width:20px;height:20px}
.soc:hover .ic{stroke:var(--bg)}
/* Filled glyphs flip with currentColor, so they follow the hover */

/* =========================================================
   FOOTER
   ========================================================= */
.footer{
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:14px;
  padding:32px clamp(20px,4vw,40px);
  border-top:1px solid var(--line);
  background:var(--bg);
}
.foot-soc{display:flex;gap:6px}
.foot-soc a{
  width:36px;height:36px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;color:var(--muted);
  transition:color .25s var(--ease), background .25s var(--ease);
}
.foot-soc a:hover{color:var(--ink);background:var(--bg-2)}
.foot-copy{font-size:.75rem;letter-spacing:.06em;color:var(--muted)}

/* =========================================================
   FLOATING
   ========================================================= */
.fab{
  position:fixed;right:22px;bottom:22px;z-index:90;
  width:52px;height:52px;border-radius:50%;
  background:#25D366;color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  box-shadow:0 12px 30px -10px rgba(37,211,102,.55);
  transition:transform .25s var(--ease);
}
.fab:hover{transform:translateY(-2px) scale(1.04)}
.fab .ic{width:24px;height:24px;stroke:#fff;fill:#fff}

.to-top{
  position:fixed;right:22px;bottom:84px;z-index:90;
  width:42px;height:42px;border-radius:50%;
  background:var(--surface);color:var(--ink);
  border:1px solid var(--line);
  display:none;align-items:center;justify-content:center;
  box-shadow:var(--shadow-sm);
}
.to-top.show{display:inline-flex}
.to-top .ic{width:18px;height:18px}

/* =========================================================
   LIGHTBOX
   ========================================================= */
.lightbox{position:fixed;inset:0;z-index:200;display:none}
.lightbox.open{display:block}
.lb-overlay{position:absolute;inset:0;background:rgba(15,14,10,.7);backdrop-filter:blur(8px)}
.lb-panel{
  position:absolute;inset:5% 5%;
  background:var(--surface);border-radius:var(--r-lg);overflow:hidden;
  display:flex;flex-direction:column;border:1px solid var(--line);
  box-shadow:0 40px 80px -20px rgba(0,0,0,.4);
}
.lb-bar{
  display:flex;align-items:center;justify-content:space-between;
  padding:16px 20px;border-bottom:1px solid var(--line);
}
.lb-meta{display:flex;align-items:center;gap:10px;color:var(--ink)}
.lb-meta .ic{color:var(--hi);width:22px;height:22px}
.lb-meta span{font-family:var(--serif);font-style:italic;font-size:1.15rem;letter-spacing:-.01em}
.lb-bar-actions{display:flex;gap:6px}
.lb-grid{
  flex:1;padding:14px;overflow:auto;
  display:flex;flex-direction:column;align-items:center;
  gap:12px;
  background:var(--bg-2);
}
/* Images render at NATURAL size, capped by the container — small
   images are never upscaled (blurry + huge vertical bulk that read
   as giant gaps); large ones shrink to fit. */
.lb-grid img{
  width:auto;
  max-width:min(100%, 1400px);
  height:auto;
  object-fit:contain;
  border-radius:var(--r-sm);
  background:var(--bg);
  display:block;
}
/* Video standards:
   · Landscape video — 16:9 (max 1400px wide)
   · Reel — 9:16 (constrained so portrait reels don't dominate the screen) */
.lb-grid video{
  width:auto;
  max-width:min(100%, 1400px);
  max-height:85vh;
  height:auto;
  object-fit:contain;
  border-radius:var(--r-sm);
  background:#000;
  display:block;
}
.lb-grid video.is-portrait{
  max-width:min(440px, 92%);
  aspect-ratio:9/16;
  height:auto;
}

/* =========================================================
   TOAST
   ========================================================= */
.toast{
  position:fixed;left:50%;bottom:32px;transform:translateX(-50%) translateY(20px);
  display:inline-flex;align-items:center;gap:8px;
  padding:10px 16px;border-radius:999px;
  background:var(--ink);color:var(--bg);
  font-size:.85rem;letter-spacing:.02em;
  opacity:0;pointer-events:none;z-index:300;
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast .ic{stroke:var(--bg);width:16px;height:16px}

/* =========================================================
   REVEAL animations
   ========================================================= */
.reveal{opacity:0;transform:translateY(28px);transition:opacity .8s var(--ease) var(--d, 0s), transform .8s var(--ease) var(--d, 0s)}
.reveal.in{opacity:1;transform:translateY(0)}
.stagger > *{opacity:0;transform:translateY(18px);transition:opacity .55s var(--ease), transform .55s var(--ease)}
.stagger.in > *{opacity:1;transform:translateY(0)}
.stagger.in > *:nth-child(1){transition-delay:.04s}
.stagger.in > *:nth-child(2){transition-delay:.08s}
.stagger.in > *:nth-child(3){transition-delay:.12s}
.stagger.in > *:nth-child(4){transition-delay:.16s}
.stagger.in > *:nth-child(5){transition-delay:.20s}
.stagger.in > *:nth-child(6){transition-delay:.24s}
.stagger.in > *:nth-child(7){transition-delay:.28s}
.stagger.in > *:nth-child(8){transition-delay:.32s}
.stagger.in > *:nth-child(9){transition-delay:.36s}
.stagger.in > *:nth-child(10){transition-delay:.40s}
.stagger.in > *:nth-child(11){transition-delay:.44s}
.stagger.in > *:nth-child(12){transition-delay:.48s}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 1180px){
  .work-grid{grid-template-columns:repeat(var(--pg-cols-tablet, 4), 1fr)}
  .work-grid.is-masonry{column-count:var(--pg-cols-tablet, 4)}
}
@media (max-width: 980px){
  #nav{gap:10px;padding:8px 10px}
  .nav-dots{display:none}
  .pill-cta span{display:none}
  .pill-cta{padding:9px}
  .hero{padding:120px 0 60px}
  .hero-inner{grid-template-columns:1fr;gap:28px}
  .hero-right{order:-1}
  .portrait{width:min(70vw, 320px)}
  .hero-stats{grid-template-columns:repeat(3,1fr)}
  .about-grid{grid-template-columns:1fr}
  .tool-grid{grid-template-columns:repeat(4,1fr)}
  .svc-grid{grid-template-columns:repeat(3,1fr)}
}
@media (max-width: 700px){
  .work-grid{grid-template-columns:repeat(var(--pg-cols-mobile, 2), 1fr)}
  .work-grid.is-masonry{column-count:var(--pg-cols-mobile, 2)}
  /* Keep span variants from overflowing the narrow grid */
  .card[data-size="large"],
  .card[data-size="featured"]{ grid-column:span 2; grid-row:span 2; }
  .card[data-size="wide"]    { grid-column:span 2; }
  .card[data-size="tall"]    { grid-row:span 2; }
}
@media (max-width: 560px){
  .hero h1{font-size:clamp(3rem, 14vw, 4.6rem)}
  .tool-grid{grid-template-columns:repeat(3,1fr)}
  .svc-grid{grid-template-columns:repeat(2,1fr)}
  .about-cards{grid-template-columns:1fr}
  .hero-stats{gap:10px;padding-top:22px;margin-top:30px}
  .stat b{font-size:1.6rem}
  .tl-row{grid-template-columns:48px 1fr;padding:18px}
  .tl-mono{width:40px;height:40px;font-size:.9rem}
  .lb-panel{inset:0;border-radius:0}
  .lb-grid img, .lb-grid video{height:220px}
  .footer{flex-direction:column;text-align:center}
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce){
  *{animation:none !important;transition:none !important}
  .reveal{opacity:1;transform:none}
  /* iPhones very often ship with Reduce Motion ON — killing the ticker
     entirely made it look "broken" on iOS. Keep it moving at half speed
     instead: dramatically calmer, but the brand strip still lives. */
  .ticker-track{animation:ticker 76s linear infinite !important}
}

/* No-JS fallback — keep content visible if scripts fail */
.no-js .reveal{opacity:1;transform:none}
.no-js .stagger > *{opacity:1;transform:none}

/* =========================================================
   ACCESSIBILITY & MOBILE HARDENING
   ========================================================= */

/* Visible keyboard focus everywhere (WCAG 2.4.7) */
:focus-visible{
  outline:2px solid var(--ink);
  outline-offset:2px;
  border-radius:4px;
}
.card:focus-visible{outline-offset:4px}

/* Touch targets ≥44px on touch devices (WCAG 2.5.5) */
@media (pointer:coarse){
  .icon-btn{width:44px;height:44px}
  .chip{min-height:44px;padding:0 18px}
  .nav-dots a{padding:12px 12px}
  .soc{width:52px;height:52px}
  .to-top{width:48px;height:48px}
}

/* Phone-width nav: keep the pill from crowding */
@media (max-width: 560px){
  #nav{gap:6px;padding:8px}
  .brand{font-size:1.05rem;padding:0 4px 0 6px}
  .nav-text-btn{padding:8px 12px;font-size:.78rem}
  .pill-cta{padding:9px 12px}
  .nav-actions{gap:4px;padding-left:4px}
  .hero{padding:104px 0 56px}
  .hero h1{font-size:clamp(2.7rem, 13vw, 4.2rem)}
  .hero-stats{grid-template-columns:repeat(3,1fr)}
  .contact-actions .btn-lg{padding:14px 20px;font-size:.9rem}
}

/* iPad / tablet: comfortable hero + grids between 700–980px */
@media (min-width: 700px) and (max-width: 980px){
  .hero-inner{gap:36px}
  .portrait{width:min(44vw, 340px)}
  .tool-grid{grid-template-columns:repeat(4,1fr)}
  .svc-grid{grid-template-columns:repeat(3,1fr)}
}

/* Prevent iOS auto-zoom on focus: form controls must be ≥16px */
@media (max-width: 980px){
  input, select, textarea{font-size:16px !important}
}

/* Skip link — visible only when focused via keyboard */
.skip-link{
  position:fixed;top:-48px;left:16px;z-index:300;
  background:var(--ink);color:var(--bg);
  padding:10px 18px;border-radius:0 0 12px 12px;
  font-size:.85rem;font-weight:500;
  transition:top .2s var(--ease);
}
.skip-link:focus{top:0;outline:none}

/* =========================================================
   TOOLKIT — compact badge wall on phones
   ========================================================= */
@media (max-width: 700px){
  .tool-grid{grid-template-columns:repeat(4,1fr);gap:8px}
  .tool{padding:14px 6px 12px;gap:8px;border-radius:12px}
  .logo{width:36px;border-radius:9px}
  .logo-mono{font-size:.82rem}
  /* hover labels are unreachable on touch — drop the reserved line */
  .logo-label{display:none}
}
@media (max-width: 380px){
  .tool-grid{gap:6px}
  .logo{width:32px}
}

/* =========================================================
   WORK FILTERS — slim chips on phones
   (overrides the pointer:coarse 44px bump, which made the
    filter bar bulky; 36px + spacing still passes WCAG 2.2 AA)
   ========================================================= */
@media (max-width: 700px){
  .filters{padding:4px;gap:4px;margin-bottom:24px}
  .filters .chip,
  .chip{
    height:34px;min-height:34px;
    padding:0 13px;
    font-size:.75rem;
  }
}
@media (pointer:coarse) and (max-width: 700px){
  .chip{min-height:34px;padding:0 13px}
}

/* About: optional description paragraph (public page) */
.about-desc{
  margin:14px 0 0;font-size:1rem;line-height:1.6;color:var(--ink-2);max-width:60ch;
}

/* =========================================================
   GLOBAL AVAILABILITY STATUS BADGE
   Painted into every [data-status-badge] by js/cms/status.js.
   Color comes from --sb-color (per-status: green/teal/amber/gray).
   ========================================================= */
.status-badge{
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 12px;border-radius:999px;
  background:var(--bg-2);border:1px solid var(--line);
  font-family:var(--sans);font-size:.72rem;font-weight:500;
  letter-spacing:.06em;color:var(--ink-2);
  white-space:nowrap;vertical-align:middle;
}
.status-badge[hidden]{display:none}
.sb-dot{
  width:8px;height:8px;border-radius:50%;flex:none;
  background:var(--sb-color, #5DC57A);
  box-shadow:0 0 0 4px color-mix(in oklab, var(--sb-color, #5DC57A) 25%, transparent);
  animation:pulse 2.2s infinite;
}
/* Offline: no pulse — it reads as inactive */
.status-badge[data-mode="offline"] .sb-dot{animation:none;box-shadow:none}

/* Section-header placement (About / Selected Work) */
.sec-head .status-badge, .about-grid .status-badge{margin-left:12px}
@media (max-width:700px){
  .status-badge{font-size:.66rem;padding:5px 10px;gap:6px}
  .sec-head .status-badge, .about-grid .status-badge{margin-left:8px}
}

/* =========================================================
   CONTACT FORM (Formspree) — premium theme, responsive
   ========================================================= */
.contact-form{
  width:min(560px, 100%);
  margin:44px auto 0;
  padding:clamp(20px, 3.5vw, 32px);
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);
  display:flex;flex-direction:column;gap:16px;
  text-align:left;
}
.cf-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.cf-field{display:flex;flex-direction:column;gap:6px}
.cf-field > span{
  font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted);font-weight:500;
}
.cf-field input,
.cf-field textarea{
  background:var(--bg-2);
  border:1px solid var(--line);
  border-radius:12px;
  padding:13px 14px;
  font-family:var(--sans);font-size:16px;   /* ≥16px: no iOS zoom */
  color:var(--ink);
  outline:none;resize:vertical;
  transition:border-color .2s var(--ease), background .2s var(--ease);
}
.cf-field input:focus,
.cf-field textarea:focus{border-color:var(--ink);background:var(--surface)}
.cf-field input.invalid,
.cf-field textarea.invalid{border-color:#B45656}
.cf-field input::placeholder,
.cf-field textarea::placeholder{color:var(--muted)}

/* Honeypot — visually gone, still in the form for bots */
.cf-hp{position:absolute !important;left:-9999px;width:1px;height:1px;opacity:0}

.cf-actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:2px}
.cf-send{min-width:180px;justify-content:center}
.cf-send:disabled{opacity:.6;cursor:default;transform:none}
.cf-status{margin:0;font-size:.8rem;line-height:1.4}
.cf-status[data-kind="error"]{color:#B45656}
html[data-theme="dark"] .cf-status[data-kind="error"]{color:#E89898}

/* Success card */
.cf-success{
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:28px 16px;text-align:center;
}
.cf-success .ic{
  width:36px;height:36px;color:#3F9D5C;
  background:color-mix(in oklab, #3F9D5C 12%, transparent);
  border-radius:50%;padding:8px;box-sizing:content-box;
}
.cf-success b{
  font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:1.35rem;color:var(--ink);letter-spacing:-.01em;
}
.cf-success p{margin:0;color:var(--ink-2);font-size:.92rem}

@media (max-width: 560px){
  .cf-row{grid-template-columns:1fr}
  .contact-form{margin-top:32px}
  .cf-send{width:100%}
}

/* Hard-stop any horizontal overflow (ticker marquee etc.) —
   overflow-x:clip clips without creating a scroll container,
   so position:sticky keeps working; hidden is the fallback. */
html{overflow-x:hidden;overflow-x:clip}
.ticker{max-width:100vw}

/* =========================================================
   TIMELINE META — years + location side by side
   Years get full-contrast ink so they read clearly in both
   themes; location stays quiet. Wraps gracefully on phones.
   ========================================================= */
.tl-meta{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  justify-content:flex-end;
}
.tl-when-period{
  color:var(--ink);
  font-weight:600;
}
.tl-when-period .ic{color:var(--hi)}
@media (max-width: 560px){
  .tl-top{flex-direction:column;align-items:flex-start;gap:4px}
  .tl-meta{justify-content:flex-start;gap:10px}
}

/* Hero stats — soft entry when cards are shown/re-rendered */
@keyframes statIn{
  from{opacity:0;transform:translateY(8px)}
  to{opacity:1;transform:translateY(0)}
}
.hero-stats .stat{animation:statIn .4s var(--ease) both}
.hero-stats .stat:nth-child(2){animation-delay:.06s}
.hero-stats .stat:nth-child(3){animation-delay:.12s}

/* =========================================================
   WORK SHOWCASE — pure white empty space
   All gaps/padding around and between work images render
   white (#FFFFFF via --surface) instead of the warm beige
   paper tones. Dark theme keeps its dark surface.
   ========================================================= */
.work{background:var(--surface)}                 /* section behind the grid   */
.card{background:var(--surface)}                 /* tile placeholder area     */
.lb-panel{background:var(--surface)}             /* modal shell               */
.lb-grid{background:var(--surface)}              /* gallery scroll area       */
.lb-grid img{background:var(--surface)}          /* behind transparent PNGs   */
.lb-bar{background:var(--surface)}               /* modal header row          */
/* videos keep a black backdrop — letterbox bars are part of the
   media frame, not empty page space */

/* =========================================================
   EXPERIENCE — show-more expansion (smooth, no reload)
   Grid-rows animation: buttery height transition without
   measuring content; works on Safari 16+ / iOS 16+.
   ========================================================= */
.tl-extra{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .55s var(--ease);
}
.tl-extra.open{grid-template-rows:1fr}
.tl-extra-inner{
  overflow:hidden;
  display:flex;flex-direction:column;gap:10px;
  min-height:0;
}
.tl-extra.open .tl-extra-inner{padding-top:10px}

.exp-more-btn{
  display:flex;align-items:center;gap:10px;
  margin:22px auto 0;
  padding:12px 22px;border-radius:999px;
  background:transparent;color:var(--ink);
  border:1px solid var(--line-2);
  font-family:var(--sans);font-size:.85rem;font-weight:500;
  cursor:pointer;
  transition:background .25s var(--ease), color .25s var(--ease),
             border-color .25s var(--ease), transform .25s var(--ease);
}
.exp-more-btn:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.exp-more-btn:hover .ic{stroke:var(--bg)}
.exp-more-ic{transform:rotate(90deg);transition:transform .35s var(--ease)}
.exp-more-btn.open .exp-more-ic{transform:rotate(-90deg)}

/* Reduced motion: expansion still works, just without the slide */
@media (prefers-reduced-motion: reduce){
  .tl-extra{transition:none}
}

/* =========================================================
   PREMIUM MICRO-MOTION LAYER
   Apple/Framer-style: small, smooth, GPU-only (transform /
   opacity / filter). Theme-agnostic — inherits tokens.
   Fully disabled by the global prefers-reduced-motion block.
   ========================================================= */

/* Page entrance — one soft fade, no layout shift */
@media (prefers-reduced-motion: no-preference){
  @keyframes pageIn{from{opacity:0}to{opacity:1}}
  body{animation:pageIn .45s var(--ease) both}
}

/* 1 · Scroll reveals — add blur-to-clear to the existing fade-up */
.reveal{
  opacity:0;
  transform:translateY(22px);
  filter:blur(5px);
  transition:opacity .7s var(--ease) var(--d,0s),
             transform .7s var(--ease) var(--d,0s),
             filter .7s var(--ease) var(--d,0s);
}
.reveal.in{opacity:1;transform:none;filter:blur(0)}
.stagger > *{filter:blur(4px)}
.stagger.in > *{filter:blur(0)}
.stagger > *{transition-property:opacity,transform,filter}

/* 2 · Word-level text reveal (headings) — spans injected by main.js */
.w{
  display:inline-block;
  opacity:0;
  transform:translateY(.32em);
  filter:blur(4px);
  transition:opacity .55s var(--ease) calc(var(--wi,0)*45ms),
             transform .55s var(--ease) calc(var(--wi,0)*45ms),
             filter .55s var(--ease) calc(var(--wi,0)*45ms);
  will-change:transform,opacity;
}
.in .w, .reveal.in .w, .w.done{
  opacity:1;transform:none;filter:blur(0);
}

/* 3 · Gentle parallax — hero glow blobs + portrait drift.
      --sy is set by a rAF scroll handler (desktop, fine pointers). */
@media (pointer:fine) and (prefers-reduced-motion: no-preference){
  .hero::before{transform:translate3d(0, calc(var(--sy,0) * .10px), 0)}
  .hero::after{transform:translate3d(0, calc(var(--sy,0) * .06px), 0)}
  .hero .portrait{transform:translate3d(0, calc(var(--sy,0) * -.035px), 0)}
}

/* 4 · Hover micro-interactions */
.btn:active, .pill-cta:active, .nav-text-btn:active{transform:scale(.975)}
.icon-btn .ic, .soc .ic{transition:transform .3s var(--ease)}
.icon-btn:hover .ic{transform:scale(1.12)}
.soc:hover .ic{transform:scale(1.1)}
.fact .ic, .svc .ic{transition:transform .35s var(--ease), color .3s var(--ease)}
.fact:hover .ic{transform:translateY(-2px)}
.svc:hover .ic{transform:scale(1.12)}
.tool .logo{transition:transform .35s var(--ease)}
.tool:hover .logo{transform:scale(1.06)}
.brand span{display:inline-block;transition:transform .35s var(--ease)}
.brand:hover span{transform:translateY(-2px)}

/* 5 · Navbar — deepen on scroll */
#nav{transition:padding .35s var(--ease), top .35s var(--ease),
              box-shadow .35s var(--ease), border-color .35s var(--ease)}
#nav.scrolled{
  box-shadow:0 8px 30px -12px rgba(23,21,15,.16);
  border-color:var(--line-2);
}
html[data-theme="dark"] #nav.scrolled{box-shadow:0 8px 30px -12px rgba(0,0,0,.5)}

/* 6 · Lightbox — smooth open/close + image fade-in.
      Works with the existing .open class toggle: visibility is
      transition-delayed so the fade-out plays before hiding. */
.lightbox{
  display:block;
  visibility:hidden;
  pointer-events:none;
  transition:visibility 0s linear .32s;
}
.lightbox.open{
  visibility:visible;
  pointer-events:auto;
  transition:visibility 0s;
}
.lb-overlay{
  opacity:0;
  transition:opacity .3s var(--ease);
}
.lightbox.open .lb-overlay{opacity:1}
.lb-panel{
  opacity:0;
  transform:translateY(10px) scale(.988);
  transition:opacity .32s var(--ease), transform .32s var(--ease);
  will-change:transform,opacity;
}
.lightbox.open .lb-panel{opacity:1;transform:none}

/* Gallery media fade in as each file finishes loading */
.lb-grid img{
  opacity:0;
  transform:scale(.995);
  transition:opacity .45s var(--ease), transform .45s var(--ease);
}
.lb-grid img.ld{opacity:1;transform:none}
.lb-grid video{opacity:0;transition:opacity .45s var(--ease)}
.lb-grid video.ld{opacity:1}

/* Reduced motion — the global kill-switch already zeroes all
   animation/transition; ensure end-states are visible */
@media (prefers-reduced-motion: reduce){
  .reveal, .stagger > *{opacity:1;transform:none;filter:none}
  .w{opacity:1;transform:none;filter:none}
  .lightbox{visibility:hidden}
  .lightbox.open{visibility:visible}
  .lb-overlay, .lb-panel, .lb-grid img, .lb-grid video{opacity:1;transform:none}
}
