/* ===================================================================
   Valencia Arlin Halim — portfolio styles
   -------------------------------------------------------------------
   NAVIGATION — search for a banner (each starts with "===") to jump:
     SHARED SECTION PRIMITIVES ... .section / .section-inner / .eyebrow / .hairline
     HERO ......................... the pinned scroll hero (all .hero-* classes)
     01 · FEATURED WORK ........... #sec-work — filter tabs + bento cards
     02 · LIFE AROUND THE WORK .... #work-gallery — horizontal photo pan
     03 · OTHER WORK .............. #sec-other — two-column list
     04 · HOBBIES ................. #sec-hobbies — tessellation columns
     05 · ASK MY PORTFOLIO ........ #sec-ask — search-to-answer panel
     CONTACT ...................... #sec-contact — final reveal
     PAGE LOADER .................. #page-loader splash
     COMPONENTS RENDERED BY app.js  cards / caps / modal drawer
   Responsive overrides live in the @media blocks near the end.

   DESIGN TOKENS: colours, font families/sizes/weights, line-heights,
   letter-spacing, the page gutter, and radii all live in tokens.css and are
   referenced here via var(--…). Change a reused value there, not here.
   =================================================================== */
html,
body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-heading); /* default warm-ivory text — the dc runtime used to supply this;
                     restored so colourless headings (.hero-panel-title/.section-title/.ask-h2/.contact-h2) aren't black */
  scroll-behavior: smooth;
  overflow-x: clip;
  max-width: 100%;
}
/* The rubber-band / elastic overscroll gap is painted by the ROOT (<html>) background only —
   fixed/absolute hero layers clip to the viewport and can't reach it. The hero's top edge is the
   aperture's flat dark field, sampled at #06080e — matching the root to that EXACT colour makes the
   field read as continuing into the bounce with no visible seam. (Update this if the aperture PNG
   changes: sample the field colour just above the silhouette's crown.) */
html {
  background-color: #06080e;
}
/* shared utility classes (extracted from repeated inline styles) */
.accent {
  font-style: italic;
  color: var(--c-italic);
} /* the serif italic accent on headings (was repeated inline) */
*::-webkit-scrollbar {
  width: 10px;
}
*::-webkit-scrollbar-thumb {
  background: var(--c-surface-2);
  border-radius: 6px;
}
@keyframes driftSlow {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -720px 30px;
  }
}
@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* floating menu */
.menu-wrap {
  position: fixed;
  inset: 0;
  z-index: 44;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
.menu-wrap.open {
  pointer-events: auto;
  opacity: 1;
  visibility: visible;
}
.menu-back {
  position: absolute;
  inset: 0;
  background: rgba(8, 12, 20, 0);
  transition: background 0.4s ease;
}
.menu-wrap.open .menu-back {
  background: rgba(8, 12, 20, 0.55);
  backdrop-filter: blur(3px);
}
.menu-panel {
  position: absolute;
  top: 84px;
  right: 24px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
}
/* fixed circular hamburger, top-right (fades in past the hero — see app.js) */
.ham {
  position: fixed;
  top: 24px;
  right: 24px;
  z-index: 47;
  width: 44px;
  height: 44px;
  border-radius: var(--r-round);
  border: 1px solid var(--c-border-pill);
  background: var(--c-glass);
  backdrop-filter: blur(var(--blur));
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition:
    opacity var(--transition),
    transform var(--transition),
    visibility var(--transition);
}
.ham img {
  width: 18px;
  height: 18px;
  display: block;
}
.ham.show {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.menu-link {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  letter-spacing: 0.02em;
  color: var(--c-btn-text);
  text-decoration: none;
  cursor: pointer;
  background: transparent;
  opacity: 0;
  transform: translateY(-8px);
  transition: color var(--transition);
}
.menu-link span {
  position: relative;
  z-index: 2;
}
.menu-link::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(143, 176, 198, 0.2);
  transform: translateX(-103%);
  z-index: 1;
  transition: transform 0.35s var(--ease);
}
.menu-wrap.open .menu-link {
  animation: mIn 0.45s ease forwards;
}
.menu-wrap.open .menu-link:nth-child(1) {
  animation-delay: 0.04s;
}
.menu-wrap.open .menu-link:nth-child(2) {
  animation-delay: 0.12s;
}
.menu-wrap.open .menu-link:nth-child(3) {
  animation-delay: 0.2s;
}
.menu-wrap.open .menu-link:nth-child(4) {
  animation-delay: 0.28s;
}
.menu-wrap.open .menu-link:nth-child(5) {
  animation-delay: 0.36s;
}
@keyframes mIn {
  to {
    opacity: 1;
    transform: none;
  }
}
.menu-link:hover {
  color: var(--c-heading-hi);
}
.menu-link:hover::before {
  transform: translateX(0);
}
.mstar {
  position: relative;
  z-index: 2;
  color: var(--c-accent-deep);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-none);
  display: none;
}
.menu-link.active .mstar {
  display: inline-block;
}
/* ===================================================================
   CONTACT / FINAL REVEAL  (#sec-contact) — night-scene close with a
   curved top edge that overlaps the section above it.
   =================================================================== */
#sec-contact {
  position: relative;
  z-index: 2;
  margin-top: -6vw;
  border-top-left-radius: 50% 6vw;
  border-top-right-radius: 50% 6vw;
  min-height: 90dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--c-bg);
  overflow: hidden;
}
.contact-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 82%;
}
.contact-scrim {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    120% 90% at 50% 38%,
    rgba(10, 16, 26, 0.5) 0%,
    rgba(8, 12, 20, 0.72) 60%,
    rgba(7, 11, 18, 0.9) 100%
  );
}
#sec-contact .topo {
  opacity: 0.05;
}
.contact-inner {
  position: relative;
  text-align: center;
  max-width: 900px;
  padding: 60px 40px;
}
.contact-portrait {
  width: 150px;
  height: 150px;
  border-radius: var(--r-round);
  object-fit: cover;
  object-position: center center;
  border: 1px solid rgba(159, 192, 216, 0.3);
  margin-bottom: 34px;
  animation: breath 8s ease-in-out infinite;
}
.contact-h2 {
  font-family: var(--font-serif);
  font-weight: var(--fw-light);
  font-size: var(--fs-display-lg);
  line-height: var(--lh-heading);
  margin: 0 0 22px;
}
.contact-cursive {
  font-family: var(--font-script);
  font-style: normal;
  font-weight: var(--fw-bold);
  font-size: var(--fs-hero);
  color: var(--c-pink);
  line-height: 0.6;
}
.contact-lead {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-relaxed);
  color: var(--c-text-soft);
  max-width: 540px;
  margin: 0 auto 36px;
}
/* contact channels — each is "[icon] underlined-link".
   Desktop: all four on one centered row. Tablet/mobile (≤1024, see below):
   stacked into a single left-aligned column. */
.contact-links {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  gap: clamp(20px, 3vw, 48px);
}
.contact-link {
  display: flex;
  flex-direction: row; /* icon to the left of the text */
  align-items: center;
  gap: 14px;
  text-decoration: none;
}
.contact-ico {
  width: 22px;
  height: 22px;
  object-fit: contain;
  opacity: 0.85;
  transition: opacity var(--transition);
}
.contact-link:hover .contact-ico {
  opacity: 1;
}
/* the value doubles as the link text — underlined to read as clickable */
.contact-value {
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  letter-spacing: 0.01em;
  color: var(--c-text-bright);
  text-decoration: underline;
  text-decoration-color: rgba(159, 176, 200, 0.5);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition:
    color var(--transition),
    text-decoration-color var(--transition);
}
.contact-link:hover .contact-value {
  color: var(--c-pink);
  text-decoration-color: var(--c-pink);
}
/* tablet + mobile: stack into a column whose items are left-aligned, but the
   column itself is centered on the viewport (shrink to content, then auto-margin) */
@media (max-width: 1024px) {
  .contact-links {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
    width: max-content;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
  }
}
@keyframes breath {
  0%,
  100% {
    opacity: 0.9;
  }
  50% {
    opacity: 1;
  }
}
.topo {
  position: absolute;
  inset: -60px;
  pointer-events: none;
  background: url("assets/effects/topo.svg") repeat;
  background-size: 720px 520px;
  animation: driftSlow 90s linear infinite;
}
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 1s var(--ease),
    transform 1s var(--ease);
}
.reveal.in {
  opacity: 1;
  transform: none;
}
/* ===================================================================
   SHARED SECTION PRIMITIVES — reused by every content section below
   (Featured Work, Other Work, Hobbies, Ask, Contact). Change the look
   of all section headers in one place here.
   =================================================================== */
.section {
  position: relative;
  overflow: hidden;
  scroll-margin-top: 80px;
  background: var(--c-bg);
}
.section-inner {
  position: relative;
  max-width: 1280px;
  margin: 0 auto;
}
/* small monospace label above a section title ("01 / Selected Work") */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-eyebrow);
  color: var(--c-accent);
  text-transform: uppercase;
}
/* horizontal fade-out rule that trails an eyebrow/heading */
.hairline {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(143, 176, 198, 0.4), transparent);
}
/* header row: eyebrow + hairline sharing one baseline */
.section-head {
  display: flex;
  align-items: baseline;
  gap: 18px;
  margin-bottom: 40px;
}
/* serif section title ("Selected work.") */
.section-title {
  font-family: var(--font-serif);
  font-weight: var(--fw-light);
  font-size: var(--fs-hero);
  line-height: var(--lh-none);
  margin: 0 0 18px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: 18px;
  background: rgba(160, 176, 196, 0.08);
  border: 1px solid var(--c-border);
  font-size: var(--fs-body-sm);
  color: var(--c-text-soft);
}
.askbar {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 50px;
  padding: 0 7px 0 20px;
  border-radius: 26px;
  background: rgba(16, 22, 34, 0.7);
  border: 1px solid rgba(160, 176, 196, 0.2);
  cursor: pointer;
  transition:
    border-color var(--transition),
    background var(--transition),
    transform var(--transition);
}
.askbar:hover {
  border-color: rgba(143, 176, 198, 0.55);
  background: rgba(20, 28, 42, 0.85);
  transform: translateY(-2px);
}
.tab {
  font-size: var(--fs-body-sm);
  letter-spacing: 0.01em;
  color: var(--c-muted);
  padding: 8px 2px;
  cursor: pointer;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
  transition: 0.25s;
}
/* ===================================================================
   01 · FEATURED WORK  (#sec-work) — filter tabs + bento card grid
   =================================================================== */
#sec-work {
  padding: 120px var(--gutter);
}
#sec-work > .topo {
  opacity: 0.16;
}
/* header: title block on the left, room to grow on the right */
.work-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 40px;
  flex-wrap: wrap;
}
.work-head-main {
  flex: 1;
  min-width: 300px;
}
.work-head .eyebrow {
  margin-bottom: 16px;
}
.work-sub {
  font-family: var(--font-serif);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  color: var(--c-text-soft);
  margin: 0;
  max-width: 440px;
}
/* soft italic emphasis inside body copy ("meaningful") — reused in Ask/Contact */
.em-soft {
  font-style: italic;
  color: var(--c-text);
}
.dash-tabs {
  display: flex;
  gap: 24px;
  border-bottom: 1px solid var(--c-border-line);
  margin-bottom: 30px;
  padding-top: 30px;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.dash-tabs::-webkit-scrollbar {
  display: none;
  height: 0;
}
.dash-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 18px;
}
.tab:hover {
  color: var(--c-btn-text);
}
.hero-nav-link {
  color: var(--c-text-soft);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--transition);
}
.hero-nav-link:hover {
  color: var(--c-heading-hi);
}
/* pill & icon buttons (hero résumé, icon circles, top button) share one
   interaction: a base transition + a fill/border/lift on hover. Defined once
   here; the individual boxes (padding, radius, glass) differ below. */
.hero-resume,
.icirc,
.topbtn,
.ask-reset {
  transition:
    background var(--transition),
    border-color var(--transition),
    color var(--transition),
    transform var(--transition);
}
.hero-resume:hover,
.icirc:hover,
.topbtn:hover,
.ask-reset:hover {
  background: var(--c-hover-fill) !important;
  border-color: var(--c-hover-border) !important;
  color: var(--c-heading-hi);
}
.hero-resume:hover,
.icirc:hover,
.ask-reset:hover {
  transform: translateY(-2px);
}
.hero-resume {
  padding: 8px 16px;
  border: 1px solid rgba(170, 180, 196, 0.32);
  border-radius: 20px;
  color: var(--c-btn-text);
  cursor: pointer;
}
/* fixed "↑ Top" pill, bottom-center */
.topbtn {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 45;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 18px;
  border-radius: 22px;
  border: 1px solid var(--c-border-pill);
  background: var(--c-glass);
  backdrop-filter: blur(var(--blur));
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-label);
  color: var(--c-text);
  text-transform: uppercase;
}
/* keeps the centering translateX while adding the shared lift */
.topbtn:hover {
  transform: translateX(-50%) translateY(-2px) !important;
}
.tab.on {
  color: var(--c-heading);
  border-color: var(--c-accent);
}
/* ===================================================================
   03 · OTHER WORK  (#sec-other) — two-column list of secondary projects
   =================================================================== */
#sec-other {
  padding: 110px var(--gutter);
  background: var(--c-bg-alt);
}
.other-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0 clamp(40px, 5vw, 96px);
}
/* rows built by app.js renderOther() */
.other-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 22px 0;
  border-top: 1px solid var(--c-border-line);
  cursor: pointer;
  transition:
    background var(--transition),
    padding-left var(--transition);
}
.other-row:hover {
  background: rgba(143, 176, 198, 0.06);
  padding-left: 12px;
}
.other-name {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  color: var(--c-name);
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.other-arrow {
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  color: var(--c-accent);
  opacity: 0;
  transition:
    opacity var(--transition),
    transform var(--transition);
}
.other-kind {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  color: var(--c-muted);
  letter-spacing: 0.08em;
  white-space: nowrap;
}
/* ===================================================================
   05 · ASK MY PORTFOLIO  (#sec-ask) — centered search-to-answer panel
   =================================================================== */
#sec-ask {
  position: relative;
  padding: 230px var(--gutter);
  background: var(--c-bg-alt);
}
.ask-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
#sec-ask .topo {
  opacity: 0.2;
}
.ask-inner {
  position: relative;
  max-width: 820px;
  margin: 0 auto;
  text-align: center;
}
#sec-ask .eyebrow {
  margin-bottom: 22px;
}
.ask-h2 {
  font-family: var(--font-serif);
  font-weight: var(--fw-light);
  font-size: var(--fs-display-lg);
  line-height: 1.14;
  margin: 0 0 38px;
}
.ask-icon {
  width: 20px;
  height: 20px;
  flex: none;
}
/* the large search bar in this section (vs. the compact hero one) */
.ask-wrap .askbar {
  width: 100%;
  height: 58px;
  padding: 0 12px 0 22px;
  box-sizing: border-box;
  border: 1px solid rgba(143, 176, 198, 0.34);
}
.ask-wrap {
  position: relative;
  max-width: 620px;
  margin: 0 auto;
  text-align: left;
}
.ask-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  color: var(--c-heading);
}
.ask-input::placeholder {
  color: var(--c-placeholder);
}
.ask-send {
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: var(--r-round);
  border: none;
  background: rgba(159, 192, 216, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-text-bright);
  cursor: pointer;
  transition:
    background var(--transition),
    transform var(--transition);
}
.ask-send:hover {
  background: rgba(159, 192, 216, 0.34);
  transform: translateY(-1px);
}
.ask-suggest {
  position: absolute;
  left: 0;
  right: 0;
  top: 66px;
  z-index: 20;
  background: var(--c-surface-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  padding: 8px;
  box-shadow: 0 18px 50px rgba(4, 8, 16, 0.6);
  animation: fadeUp var(--transition);
}
.ask-sg {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 11px 13px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--c-text);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  cursor: pointer;
  transition: background var(--transition);
}
.ask-sg:hover {
  background: rgba(143, 176, 198, 0.12);
  color: var(--c-heading);
}
.ask-sg-ic {
  color: var(--c-accent);
  font-size: var(--fs-body);
}
.ask-thread {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
@keyframes askPulse {
  0%,
  100% {
    opacity: 0.25;
    transform: translateY(0);
  }
  50% {
    opacity: 1;
    transform: translateY(-3px);
  }
}
/* ===================================================================
   PAGE LOADER — full-screen splash shown until assets are ready
   (app.js adds .hidden to fade it out). Dots use .transit-dots below.
   =================================================================== */
#page-loader {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  background: var(--c-bg);
  transition:
    opacity 0.7s ease,
    visibility 0.7s ease;
}
.loader-mark {
  font-family: var(--font-serif);
  font-size: var(--fs-display);
  letter-spacing: var(--ls-caps);
  color: var(--c-white);
}
.loader-text {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-eyebrow);
  color: var(--c-accent);
  text-transform: uppercase;
}
#page-loader.hidden {
  opacity: 0;
  visibility: hidden;
}
.hero-askbar {
  margin-top: 24px;
  max-width: 320px;
  position: relative;
  z-index: 30;
  cursor: pointer;
  outline: none;
}
.transit {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  background: rgba(8, 12, 20, 0.86);
  backdrop-filter: blur(var(--blur));
  animation: fadeUp var(--transition);
}
.transit-txt {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-title);
  color: var(--c-white);
}
.transit-dots span {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin: 0 3px;
  border-radius: var(--r-round);
  background: var(--c-accent);
  animation: askPulse 1.1s ease-in-out infinite;
}
.transit-dots span:nth-child(2) {
  animation-delay: 0.18s;
}
.transit-dots span:nth-child(3) {
  animation-delay: 0.36s;
}
.ask-reset {
  margin-top: 16px;
  padding: 8px 16px;
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-tag);
  color: var(--c-btn-text);
  text-transform: uppercase;
  cursor: pointer;
  background: none;
  border: 1px solid var(--c-border-pill);
  border-radius: 20px;
}
/* fuzzy-search result cards (Ask my portfolio) */
@keyframes askFade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.ask-card {
  display: flex;
  align-items: center;
  gap: 18px;
  width: 100%;
  text-align: left;
  padding: 16px 18px;
  border-radius: var(--r-md);
  cursor: pointer;
  background: var(--c-searchbar);
  border: 1px solid var(--c-border-soft);
  transition:
    transform 0.3s var(--ease),
    opacity var(--transition),
    border-color 0.3s,
    background 0.3s;
}
.ask-card:hover {
  transform: translateY(-2px);
  border-color: rgba(143, 176, 198, 0.45);
  background: var(--c-searchbar-hover);
}
.ask-card-thumb {
  flex: none;
  width: 76px;
  height: 76px;
  border-radius: var(--r-sm);
  background-size: cover;
  background-position: center;
  background-color: var(--c-surface-2);
  border: 1px solid var(--c-border-softer);
}
.ask-card-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.ask-card-title {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  color: var(--c-heading);
  line-height: var(--lh-heading);
}
.ask-card-desc {
  font-size: var(--fs-body);
  color: var(--c-text-soft);
  line-height: 1.45;
}
.ask-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}
/* squarish highlight — the same fill the menu links use (rgba(143,176,198,.2)), but
   always present rather than wiping in on hover. No pill radius, no outline. */
.ask-tag {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-tight);
  color: var(--c-btn-text);
  padding: 3px 9px;
  border-radius: 3px;
  background: rgba(143, 176, 198, 0.2);
}
.ask-card-arrow {
  flex: none;
  color: var(--c-accent);
  font-size: var(--fs-title);
  line-height: var(--lh-none);
  transition:
    transform 0.3s,
    color 0.3s;
}
.ask-card:hover .ask-card-arrow {
  color: var(--c-white);
  transform: translateX(3px);
}
/* empty state (no matches) */
.ask-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 44px 20px 30px;
  animation: askFade var(--transition) both;
}
.ask-empty-img {
  width: 116px;
  height: auto;
  opacity: 0.85;
  margin-bottom: 22px;
}
.ask-empty-title {
  font-family: var(--font-serif);
  font-size: var(--fs-title);
  color: var(--c-name);
}
.ask-empty-sub {
  font-size: var(--fs-body);
  color: var(--c-muted);
  margin-top: 8px;
}
.other-row:hover .other-arrow {
  opacity: 1;
  transform: translateX(3px);
}
/* ===================================================================
   COMPONENTS RENDERED BY app.js — capabilities list, project cards,
   and the project modal drawer. (Markup lives in the app.js render and
   openProject functions; only truly dynamic bits — image URLs, --accent,
   grid span — stay inline there.)
   =================================================================== */
/* capabilities list (Skillsets, renderCaps) */
.caprow {
  display: flex;
  gap: 24px;
  align-items: baseline;
  padding: 20px 0;
  border-top: 1px solid var(--c-border);
}
.cap-num {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-muted);
}
.cap-body {
  flex: 1;
}
.captitle {
  font-family: var(--font-serif);
  font-size: var(--fs-title);
  color: var(--c-heading);
  line-height: 1.12;
}
.cap-tools {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  color: var(--c-accent);
  letter-spacing: 0.06em;
  margin-top: 7px;
}
/* project modal (openProject) — large centered panel: media left, details right.
   Occupies ~85% of the screen. See the ≤860px block for the stacked mobile variant. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}
.modal-back {
  position: absolute;
  inset: 0;
  background: rgba(6, 9, 15, 0.72);
  backdrop-filter: blur(3px);
}
.modal-panel {
  position: relative; /* holds the pinned close button; the scroll area fills it */
  width: 85vw;
  max-width: 1180px; /* caps the detail column's reading width on large monitors */
  height: 85vh;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-tile);
  overflow: hidden;
  box-shadow: 0 40px 100px -20px var(--c-shadow);
  animation: fadeUp 0.4s ease;
}
/* Two panes that scroll INDEPENDENTLY: the words stay put on the left while the pictures
   scroll on the right. Single-column media so images of any aspect ratio stack cleanly with
   even spacing — no ragged grid gaps, and the text is always in view (no dead whitespace). */
.modal-scrollarea {
  display: flex;
  height: 100%;
}
/* ---- LEFT: detail pane (words) ---- */
.mp-detail {
  flex: 0 0 46%;
  min-width: 0;
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  box-sizing: border-box;
  padding: 2.125em 1.75em 2.5em 2.125em;
}
/* ---- RIGHT: media pane — one full-width column, aspect ratios kept (never cropped) ---- */
.mp-media {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  box-sizing: border-box;
  padding: 2.125em 2.125em 1.25em;
}
.mp-hero,
.mp-shot {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 0 0.9em;
  background: none;
  border-radius: var(--r-tile);
}
.mp-hero:last-child,
.mp-shot:last-child {
  margin-bottom: 0;
}
video.mp-hero,
video.mp-shot {
  background: #000;
  object-fit: contain;
}
/* a hairline between the panes + always-visible scrollbars make the two independent
   scroll columns legible (the global overlay thumb is near-invisible on this surface). */
.mp-media {
  border-left: 1px solid var(--c-border-line);
}
.mp-detail,
.mp-media {
  scrollbar-width: thin;
  scrollbar-color: rgba(159, 192, 216, 0.5) transparent; /* Firefox: thumb / track */
}
.mp-detail::-webkit-scrollbar,
.mp-media::-webkit-scrollbar {
  width: 12px;
}
.mp-detail::-webkit-scrollbar-track,
.mp-media::-webkit-scrollbar-track {
  background: transparent;
}
.mp-detail::-webkit-scrollbar-thumb,
.mp-media::-webkit-scrollbar-thumb {
  background: rgba(159, 192, 216, 0.55);
  border-radius: 8px;
  border: 2px solid var(--c-surface); /* inset padding so the thumb reads as a pill */
  background-clip: padding-box;
}
.mp-detail::-webkit-scrollbar-thumb:hover,
.mp-media::-webkit-scrollbar-thumb:hover {
  background: rgba(159, 192, 216, 0.78);
  background-clip: padding-box;
}

.mp-cat {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-tag);
  color: var(--c-accent);
  text-transform: uppercase;
  margin-bottom: 1.1em;
}
.mp-title {
  font-family: var(--font-serif);
  font-weight: var(--fw-regular);
  font-size: var(--fs-display);
  line-height: var(--lh-heading-tight);
  margin: 0 0 0.45em;
}
/* meta rows: [icon] [label + content] */
.mp-rows {
  display: flex;
  flex-direction: column;
  margin-top: 1.4em;
  border-top: 1px solid var(--c-border-line);
}
.mp-row {
  display: grid;
  grid-template-columns: 2.125em 1fr;
  gap: 1em;
  padding: 1.15em 0;
  border-bottom: 1px solid var(--c-border-line);
}
.mp-row:last-child {
  border-bottom: 0;
}
/* header icon (assets/icons/<label>.png) */
.mp-ic {
  width: 1.5em;
  height: 1.5em;
  object-fit: contain;
  display: block;
  margin-top: 0.1em;
}
.mp-row-label {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-meta);
  color: var(--c-accent);
  text-transform: uppercase;
  margin-bottom: 0.55em;
}
.mp-row-text {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text);
}
.mp-bullets {
  margin: 0;
  padding-left: 1.1em;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text);
}
.mp-bullets li {
  margin-bottom: 0.2em;
}
.mp-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2em 2em;
}
.mp-metric-val {
  font-family: var(--font-serif);
  font-size: var(--fs-title);
  color: var(--c-pink);
  line-height: var(--lh-heading);
}
/* label uses the SAME body text as every other row — no bespoke caption size */
.mp-metric-label {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text);
  margin-top: 0.35em;
}
/* floating close — frosted glass; reuses the site's .icirc hover (fill + lift) */
.modal-close {
  position: absolute;
  top: 1.1em;
  right: 1.1em;
  z-index: 5;
  width: 2.5em;
  height: 2.5em;
  padding: 0;
  -webkit-appearance: none;
  appearance: none;
  border-radius: var(--r-round);
  background: var(--c-glass);
  border: 1px solid var(--c-border-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(var(--blur));
}
.modal-close img {
  width: 0.9375em;
  height: 0.9375em;
  display: block;
}
/* mobile/tablet: full-screen, single column — pictures first, then words */
@media (max-width: 860px) {
  .modal-panel {
    width: 100%;
    height: 100%;
    border: none;
    border-radius: 0;
    box-shadow: none;
  }
  /* stack the two panes and let the whole modal scroll as one — words, then pictures */
  .modal-scrollarea {
    flex-direction: column;
    overflow-y: auto;
  }
  .mp-detail {
    flex: none;
    width: auto;
    height: auto;
    overflow: visible;
    padding: 1.75em 1.25em 1.5em;
  }
  .mp-media {
    flex: none;
    height: auto;
    overflow: visible;
    border-left: 0;
    padding: 0.5em 1.25em 1.25em;
  }
}
.pcard {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 236px;
  padding: 26px;
  border-radius: var(--r-tile);
  overflow: hidden;
  cursor: pointer;
  border: 1px solid var(--c-border-soft);
  background: linear-gradient(160deg, var(--c-surface-2), var(--c-card-stop));
  transition:
    transform 0.45s var(--ease),
    border-color 0.35s,
    box-shadow 0.45s;
}
.pcard.feature {
  min-height: 308px;
}
.pcard:hover {
  transform: translateY(-6px);
  border-color: rgba(143, 176, 198, 0.5);
  box-shadow: 0 26px 60px -28px rgba(3, 6, 12, 0.85);
}
.pcard:focus-visible {
  outline: 1px solid var(--c-hover-border);
  outline-offset: 3px;
}
/* layered backdrop: photo -> left-to-right legibility scrim (one shade for all cards) */
.pcard-img {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: 78% center;
  background-repeat: no-repeat;
  transition: transform 0.6s var(--ease);
  will-change: transform;
}
.pcard:hover .pcard-img {
  transform: scale(1.05);
}
.pcard-shade {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(
    to right,
    rgba(6, 9, 15, 1) 0%,
    rgba(6, 9, 15, 0.80) 58%,
    /* rgba(6, 9, 15, 0.62) 70%, */
    rgba(6, 9, 15, 0.6) 95%
  );
}
/* no-image cards: hide the photo, show a blurred accent glow top-right */
.pcard-glow {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(
    150px 150px at 86% 14%,
    var(--accent, var(--c-accent)),
    transparent 68%
  );
  opacity: 0.5;
  filter: blur(22px);
}
.pcard-body {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  flex: 1;
  width: 100%;
  box-sizing: border-box;
}
.pcard-cat {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-accent);
  text-shadow: 0 1px 8px var(--c-shadow-soft);
}
.pcard-title {
  font-family: var(--font-serif);
  font-weight: var(--fw-regular);
  font-size: var(--fs-title);
  line-height: var(--lh-heading-tight);
  color: var(--c-heading);
  margin: 14px 0 9px;
  max-width: 80%;
}
.pcard.feature .pcard-title {
  font-size: var(--fs-display); /* bigger type is the feature card's visual cue; width stays 62% (inherited) */
}
.pcard-company {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-tag);
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 6px 0 4px;
}
.pcard-desc {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text-soft);
  max-width: 80%;
  margin: 0;
}
.pcard-foot {
  margin-top: auto;
  padding-top: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.pcard-metric {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-tight);
  line-height: 1.4;
  color: var(--c-italic);
  max-width: 62%;
}
.pcard-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: var(--r-round);
  border: 1px solid rgba(170, 184, 204, 0.42);
  color: var(--c-text);
  font-size: var(--fs-body);
  opacity: 0; /* revealed on hover/focus only — keeps the resting card quiet */
  transform: translateY(6px);
  transition:
    opacity 0.35s var(--ease),
    background 0.35s,
    color 0.35s,
    border-color 0.35s,
    transform 0.35s;
}
.pcard:hover .pcard-arrow,
.pcard:focus-visible .pcard-arrow {
  opacity: 1;
  background: var(--c-hover-fill);
  border-color: var(--c-hover-border);
  transform: translateY(0);
}
/* "click a project" annotation */
.hero-flow {
  position: absolute;
  inset: -90px;
  pointer-events: none;
  background: url("assets/effects/flow1.svg") repeat;
  background-size: 640px 440px;
  opacity: 0.1;
  animation: driftSlow 64s linear infinite reverse;
}
.hero-flow-2 {
  position: absolute;
  inset: -90px;
  pointer-events: none;
  background: url("assets/effects/flow2.svg") repeat;
  background-size: 860px 520px;
  opacity: 0.07;
  animation: driftSlow 98s linear infinite;
}
/* contour curves live INSIDE .hero-aperture-wrap and are masked by the aperture, so they show only in the
     dark field around the silhouette (behind it) and never paint across the figure/mountain window */
.sh-flowfront {
  position: absolute;
  top: 0;
  left: 0;
  width: 230.2vh;
  height: 248.4vh;
  z-index: 1;
  pointer-events: none;
  background: url("assets/effects/topo.svg") repeat;
  background-size: 760px 540px;
  opacity: 0.16;
  animation: driftSlow 80s linear infinite;
  transform-origin: 48.5% 58.6%;
  -webkit-mask: url("assets/effects/hero-aperture.webp") center/100% 100% no-repeat;
  mask: url("assets/effects/hero-aperture.webp") center/100% 100% no-repeat;
}
.sh-flowfront2 {
  position: absolute;
  top: 0;
  left: 0;
  width: 230.2vh;
  height: 248.4vh;
  z-index: 1;
  pointer-events: none;
  background: url("assets/effects/flow1.svg") repeat;
  background-size: 640px 440px;
  opacity: 0.1;
  animation: driftSlow 58s linear infinite reverse;
  transform-origin: 48.5% 58.6%;
  -webkit-mask: url("assets/effects/hero-aperture.webp") center/100% 100% no-repeat;
  mask: url("assets/effects/hero-aperture.webp") center/100% 100% no-repeat;
}
.hero-tagline {
  display: none;
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.42;
  color: var(--c-text-bright);
  margin-top: 20px;
  max-width: 340px;
}

/* ===================================================================
   HERO — base styles (moved out of inline style="" attributes in index.html).
   Responsive overrides for these classes live in the @media blocks below and
   win via source order / !important, so rendering is unchanged.
   =================================================================== */
#scroll-hero {
  position: relative;
  height: 225vh;
  background: var(--c-bg);
}
.hero-stage {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
  background: radial-gradient(120% 120% at 60% 48%, var(--c-hero-glow) 0%, var(--c-surface) 52%, var(--c-bg) 100%);
}
.hero-stage > .topo {
  opacity: 0.2;
}
.hero-stars {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.hero-mountain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 44%;
  z-index: 0;
  filter: saturate(1.18) contrast(1.08) brightness(1.06);
  opacity: 0;
  transition: opacity var(--transition);
}
.hero-mountain-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  background: linear-gradient(
    180deg,
    rgba(8, 12, 20, 0.22),
    rgba(8, 12, 20, 0.05) 45%,
    rgba(8, 12, 20, 0.32)
  );
}
.hero-aperture-wrap {
  position: absolute;
  top: -88vh;
  left: 50%;
  transform: translateX(calc(-50% + 22px));
  z-index: 2;
}
.hero-aperture {
  display: block;
  height: 248.4vh;
  transform-origin: 48.5% 59.7%;
  will-change: transform;
}
.hero-nav {
  position: fixed;
  top: 30px;
  inset-inline: var(--gutter);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 40;
}
.hero-logo {
  font-family: var(--font-serif);
  font-size: var(--fs-title);
  letter-spacing: var(--ls-label);
  color: var(--c-white);
}
.hero-nav-links {
  display: flex;
  align-items: center;
  gap: 30px;
  font-size: var(--fs-body);
  color: var(--c-text-soft);
}
.hero-intro {
  position: absolute;
  left: 122px;
  top: 22vh;
  max-width: 540px;
  z-index: 5;
  will-change: opacity, transform;
}
.hero-name {
  font-family: var(--font-serif);
  font-weight: var(--fw-regular);
  font-size: var(--fs-hero);
  line-height: var(--lh-none);
  margin: 0;
  color: var(--c-heading);
  text-shadow: var(--shadow-heading);
}
.hero-role {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: 0.26em;
  color: var(--c-accent);
  text-transform: uppercase;
  margin-top: 12px;
}
.hero-tagline-script {
  font-family: var(--font-script);
  font-weight: var(--fw-bold);
  font-size: var(--fs-display);
  color: var(--c-pink);
}
.hero-search-icon {
  width: 18px;
  height: 18px;
  flex: none;
}
.hero-askbar .ask-input {
  font-size: var(--fs-body-sm);
}
.hero-askbar .ask-suggest {
  top: 60px;
}
#hero-ask-send {
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: var(--r-round);
  background: rgba(159, 192, 216, 0.16);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-text-bright);
  cursor: pointer;
}
.hero-chips {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 20px;
  font-size: var(--fs-body);
  color: var(--c-text-bright);
  width: max-content;
  white-space: nowrap;
}
.hero-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--c-text-bright);
}
.hero-chip-star {
  color: var(--c-text-bright);
  font-size: var(--fs-body);
  line-height: var(--lh-none);
}
.hero-caption {
  position: absolute;
  right: 122px;
  bottom: 130px;
  max-width: 480px;
  text-align: right;
  z-index: 5;
  will-change: opacity, transform;
}
.hero-caption-text {
  font-family: var(--font-serif);
  font-size: var(--fs-display);
  line-height: var(--lh-snug);
  color: var(--c-white);
  text-shadow: var(--shadow-heading);
}
.hero-caption-script {
  font-family: var(--font-script);
  font-weight: var(--fw-bold);
  font-size: var(--fs-hero);
  color: var(--c-pink);
  line-height: var(--lh-none);
  font-style: normal;
}
.hero-panel {
  position: absolute;
  inset: 0;
  z-index: 4;
  opacity: 0;
  pointer-events: none;
}
.hero-panel-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(8, 12, 20, 0.82) 0%,
    rgba(9, 14, 24, 0.62) 40%,
    rgba(7, 11, 18, 0.95) 100%
  );
}
.hero-panel-intro {
  position: absolute;
  left: max(var(--gutter), calc(50vw - 640px));
  top: 20vh;
  max-width: 600px;
}
.hero-panel-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-eyebrow);
  color: var(--c-accent);
  text-transform: uppercase;
}
.hero-panel-title {
  font-family: var(--font-serif);
  font-weight: var(--fw-regular);
  font-size: var(--fs-hero);
  line-height: var(--lh-heading-tight);
  margin: 14px 0 0;
  letter-spacing: -0.01em;
}
.hero-panel-cue {
  margin-top: 30px;
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-caps);
  color: var(--c-accent);
  text-transform: uppercase;
}
.hero-panel-skills {
  position: absolute;
  right: max(var(--gutter), calc(50vw - 640px));
  top: 20vh;
  width: 600px;
  max-width: 48vw;
}
.hero-panel-skills .hero-panel-eyebrow {
  margin-bottom: 10px;
}
.hero-scrollcue {
  position: absolute;
  right: 34px;
  bottom: 34px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.hero-scrollcue-line {
  width: 1px;
  height: 46px;
  background: linear-gradient(var(--c-cyan), transparent);
}
.hero-scrollcue-label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-label);
  color: var(--c-muted);
  writing-mode: vertical-rl;
}
/* The hero panel's two 600px columns only fit side by side above ~1340px. Between
   there and the 1024px tablet reflow they overlap (the title runs into the skillsets
   column), so stack the skillsets under the intro across that gap. */
@media (min-width: 1025px) and (max-width: 1340px) {
  .hero-panel-intro {
    left: var(--gutter);
    right: var(--gutter);
    top: 15vh;
    max-width: none;
  }
  .hero-panel-skills {
    left: var(--gutter);
    right: var(--gutter);
    top: 41vh;
    bottom: var(--space-40);
    width: auto;
    max-width: none;
    overflow-y: auto;
    padding-right: var(--space-12);
  }
  .caprow {
    padding: 14px 0;
  }
  .captitle {
    font-size: var(--fs-lead);
  }
}
@media (max-width: 1024px) {
  .hero-caption {
    display: none !important;
  }
  .hero-tagline {
    display: block !important;
  }
}
/* ---------- responsive: tablet ---------- */
@media (max-width: 1024px) {
  .hero-panel-intro {
    left: 48px !important;
    right: 48px !important;
    top: 13vh !important;
    max-width: none !important;
  }
  .hero-panel-title {
    font-size: var(--fs-display-lg) !important;
  }
  .hero-panel-skills {
    position: absolute !important;
    left: var(--space-48) !important;
    right: var(--space-48) !important;
    top: 38vh !important;
    bottom: var(--space-40) !important;
    width: auto !important;
    max-width: none !important;
    overflow-y: auto !important;
    padding-right: 8px !important;
  }
  .caprow {
    padding: var(--space-12) 0 !important;
  }
  .captitle {
    font-size: var(--fs-lead) !important;
  }
  .dash-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
  .hero-intro {
    text-shadow:
      0 2px 16px rgba(6, 10, 18, 0.95),
      0 1px 5px rgba(6, 10, 18, 0.9);
  }
  .hero-intro .hero-name,
  .hero-intro h1 {
    text-shadow:
      0 2px 22px rgba(6, 10, 18, 0.96),
      0 1px 6px rgba(6, 10, 18, 0.9);
  }
  /* hero: use the mobile treatment — centered text, smaller + lower silhouette, legible */
  .hero-intro {
    left: 40px !important;
    right: 40px !important;
    max-width: none !important;
    top: 16vh !important;
    text-align: center !important;
  }
  .hero-intro .askbar {
    margin-left: auto !important;
    margin-right: auto !important;
  }
  .hero-intro .hero-tagline {
    margin-left: auto !important;
    margin-right: auto !important;
    max-width: none !important;
  }
  .hero-chips {
    justify-content: center !important;
    width: auto !important;
    white-space: normal !important;
    flex-wrap: wrap !important;
    gap: 9px 18px !important;
    position: relative;
    z-index: 5;
  }
  .hero-aperture-wrap {
    top: -34vh !important;
  }
  .hero-aperture {
    height: 177vh !important;
  }
  .hero-sparks,
  .sh-flowfront,
  .sh-flowfront2 {
    width: 164.0vh !important;
    height: 177vh !important;
  }
  /* full-bleed cover (no box) — removes the top edge that read as a hard "cut" across the crown */
  .hero-mountain {
    position: absolute !important;
    inset: 0 !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 100% !important;
    transform: none !important;
    object-position: center 59% !important;
  }
}
/* ---------- responsive: mobile ---------- */
@media (max-width: 680px) {
  .hero-nav {
    left: 18px !important;
    right: 18px !important;
    top: 20px !important;
  }
  .hero-nav-links {
    gap: 13px !important;
    font-size: var(--fs-xs) !important;
  }
  .hero-resume {
    padding: 6px 11px !important;
  }
  .hero-intro {
    left: 20px !important;
    right: 20px !important;
    max-width: none !important;
    top: 17vh !important;
    text-align: center !important;
    text-shadow:
      0 1px 12px var(--c-shadow),
      0 0 4px rgba(4, 8, 16, 0.8);
  }
  .hero-intro .askbar {
    margin-left: auto !important;
    margin-right: auto !important;
  }
  .hero-intro .hero-tagline {
    margin-left: auto !important;
    margin-right: auto !important;
    max-width: none !important;
  }
  .hero-chips {
    justify-content: center !important;
  }
  .hero-name {
    font-size: var(--fs-display-lg) !important;
  }
  .hero-chips {
    width: auto !important;
    white-space: normal !important;
    flex-wrap: wrap !important;
    gap: 9px 14px !important;
  }
  .hero-panel-intro {
    left: 20px !important;
    right: 20px !important;
    top: 11vh !important;
    max-width: none !important;
  }
  .hero-panel-title {
    font-size: var(--fs-title) !important;
  }
  .hero-panel-skills {
    position: absolute !important;
    left: 20px !important;
    right: 20px !important;
    top: 39vh !important;
    width: auto !important;
    max-width: none !important;
  }
  .caprow {
    padding: 11px 0 !important;
    gap: 16px !important;
  }
  .captitle {
    font-size: var(--fs-body-lg) !important;
  }
  /* Featured Work → single-column list; each tile hugs its content, floored at 200px */
  .dash-grid {
    grid-template-columns: 1fr !important;
    grid-auto-rows: auto !important; /* rows size to content, not a fixed height */
    gap: 12px !important;
  }
  .pcard,
  .pcard.feature {
    grid-column: auto !important; /* cancel the desktop 2-/4-col spans */
    min-height: 200px !important; /* floor; grows to fit taller content */
  }
  /* no feature treatment on mobile — every tile is identical (feature only reads as
     "feature" on tablet/desktop where its wider span is visible) */
  .pcard.feature .pcard-title {
    font-size: var(--fs-title) !important;
  }
  .pcard-desc {
    max-width: 78% !important; /* a touch wider so summaries wrap less */
  }
  .other-grid {
    grid-template-columns: 1fr !important;
    gap: 0 !important;
  }
  .ask-h2 {
    font-size: var(--fs-display) !important;
  }
  .dash-tabs {
    flex-wrap: wrap !important;
    gap: 8px !important;
    border-bottom: none !important;
    overflow: visible !important;
    margin-bottom: 26px !important;
  }
  .dash-tabs .tab {
    border: 1px solid rgba(160, 176, 196, 0.26) !important;
    border-radius: 18px !important;
    padding: 7px 13px !important;
    font-size: var(--fs-xs) !important;
  }
  .dash-tabs .tab.on {
    background: rgba(143, 176, 198, 0.18) !important;
    border-color: rgba(143, 176, 198, 0.6) !important;
    color: var(--c-heading) !important;
  }
  .contact-h2 {
    font-size: var(--fs-display) !important;
  }
  .contact-cursive {
    font-size: var(--fs-hero) !important;
  }
  #sec-work,
  #sec-other {
    padding: 80px 20px !important;
  }
  section[data-screen-label="Ask my portfolio"] {
    padding: 72px 20px !important;
  }
  #sec-hobbies > div,
  .cw-cols {
    padding-left: 20px !important;
    padding-right: 20px !important;
  }
  /* hero: drop the silhouette lower so the body bleeds off the bottom (no outline), and lift text legibility */
  .hero-aperture-wrap {
    top: -17vh !important;
  }
  .hero-aperture {
    height: 156vh !important;
  }
  .hero-sparks,
  .sh-flowfront,
  .sh-flowfront2 {
    width: 144.5vh !important;
    height: 156vh !important;
  }
  /* full-bleed cover (no box) — removes the top edge that read as a hard "cut" across the crown */
  .hero-mountain {
    position: absolute !important;
    inset: 0 !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 100% !important;
    transform: none !important;
    object-position: center 59% !important;
  }
  .hero-chips {
    position: relative;
    z-index: 5;
  }
  .hero-intro {
    text-shadow:
      0 1px 12px var(--c-shadow),
      0 0 4px rgba(4, 8, 16, 0.8);
  }
  .hero-chips {
    row-gap: 8px !important;
  }
  /* selected-work gallery: convert horizontal pan to vertical stack */
  #work-gallery {
    height: auto !important;
  }
  .wg-stage {
    position: relative !important;
    height: auto !important;
    overflow: visible !important;
  }
  .wg-track {
    position: relative !important;
    flex-direction: column !important;
    height: auto !important;
    transform: none !important;
    gap: 26px !important;
    padding: 72px 20px 56px !important;
    align-items: stretch !important;
  }
  .wg-item {
    width: 88% !important;
    height: auto !important;
    margin: 0 !important;
    align-self: center !important;
  }
  .wg-frame {
    height: 62vw !important;
    flex: none !important;
  }
  .wg-text {
    width: auto !important;
    max-width: none !important;
    align-self: stretch !important;
  }
  .wg-prog,
  .wg-hint {
    display: none !important;
  }
  .wg-head {
    left: 20px !important;
    right: 20px !important;
    width: auto !important;
    transform: none !important;
    top: 30px !important;
  }
  /* tessellation: 2 columns on mobile, all tiles, keep the scroll-shift (one up / one down) */
  .cw-cols {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 10px !important;
  }
  .cw-col:nth-child(n + 3) {
    display: none !important;
  }
}
.hero-aperture img {
  -webkit-user-drag: none;
  user-select: none;
}
/* horizontal selected-work gallery */
/* ===================================================================
   02 · LIFE AROUND THE WORK  (#work-gallery) — vertical scroll pans a
   horizontal photo track sideways over a fixed mountain backdrop.
   =================================================================== */
#work-gallery {
  position: relative;
  height: 380vh;
  background: var(--c-bg);
}
.wg-stage {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
  background: var(--c-bg);
}
.wg-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 44%;
}
.wg-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(8, 12, 20, 0.88),
    rgba(8, 12, 20, 0.8) 50%,
    rgba(7, 11, 18, 0.92)
  );
}
#work-gallery .sh-flowfront {
  opacity: 0.18;
  z-index: 1;
}
.wg-head {
  position: absolute;
  top: 38px;
  /* align the label to the SAME centred 1280px content box the other sections use
     (.section-inner), so its side padding matches the rest of the scaffolding titles */
  left: 50%;
  transform: translateX(-50%);
  width: min(1280px, calc(100% - 2 * var(--gutter)));
  z-index: 4;
  display: flex;
  align-items: baseline;
  gap: 18px;
}
.wg-hint {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  color: var(--c-muted);
  text-transform: uppercase;
}
/* intro text panel that leads the photo track */
.wg-lead {
  font-family: var(--font-serif);
  font-weight: var(--fw-light);
  font-size: var(--fs-display-lg);
  line-height: 1.18;
  color: var(--c-heading-hi);
}
.wg-kicker {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-wide);
  color: var(--c-accent);
  text-transform: uppercase;
  margin-top: 20px;
}
/* narrower interstitial text panel between photos */
.wg-text-narrow {
  width: 16vw;
  max-width: 240px;
}
.wg-label {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-label);
  color: var(--c-cyan);
  text-transform: uppercase;
}
.wg-quote {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-title);
  line-height: 1.3;
  color: var(--c-text);
  margin-top: 14px;
}
.wg-track {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 5vw;
  padding: 0 8vw;
  will-change: transform;
}
.wg-item {
  flex: none;
  display: flex;
  flex-direction: column;
  cursor: pointer;
}
.wg-frame {
  flex: 1;
  overflow: hidden;
  background: var(--c-surface-2);
  border: 1px solid var(--c-border-softer);
}
.wg-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(0.9) brightness(0.96);
  transition:
    filter 0.4s,
    transform 0.6s var(--ease);
  -webkit-user-drag: none;
}
.wg-item:hover .wg-frame img {
  filter: saturate(1) brightness(1);
  transform: scale(1.04);
}
.wg-cap {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-meta);
  text-transform: uppercase;
  color: var(--c-muted);
}
.wg-lg {
  width: 25vw;
  max-width: 400px;
  height: 48vh;
}
.wg-md {
  width: 18vw;
  max-width: 300px;
  height: 37vh;
}
.wg-sm {
  width: 13vw;
  max-width: 210px;
  height: 26vh;
}
.wg-tall {
  width: 16vw;
  max-width: 270px;
  height: 53vh;
}
.wg-p1 {
  align-self: flex-start;
  margin-top: 7vh;
}
.wg-p2 {
  align-self: flex-start;
  margin-top: 19vh;
}
.wg-p3 {
  align-self: center;
}
.wg-p4 {
  align-self: flex-end;
  margin-bottom: 7vh;
}
.wg-p5 {
  align-self: flex-end;
  margin-bottom: 20vh;
}
.wg-text {
  flex: none;
  align-self: center;
  width: 23vw;
  max-width: 360px;
}
.wg-prog {
  position: absolute;
  inset-inline: var(--gutter);
  bottom: 30px;
  height: 1px;
  background: var(--c-border-softer);
  z-index: 4;
}
.wg-prog span {
  display: block;
  height: 100%;
  width: 100%;
  background: linear-gradient(90deg, var(--c-cyan), var(--c-italic));
  transform: scaleX(0);
  transform-origin: left;
}
/* creative work — animated jagged mountain-frame columns */
/* ===================================================================
   04 · HOBBIES  (#sec-hobbies) — full-bleed animated tessellation columns
   =================================================================== */
#sec-hobbies {
  padding: 110px 0 120px;
}
/* header/intro sit in a centered column; the tiles below bleed full width */
.hb-inner {
  z-index: 1;
  padding: 0 var(--gutter);
}
#sec-hobbies .section-head {
  margin-bottom: 14px;
}
.hb-lead {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-title);
  color: var(--c-text);
  margin: 0 0 40px;
  max-width: 560px;
}
.cw-cols {
  position: relative;
  z-index: 1;
  margin-top: 8px;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  height: 128vh;
  overflow: hidden;
  -webkit-mask: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%);
  mask: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%);
}
.cw-col {
  overflow: visible;
}
.cw-inner {
  display: flex;
  flex-direction: column;
  gap: 0;
  will-change: transform;
}
.cw-tile + .cw-tile {
  margin-top: -16px;
}
.hero-sparks {
  position: absolute;
  top: 0;
  left: 0;
  width: 230.2vh;
  height: 248.4vh;
  z-index: 3; /* above the aperture so dots read clearly over + around the opening */
  pointer-events: none;
  /* soft radial mask centred on the opening: dots emanate from over the opening and
     fade out before the surrounding UI (replaces the hard aperture mask that hid them
     over the opening and made them look like they came from the field, not the opening) */
  -webkit-mask: radial-gradient(42% 52% at 48.5% 58.6%, #000 0%, #000 52%, transparent 100%);
  mask: radial-gradient(42% 52% at 48.5% 58.6%, #000 0%, #000 52%, transparent 100%);
}
.hero-sparks i {
  position: absolute;
  left: 48.5%;
  top: 58.6%;
  border-radius: var(--r-round);
  background: var(--c-white);
  box-shadow: 0 0 10px 2px rgba(214, 232, 250, 0.2);
  opacity: 0;
  animation: spkOut linear infinite;
  will-change: transform, opacity;
}
@keyframes spkOut {
  0% {
    transform: translate(0, 0) scale(0.2);
    opacity: 0;
  }
  18% {
    opacity: 0.92;
  }
  80% {
    opacity: 0.45;
  }
  100% {
    transform: translate(var(--dx), var(--dy)) scale(1);
    opacity: 0;
  }
}
@keyframes edgeGlow {
  0% {
    opacity: 0;
    filter: drop-shadow(0 0 0 rgba(232, 170, 150, 0));
  }
  22% {
    opacity: 0.85;
    filter: drop-shadow(0 0 6px rgba(240, 200, 180, 0.5))
      drop-shadow(0 0 16px rgba(226, 150, 128, 0.4)) drop-shadow(0 0 30px rgba(210, 130, 120, 0.22));
  }
  55% {
    opacity: 0.5;
  }
  100% {
    opacity: 0;
    filter: drop-shadow(0 0 0 rgba(232, 170, 150, 0));
  }
}
.cw-tile.glow {
  z-index: 6;
}
.cw-tile.glow .cw-edge {
  animation: edgeGlow 1.5s ease-out both;
}
.hb-flow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: url("assets/effects/topo.svg") repeat;
  background-size: 660px 470px;
  opacity: 0.26;
  mix-blend-mode: screen;
  -webkit-mask: radial-gradient(
    135% 130% at 100% 100%,
    #000 0%,
    rgba(0, 0, 0, 0.55) 38%,
    transparent 74%
  );
  mask: radial-gradient(135% 130% at 100% 100%, #000 0%, rgba(0, 0, 0, 0.55) 38%, transparent 74%);
  animation: hbDrift 58s linear infinite;
}
.ow-flow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: url("assets/effects/radial-contours.webp") center/cover no-repeat;
  opacity: 0.34;
  mix-blend-mode: screen;
}
.hb-curve {
  position: absolute;
  left: -2%;
  top: 0;
  width: 104%;
  height: 7vw;
  background: var(--c-bg);
  border-bottom-left-radius: 50% 100%;
  border-bottom-right-radius: 50% 100%;
  z-index: 3;
  pointer-events: none;
}
@keyframes hbDrift {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -200px -150px;
  }
}
.cw-inner {
  transition: transform 1.1s cubic-bezier(0.16, 0.7, 0.2, 1);
}
.cw-tile {
  width: 100%;
  aspect-ratio: 608/648;
  position: relative;
}
.cw-fill {
  position: absolute;
  inset: 0;
  clip-path: polygon(
    0% 6.03%,
    4.94% 7.26%,
    10.05% 8.5%,
    14.99% 9.74%,
    19.93% 10.97%,
    25.04% 12.21%,
    29.98% 11.9%,
    34.93% 10.66%,
    40.03% 9.43%,
    44.98% 8.19%,
    50.08% 6.8%,
    55.02% 6.34%,
    59.97% 7.42%,
    65.07% 8.5%,
    70.02% 8.66%,
    74.96% 7.26%,
    80.07% 5.72%,
    85.01% 4.33%,
    89.95% 2.94%,
    95.06% 1.39%,
    100% 0%,
    100% 87.33%,
    95.06% 88.87%,
    89.95% 90.26%,
    85.01% 91.65%,
    80.07% 93.2%,
    74.96% 94.59%,
    70.02% 95.98%,
    65.07% 95.98%,
    59.97% 94.74%,
    55.02% 93.66%,
    50.08% 94.28%,
    44.98% 95.52%,
    40.03% 96.75%,
    34.93% 97.99%,
    29.98% 99.23%,
    25.04% 99.54%,
    19.93% 98.3%,
    14.99% 97.06%,
    10.05% 95.83%,
    4.94% 94.59%,
    0% 93.35%
  );
}
.cw-edge {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  opacity: 0;
  pointer-events: none;
}
.cw-edge polygon {
  fill: none;
  stroke: var(--c-pink);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
}
/* hobbies "creative wall" — real creative-work photos */
.cw-p1 {
  background: var(--tile-1) url(assets/creative/file_1.webp) center/cover;
}
.cw-p2 {
  background: var(--tile-2) url(assets/creative/file_2.webp) center/cover;
}
.cw-p3 {
  background: var(--tile-3) url(assets/creative/file_3.webp) center/cover;
}
.cw-p4 {
  background: var(--tile-4) url(assets/creative/file_4.webp) center/cover;
}
.cw-p5 {
  background: var(--tile-1) url(assets/creative/file_5.webp) center/cover;
}
.cw-p6 {
  background: var(--tile-2) url(assets/creative/file_6.webp) center/cover;
}
.cw-p7 {
  background: var(--tile-3) url(assets/creative/file_7.webp) center/cover;
}
.cw-p8 {
  background: var(--tile-4) url(assets/creative/file_8.webp) center/cover;
}
.cw-p9 {
  background: var(--tile-1) url(assets/creative/file_9.webp) center/cover;
}
.cw-p10 {
  background: var(--tile-2) url(assets/creative/file_10.webp) center/cover;
}
.cw-p11 {
  background: var(--tile-3) url(assets/creative/file_11.webp) center/cover;
}
.cw-p12 {
  background: var(--tile-4) url(assets/creative/file_12.webp) center/cover;
}
.cw-p13 {
  background: var(--tile-1) url(assets/creative/file_13.webp) center/cover;
}
.cw-p14 {
  background: var(--tile-2) url(assets/creative/file_14.webp) center/cover;
}
.cw-p15 {
  background: var(--tile-3) url(assets/creative/file_15.webp) center/cover;
}
