/* ===========================================================
   MeStyle Studio — Portfolio
   =========================================================== */

:root{
  --cream: #ECE7DC;
  --cream-2: #E4DECF;
  --paper: #F2EEE4;
  --ink: #17190f;
  --green: #34492f;
  --green-dark: #232f1e;
  --maroon: #7a1f3a;
  --navy: #1c3a68;
  --mustard: #f0c95d;
  --coral: #e08063;
  --lime: #d4e457;
  --teal: #17513f;
  --wine: #7a1f4f;
  --dark: #121210;
  --dark-2: #1a1a17;
  --font-thai: "Sukhumvit Set", "Noto Sans Thai", sans-serif;
  --font-display: "Unbounded", "Sukhumvit Set", "Noto Sans Thai", sans-serif;
  --font-mono: "Space Mono", "Sukhumvit Set", "Noto Sans Thai", monospace;
  --font-script: "Fraunces", "Sukhumvit Set", "Noto Sans Thai", serif;
  --ease: cubic-bezier(.16,.84,.32,1);
}

*{ margin:0; padding:0; box-sizing:border-box; }

html{ background:var(--cream); touch-action:pan-y; -webkit-text-size-adjust:100%; }

body{
  background:var(--cream);
  color:var(--ink);
  font-family:var(--font-mono);
  font-size:16px;
  line-height:1.5;
  overflow-x:hidden;
  cursor:default;
}

img{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; border:none; background:none; cursor:pointer; color:inherit; }
ul{ list-style:none; }

::selection{ background:var(--green); color:var(--cream); }

/* ---------- grain texture ---------- */
.grain{
  position:fixed; inset:0; z-index:9999; pointer-events:none;
  opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* no mix-blend-mode here on purpose: a full-viewport blended layer forces the
   compositor to redo the blend every frame that anything else on the page
   animates (marquee, cursor, drift...) — a real, easy-to-miss jank source. */

/* ---------- custom cursor ---------- */
.cursor-dot{
  position:fixed; top:0; left:0; width:10px; height:10px; border-radius:50%;
  background:var(--ink); pointer-events:none; z-index:9998;
  transform:translate(-50%,-50%); transition:opacity .2s, background .3s;
  mix-blend-mode:difference;
}
.cursor-label{
  position:fixed; top:0; left:0; width:84px; height:84px; border-radius:50%;
  background:var(--ink); color:var(--cream); display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-size:12px; letter-spacing:.05em; text-transform:uppercase;
  pointer-events:none; z-index:9997; transform:translate(-50%,-50%) scale(0); opacity:0;
  transition:transform .35s var(--ease), opacity .3s;
}
@media (hover:none){ .cursor-dot,.cursor-label{ display:none; } }

/* ---------- scroll progress ---------- */
.scroll-progress{ position:fixed; top:0; left:0; width:100%; height:3px; z-index:500; background:transparent; }
.scroll-progress__bar{ height:100%; width:0%; background:var(--green); }

/* ================= NAV ================= */
.nav{
  position:fixed; top:0; left:0; width:100%; z-index:400;
  display:flex; align-items:center; justify-content:space-between;
  padding:22px 40px; mix-blend-mode:normal;
}
.nav__logo{
  font-family:var(--font-display); font-weight:700; font-size:18px;
  display:flex; align-items:center; gap:8px;
}
.nav__mark{ width:24px; height:24px; border-radius:50%; flex-shrink:0; }
.nav__tm{ font-size:10px; vertical-align:super; }
.nav__links{ display:flex; gap:32px; font-size:13px; text-transform:uppercase; letter-spacing:.06em; }
.nav__links a{ position:relative; }
.nav__links a::after{
  content:""; position:absolute; left:0; bottom:-4px; width:0; height:1px; background:var(--ink);
  transition:width .3s var(--ease);
}
.nav__links a:hover::after{ width:100%; }
.nav__cta{ font-size:12px; padding:10px 20px; }


/* ---------- language switch (sits beside the CTA, deliberately small) ---------- */
.nav__lang{ display:flex; align-items:center; gap:5px; margin-left:14px; }
.nav__lang-btn{
  font-family:var(--font-mono); font-size:11px; font-weight:700; letter-spacing:.06em;
  color:#8a8a78; padding:3px 2px; line-height:1; transition:color .25s var(--ease);
}
.nav__lang-btn:hover{ color:var(--ink); }
.nav__lang-btn.is-active{ color:var(--ink); }
.nav__lang-sep{ font-family:var(--font-mono); font-size:11px; color:#b9b9a8; }

/* ---------- hamburger ---------- */
.nav__burger{
  display:none; position:relative; width:40px; height:40px; margin-left:6px;
  flex-direction:column; align-items:center; justify-content:center; gap:5px;
  border-radius:50%; flex-shrink:0;
}
.nav__burger span{
  display:block; width:20px; height:2px; background:var(--ink); border-radius:2px;
  transition:transform .4s var(--ease), opacity .25s var(--ease);
}
.nav__burger.is-open span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.nav__burger.is-open span:nth-child(2){ opacity:0; transform:scaleX(.2); }
.nav__burger.is-open span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

.nav__scrim{
  position:fixed; inset:0; z-index:390; background:rgba(18,18,16,.42);
  backdrop-filter:blur(3px); opacity:0; transition:opacity .35s var(--ease);
}
.nav__scrim.is-open{ opacity:1; }

@media(max-width:820px){
  .nav{ padding:16px 20px; }
  .nav__burger{ display:flex; }
  .nav__logo, .nav__lang, .nav__burger{ position:relative; z-index:2; }
  .nav .nav__cta{ display:none; }
  .nav__lang{ margin-left:auto; margin-right:4px; }

  /* the links become a sheet that drops from under the bar */
  /* the sheet is a child of .nav, so its z-index competes with the bar's own
     controls — keep it at 1 and lift the logo/lang/burger above it so they
     stay clickable and visible while the menu is open */
  .nav__links{
    position:fixed; top:0; left:0; right:0; z-index:1;
    display:flex; flex-direction:column; align-items:flex-start; gap:0;
    padding:84px 26px 26px; background:var(--paper);
    border-bottom-left-radius:22px; border-bottom-right-radius:22px;
    box-shadow:0 24px 60px rgba(18,18,16,.18);
    text-transform:none; letter-spacing:normal; font-size:17px;
    transform:translateY(-102%); transition:transform .5s var(--ease);
    pointer-events:none;
  }
  .nav__links.is-open{ transform:translateY(0); pointer-events:auto; }
  .nav__links a{
    width:100%; padding:15px 0; border-bottom:1px solid rgba(23,25,15,.1);
    opacity:0; transform:translateY(-10px);
    transition:opacity .4s var(--ease), transform .4s var(--ease);
  }
  .nav__links a:last-child{ border-bottom:none; }
  .nav__links a::after{ display:none; }
  .nav__links.is-open a{ opacity:1; transform:translateY(0); }
  /* each row trails the one above it as the sheet lands */
  .nav__links.is-open a:nth-child(1){ transition-delay:.16s; }
  .nav__links.is-open a:nth-child(2){ transition-delay:.21s; }
  .nav__links.is-open a:nth-child(3){ transition-delay:.26s; }
  .nav__links.is-open a:nth-child(4){ transition-delay:.31s; }
  .nav__links.is-open a:nth-child(5){ transition-delay:.36s; }
  .nav__links.is-open a:nth-child(6){ transition-delay:.41s; }
  body.nav-open{ overflow:hidden; }
}
@media (prefers-reduced-motion: reduce){
  .nav__links, .nav__links a, .nav__burger span, .nav__scrim{ transition-duration:.01ms !important; }
}

/* ================= BUTTONS / PILLS ================= */
.pill{
  display:inline-flex; align-items:center; padding:9px 20px; border-radius:100px;
  font-family:var(--font-mono); font-weight:700; font-size:13px; letter-spacing:.02em;
  white-space:nowrap;
}
.pill--outline{ border:1.5px solid var(--green); color:var(--green); background:transparent; }
.pill--outline-dark{ border:1.5px solid var(--ink); color:var(--ink); background:transparent; }
.pill--outline-light{ border:1.5px solid rgba(236,231,220,.5); color:var(--cream); }
.pill--outline-light:hover{ background:var(--cream); color:var(--dark); }
.pill--maroon{ background:var(--maroon); color:#f3c8d4; }
.pill--navy{ background:var(--navy); color:#cfe0ff; }
.pill--mustard{ background:var(--mustard); color:#5c3d10; }
.pill--coral{ background:var(--coral); color:#3c1305; }
.pill--lime{ background:var(--lime); color:#2b3a12; }
.pill--teal{ background:var(--teal); color:#bdf5e0; }
.pill--wine{ background:var(--wine); color:#f5cfe3; }

.mark-circle{
  width:44px; height:44px; border-radius:50%; flex-shrink:0;
}

.btn{
  display:inline-flex; align-items:center; justify-content:center; padding:16px 34px;
  border-radius:100px; font-family:var(--font-mono); font-weight:700; font-size:14px;
  letter-spacing:.02em; transition:transform .35s var(--ease), background .3s, color .3s;
}
.btn--ghost{ border:1.5px solid var(--ink); }
.btn--ghost:hover{ background:var(--ink); color:var(--cream); }
.btn--solid{ background:var(--ink); color:var(--cream); width:100%; }
.btn--solid:hover{ background:var(--green); }
.btn--outline{ border:1.5px solid var(--ink); width:100%; }
.btn--outline:hover{ background:var(--ink); color:var(--cream); }

/* ================= TYPOGRAPHY HELPERS ================= */
.eyebrow{
  font-family:var(--font-mono); font-weight:700; text-transform:uppercase; letter-spacing:.12em;
  font-size:13px; color:var(--green); margin-bottom:18px;
}
.h2{ font-family:var(--font-display); font-weight:700; font-size:clamp(30px,4.4vw,58px); line-height:1.08; letter-spacing:-.01em; }
.h2--big{ font-size:clamp(38px,6vw,80px); }

/* ================= HERO ================= */
.hero{
  min-height:100svh; padding:150px 40px 90px; display:flex; flex-direction:column; align-items:center;
  text-align:center; position:relative; background:var(--cream);
}
.hero__badge-row{ display:flex; align-items:center; gap:14px; margin-bottom:26px; }
.hero__eyebrow{
  font-family:var(--font-mono); font-weight:700; color:var(--green); letter-spacing:.1em;
  text-transform:uppercase; font-size:14px; margin-bottom:8px;
}
.hero__title{
  font-family:var(--font-display); font-weight:800; letter-spacing:-.02em;
  font-size:clamp(60px,13vw,168px); line-height:.92; color:var(--ink);
}
.hero__title .line{ display:block; overflow:hidden; }
.hero__tm{ font-size:.28em; vertical-align:super; }
.hero__tagline{
  font-family:var(--font-mono); font-size:clamp(16px,2vw,22px); color:var(--green); margin:26px 0 34px;
  font-weight:700;
}
.hero__tags{ display:flex; flex-wrap:wrap; justify-content:center; gap:12px; max-width:900px; }

/* secondary page header (work.html) — shorter than the full-screen homepage hero */
.hero--page{ min-height:auto; padding:150px 40px 50px; }
.hero__title--page{
  font-family:var(--font-display); font-weight:800; letter-spacing:-.02em;
  /* line-height 1.25 (not the ~.92 the Latin wordmark in .hero__title uses) —
     Thai vowel/tone marks stack above and below the baseline and get clipped
     into neighbouring lines at tight line-heights */
  font-size:clamp(40px,7vw,88px); line-height:1.25; color:var(--ink); margin:14px 0 22px;
}

.scroll-cue{
  margin-top:auto; padding-top:48px;
  display:flex; flex-direction:column; align-items:center; gap:10px;
  font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--green);
  flex-shrink:0;
}
.scroll-cue__line{ width:1px; height:44px; background:var(--green); overflow:hidden; position:relative; }
.scroll-cue__line::after{
  content:""; position:absolute; top:-100%; left:0; width:100%; height:100%; background:var(--ink);
  animation:cue 1.8s ease-in-out infinite;
}
@keyframes cue{ 0%{ top:-100%; } 50%{ top:0; } 100%{ top:100%; } }

/* ================= MARQUEE ================= */
.marquee-section{ border-top:1px solid rgba(23,25,15,.12); border-bottom:1px solid rgba(23,25,15,.12); padding:24px 0; overflow:hidden; }
.marquee{ display:flex; white-space:nowrap; }
.marquee__track{ display:flex; align-items:center; flex-shrink:0; animation:marquee 34s linear infinite; }
.marquee__track span{
  font-family:var(--font-display); font-weight:600; font-size:clamp(20px,3vw,34px);
  padding:0 22px; color:var(--ink); opacity:.85;
}
@keyframes marquee{ from{ transform:translate3d(0,0,0); } to{ transform:translate3d(-100%,0,0); } }

/* client-logo marquee: smaller/symmetric sizing + cross-platform-safe loop */
.marquee--clients .marquee__track{
  gap:44px; backface-visibility:hidden; will-change:transform;
}
.marquee--clients .marquee__track span{
  font-size:clamp(13px,1.6vw,20px); padding:0; line-height:1; opacity:.7;
}
@media (prefers-reduced-motion: reduce){
  .marquee__track{ animation-play-state:paused; }
}

/* ================= ABOUT ================= */
.about{ padding:150px 40px; max-width:1360px; margin:0 auto; }
.about__grid{ display:grid; grid-template-columns:1fr 1fr; gap:60px; margin-bottom:110px; }
.about__copy p{ font-size:16px; line-height:1.75; margin-bottom:20px; color:#3a3a30; }
.about__copy p:last-child{ margin-bottom:0; }
.about__copy strong{ font-weight:700; color:var(--ink); }
.about__role{
  margin-top:22px; font-family:var(--font-mono); font-size:13px; line-height:1.8;
  letter-spacing:.04em; color:#5c5c4d;
}

.stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:30px; border-top:1.5px solid var(--ink); padding-top:44px; }
.stats__item p{ font-size:13px; color:#4d4d40; margin-top:10px; max-width:180px; }
.stats__num{ font-family:var(--font-display); font-weight:800; font-size:clamp(40px,5vw,68px); }
.stats__plus{ font-family:var(--font-display); font-weight:800; font-size:clamp(24px,3vw,36px); color:var(--green); }

@media(max-width:900px){
  .about__grid{ grid-template-columns:1fr; gap:30px; }
  .stats{ grid-template-columns:repeat(2,1fr); }
}

/* ================= SERVICES ================= */
.services{ padding:60px 40px 150px; max-width:1360px; margin:0 auto; }
.services__list{ margin-top:60px; border-top:1.5px solid var(--ink); }
/* each row is now a link through to that category on the work page, so the
   grid gains a trailing "ดูผลงาน →" cell that only shows on hover/focus */
.service-row{
  display:grid; grid-template-columns:60px 1fr 2fr auto auto; align-items:center; gap:30px;
  padding:34px 10px; border-bottom:1.5px solid var(--ink);
  transition:padding-left .4s var(--ease), background .4s; color:inherit;
}
.service-row:hover{ padding-left:22px; background:rgba(52,73,47,.06); }
.service-row:focus-visible{ outline:2px solid var(--green); outline-offset:-2px; }
.service-row__num{ font-family:var(--font-mono); font-weight:700; color:var(--green); font-size:14px; }
.service-row__title{ font-family:var(--font-display); font-weight:700; font-size:clamp(20px,2.4vw,32px); }
.service-row__desc{ font-size:14px; color:#4d4d40; max-width:520px; }
.service-row__tag{ justify-self:end; }
.service-row__go{
  justify-self:end; white-space:nowrap;
  font-family:var(--font-mono); font-size:12px; font-weight:700; color:var(--green);
  opacity:0; transform:translateX(-8px);
  transition:opacity .35s var(--ease), transform .35s var(--ease);
}
.service-row:hover .service-row__go,
.service-row:focus-visible .service-row__go{ opacity:1; transform:translateX(0); }

@media(max-width:820px){
  .service-row{ grid-template-columns:1fr; gap:12px; text-align:left; }
  .service-row__tag, .service-row__go{ justify-self:start; }
  /* no hover on touch — keep the affordance permanently visible instead */
  .service-row__go{ opacity:1; transform:none; }
}

/* ================= WORK DIVIDER ================= */
.work-divider{
  background:var(--dark); color:var(--paper); padding:150px 40px; text-align:center;
  display:flex; flex-direction:column; align-items:center; gap:20px;
}
.work-divider__script{
  font-family:var(--font-script); font-style:italic; font-weight:400;
  font-size:clamp(48px,10vw,150px); letter-spacing:-.01em;
}
.work-divider__sub{ font-family:var(--font-mono); font-size:13px; letter-spacing:.06em; opacity:.65; }

/* ================= WORK / MASONRY ================= */
.work{ background:var(--cream); padding:20px 40px 60px; max-width:1360px; margin:0 auto; }

.work__masonry{ display:flex; gap:24px; align-items:flex-start; }
.masonry__col{ flex:1; min-width:0; display:flex; flex-direction:column; gap:24px; }

.masonry__tile{
  position:relative; display:block; overflow:hidden; border-radius:16px; background:var(--dark-2);
  width:100%; padding:0; border:0; font:inherit; text-align:left; cursor:pointer;
}
/* these three shapes are what give the masonry grid its varied rhythm, but
   object-fit:cover crops whichever dimension overflows the tile — and every
   source photo is now a fixed 4:5 (1080×1350, the IG-post standard). --short
   used to be 4:3 (much wider than tall), which crops HARD off the top/bottom
   of a 4:5 source and was cutting off logos/headlines sitting near the edges.
   Tightened all three closer to 4:5 so tiles still read as tall/med/short
   relative to each other, but none crop aggressively — --med now matches 4:5
   exactly (zero crop). */
.masonry__tile--tall{ aspect-ratio:3/4; }
.masonry__tile--med{ aspect-ratio:4/5; }
.masonry__tile--short{ aspect-ratio:1/1; }

.masonry__tile img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .6s var(--ease);
}
.masonry__preview-grid{
  position:absolute; inset:0; display:grid; grid-template-columns:1.35fr 1fr; grid-template-rows:1fr 1fr;
  gap:3px; background:var(--cream-2);
}
.masonry__preview-grid img:first-child{ grid-row:1 / span 2; }
.masonry__preview-grid img{ min-width:0; min-height:0; transition:transform .6s var(--ease); }
.masonry__preview-grid-video{
  display:flex; align-items:center; justify-content:center; background:var(--dark-2); color:var(--cream);
  font-size:clamp(20px,3vw,34px); line-height:1;
}
.masonry__tile:hover .masonry__preview-grid img,
.masonry__tile:focus-visible .masonry__preview-grid img{ transform:scale(1.06); }
.masonry__tile:hover img, .masonry__tile:focus-visible img{ transform:scale(1.08); }

.masonry__overlay{
  position:absolute; inset:0; display:flex; flex-direction:column; justify-content:flex-end; gap:10px;
  padding:22px; background:linear-gradient(180deg, rgba(18,18,16,0) 45%, rgba(18,18,16,.88) 100%);
  opacity:0; transform:translateY(10px);
  transition:opacity .4s var(--ease), transform .4s var(--ease);
}
.masonry__tile:hover .masonry__overlay,
.masonry__tile:focus-visible .masonry__overlay{ opacity:1; transform:translateY(0); }
.masonry__overlay .pill{ align-self:flex-start; }
.masonry__overlay h3, .masonry__overlay-title{ display:block; font-family:var(--font-display); font-weight:700; font-size:clamp(18px,2vw,24px); color:var(--cream); }

.work__more{ margin-top:56px; text-align:center; display:flex; flex-direction:column; align-items:center; gap:16px; }
.work__more p{ font-size:12.5px; color:#6b6b5c; max-width:460px; }

/* column count is decided in JS (shortest-column-first packing) so the grid
   stays balanced under every filter — the breakpoints here only tighten the
   gutters to match. */
@media(max-width:1100px){
  .work__masonry, .masonry__col{ gap:18px; }
}
@media(max-width:820px){
  .work__masonry, .masonry__col{ gap:14px; }
  .work{ padding:20px 20px 60px; }
}
@media (hover:none){
  .masonry__overlay{ opacity:1; transform:translateY(0); background:linear-gradient(180deg, rgba(18,18,16,0) 55%, rgba(18,18,16,.82) 100%); }
}

/* ================= WORK FILTER TABS (work.html) ================= */
.work-filter{ display:flex; flex-wrap:wrap; gap:10px; justify-content:center; margin:0 0 50px; }
.work-filter button{
  padding:10px 22px; border-radius:100px; border:1.5px solid var(--ink); font-family:var(--font-mono);
  font-weight:700; font-size:13px; transition:background .3s, color .3s;
}
.work-filter button.is-active{ background:var(--ink); color:var(--cream); }

/* ================= LIGHTBOX (work.html project viewer) ================= */
.lightbox{
  position:fixed; inset:0; z-index:1000; display:flex; align-items:center; justify-content:center;
  padding:40px; visibility:hidden; opacity:0;
}
.lightbox.is-open{ visibility:visible; opacity:1; }
.lightbox__backdrop{
  position:absolute; inset:0; background:rgba(18,18,16,.9); backdrop-filter:blur(6px);
}
/* IG-post layout: image dominant on top, small caption strip below — not a
   side-by-side split, so the photo stays the focus and text stays secondary.
   Media box is a fixed 4:5 (1080×1350, IG's own standard post size) frame —
   matches the project photo/video standard, so the frame never resizes
   between slides (no reflow/"flicker" of the caption below) and media fills
   it edge-to-edge with no bars. Shorter than the old 9:16 frame, so there's
   much more often enough room for photo + caption without needing to scroll
   at all. */
/* overflow-x:hidden keeps the rounded-corner clip on the media's square
   edges; overflow-y:auto is what lets the whole card scroll when the photo
   (always full size, never shrunk) plus the caption add up to more than the
   screen — see .lightbox__scroll-hint below for the "you can scroll" cue.
   overscroll-behavior:contain stops the rubber-band bounce at the top/bottom
   edge from chaining/leaking into the page or lingering — without it,
   reversing direction right at the bottom edge felt sticky/unresponsive,
   like it took a few tries to get the scroll moving back up again. */
.lightbox__panel{
  position:relative; z-index:1; background:var(--paper); border-radius:20px;
  overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain;
  width:min(400px,92vw); max-height:92vh; display:flex; flex-direction:column;
  scrollbar-width:thin; scrollbar-color:rgba(23,25,15,.4) transparent; /* Firefox */
}
/* macOS/iOS default scrollbars are "overlay" — invisible until you're mid-
   scroll, then they fade out again, which is exactly what read as "disappears".
   Styling ::-webkit-scrollbar switches Safari/Chrome to a classic, permanently
   visible scrollbar instead of the overlay one. */
.lightbox__panel::-webkit-scrollbar{ width:6px; }
.lightbox__panel::-webkit-scrollbar-track{ background:transparent; }
.lightbox__panel::-webkit-scrollbar-thumb{ background:rgba(23,25,15,.4); border-radius:3px; }
.lightbox__panel::-webkit-scrollbar-thumb:hover{ background:rgba(23,25,15,.6); }
.lightbox__close{
  position:absolute; top:16px; right:16px; z-index:2; width:34px; height:34px; border-radius:50%;
  background:rgba(18,18,16,.55); color:var(--cream); font-size:14px; display:flex; align-items:center; justify-content:center;
}
/* escape hatch out of a single project: jump to any category or home without
   having to close first and hunt for the filter bar underneath */
.lightbox__categories{ position:absolute; top:16px; left:16px; z-index:3; }
.lightbox__categories-toggle{
  width:34px; height:34px; border-radius:50%; border:0; cursor:pointer;
  background:rgba(18,18,16,.55); color:var(--cream); font-size:14px; display:flex; align-items:center; justify-content:center;
}
.lightbox__categories-menu{
  position:absolute; top:42px; left:0; min-width:170px; background:var(--paper); border-radius:12px;
  overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,.4); display:none; flex-direction:column;
}
.lightbox__categories-menu.is-open{ display:flex; }
.lightbox__categories-menu button, .lightbox__categories-menu a{
  padding:11px 16px; text-align:left; font-size:13px; color:var(--ink); background:none; border:0;
  cursor:pointer; text-decoration:none; font-family:inherit;
}
.lightbox__categories-menu button:hover, .lightbox__categories-menu a:hover{ background:var(--cream-2); }
.lightbox__categories-menu button.is-flagship{ font-weight:700; }
.lightbox__categories-home{ border-top:1px solid var(--cream-2); }
/* the photo is never shrunk/cropped to make room for the caption — it always
   renders at its true 4:5 size for the panel's width, full stop. If that plus
   the caption below is still taller than the screen (long descriptions,
   short windows), the PANEL scrolls (see overflow-y:auto on .lightbox__panel
   above) so you scroll to reveal the rest, the same way you'd scroll any tall
   webpage — the image itself never changes size. */
.lightbox__media{
  position:relative; background:var(--dark-2); overflow:hidden; touch-action:pan-y;
  width:100%; aspect-ratio:4/5; flex:0 0 auto;
}
.lightbox__stage{ position:relative; width:100%; height:100%; }
.lightbox__stage.is-video::before{
  content:""; position:absolute; inset:-12%; z-index:0; background-image:var(--media-bg);
  background-position:center; background-size:cover; filter:blur(24px); transform:scale(1.08); opacity:.68;
}
.lightbox__stage img, .lightbox__stage video{
  width:100%; height:100%; object-fit:cover; display:block;
}
.lightbox__stage video{ position:relative; z-index:1; object-fit:contain; background:transparent; }
.lightbox__nav{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2; width:40px; height:40px; border-radius:50%;
  background:rgba(236,231,220,.15); color:var(--cream); font-size:16px; display:flex; align-items:center; justify-content:center;
  transition:background .3s;
}
.lightbox__nav:hover{ background:rgba(236,231,220,.32); }
.lightbox__nav--prev{ left:14px; }
.lightbox__nav--next{ right:14px; }

/* IG-style dot indicators */
.lightbox__dots{
  position:absolute; bottom:16px; left:50%; transform:translateX(-50%); z-index:2;
  display:flex; gap:7px; padding:6px 10px; border-radius:100px; background:rgba(18,18,16,.35);
}
.lightbox__dot{ width:6px; height:6px; border-radius:50%; background:rgba(236,231,220,.45); transition:background .25s, transform .25s; }
.lightbox__dot.is-active{ background:var(--cream); transform:scale(1.3); }

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

/* caption strip, IG-style: small and secondary — the photo does the talking.
   Description defaults to a 2-line clamp with a "เพิ่มเติม" toggle (like IG's
   "more") instead of a raw scroll box. No max-height/scroll of its own here —
   a second, nested scroll area fights with the panel's own scroll (whichever
   one the cursor happens to be over wins, which feels broken). The panel
   above is the single scroll surface for the whole card. */
.lightbox__info{
  flex:0 0 auto; padding:16px 20px 20px; display:flex; flex-direction:column; align-items:flex-start; gap:6px;
}
.lightbox__info .pill{ font-size:10.5px; padding:4px 12px; margin-bottom:2px; }
.lightbox__info h3{ font-family:var(--font-display); font-weight:700; font-size:15px; }
.lightbox__info p{ font-size:12.5px; line-height:1.55; color:#5a5a4d; }
.lightbox__info p.is-clamped{
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
/* the clamped <p> must NOT be a direct flex item — flexbox blockifies/strips
   -webkit-box's special multi-line clamp rendering, so it silently never
   truncated. This plain block wrapper keeps it out of .lightbox__info's flex
   context while still taking part in that layout as a single flex child. */
.lightbox__desc-wrap{ width:100%; }
.lightbox__desc-toggle{
  display:none; border:0; background:none; padding:0; margin-top:4px; font-size:12.5px; font-weight:700;
  color:var(--ink); text-decoration:underline; cursor:pointer; font-family:inherit;
}
.lightbox__desc-toggle.is-visible{ display:block; }

/* "you can scroll" cue: a quiet text label pinned to the bottom of the card's
   visible area (position:absolute against .lightbox__panel, so it stays put
   while the panel's own content scrolls underneath it). Deliberately low-key
   — it used to be a bold bouncing circle-arrow that drew more attention than
   the photo itself, which is backwards; this should be noticeable only if
   you're looking for it. JS shows it only while there's actually more
   content below, and hides it once scrolled to the true bottom. */
.lightbox__scroll-hint{
  position:absolute; left:50%; bottom:10px; transform:translateX(-50%); z-index:4;
  border:0; border-radius:100px; background:rgba(18,18,16,.32); color:var(--cream);
  display:flex; align-items:center; justify-content:center; gap:4px;
  padding:5px 12px; font-size:10.5px; font-family:inherit; letter-spacing:.02em; white-space:nowrap;
  opacity:0; pointer-events:none; cursor:pointer; transition:opacity .3s ease, background .2s ease;
}
.lightbox__scroll-hint:hover{ background:rgba(18,18,16,.5); }
.lightbox__scroll-hint.is-visible{ opacity:.75; pointer-events:auto; }
.lightbox__scroll-hint.is-visible:hover{ opacity:1; }

@media(max-width:760px){
  .lightbox{ padding:0; }
  .lightbox__panel{ border-radius:0; max-height:100vh; }
}

/* ================= START A PROJECT / BRIEF FORM ================= */
/* replaced the old public price table: rates are quoted per-project after the
   brief instead of listed on the page, so the section's job is to make it easy
   to describe a project, not to advertise a number. */
.brief{ padding:150px 40px; max-width:820px; margin:0 auto; text-align:center; }
.brief .eyebrow, .brief .h2{ text-align:center; }
.brief .h2{ margin:0 auto 24px; }
.brief__lead{ font-size:15px; line-height:1.8; color:#4d4d40; max-width:560px; margin:0 auto 56px; }

form.brief{ padding:0; max-width:100%; text-align:left; position:relative; }
.brief__bar{ height:3px; background:rgba(23,25,15,.12); border-radius:100px; overflow:hidden; }
.brief__bar-fill{ display:block; height:100%; width:25%; background:var(--green); transition:width .45s var(--ease); }
.brief__count{ font-family:var(--font-mono); font-size:12px; letter-spacing:.08em; color:#6b6b5c; margin:14px 0 34px; }

.brief__step{ display:none; border:0; padding:0; margin:0; }
.brief__step.is-active{ display:block; }
.brief__q{
  font-family:var(--font-display); font-weight:700; font-size:clamp(21px,2.6vw,28px);
  line-height:1.35; margin-bottom:10px; padding:0;
}
.brief__hint{ font-family:var(--font-mono); font-size:12.5px; color:#6b6b5c; margin-bottom:18px; }
.brief__hint--mt{ margin-top:34px; }

.brief__opts{ display:flex; flex-wrap:wrap; gap:10px; }
.brief__opt{ position:relative; cursor:pointer; }
.brief__opt input{ position:absolute; opacity:0; width:0; height:0; }
.brief__opt span{
  display:inline-block; padding:12px 20px; border-radius:100px; border:1.5px solid rgba(23,25,15,.28);
  font-family:var(--font-mono); font-size:13px; font-weight:700; line-height:1;
  transition:background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.brief__opt:hover span{ border-color:var(--ink); }
.brief__opt input:checked + span{ background:var(--ink); border-color:var(--ink); color:var(--cream); }
.brief__opt input:focus-visible + span{ outline:2px solid var(--green); outline-offset:3px; }

.brief__fields{ display:grid; grid-template-columns:1fr 1fr; gap:18px; }
.brief__field{ display:flex; flex-direction:column; gap:8px; }
.brief__field--full{ grid-column:1 / -1; margin-top:18px; }
.brief__field > span{ font-family:var(--font-mono); font-size:12.5px; color:#4d4d40; }
.brief__field em{ color:#a4432f; font-style:normal; }
.brief__field input, .brief__field textarea{
  width:100%; padding:14px 16px; border-radius:12px; border:1.5px solid rgba(23,25,15,.22);
  background:var(--paper); font-family:inherit; font-size:14.5px; color:var(--ink);
  transition:border-color .25s var(--ease);
}
.brief__field input:focus, .brief__field textarea:focus{ outline:none; border-color:var(--green); }
.brief__field textarea{ resize:vertical; line-height:1.7; }

.brief__error{ margin-top:16px; font-family:var(--font-mono); font-size:12.5px; color:#a4432f; min-height:18px; }

.brief__nav{ display:flex; gap:12px; justify-content:space-between; margin-top:42px; }
.brief__nav .btn{ min-width:132px; justify-content:center; }
.brief__nav .btn[disabled]{ opacity:.35; pointer-events:none; }

.brief__done{ text-align:left; }
.brief__done-title{ font-family:var(--font-display); font-weight:700; font-size:22px; margin-bottom:16px; }
.brief__summary{
  background:var(--paper); border:1.5px solid rgba(23,25,15,.18); border-radius:14px;
  padding:22px; font-family:var(--font-mono); font-size:12.5px; line-height:1.85; color:#3a3a30;
  white-space:pre-wrap; word-break:break-word; max-height:340px; overflow:auto;
}
.brief__done-actions{ display:flex; flex-wrap:wrap; gap:12px; margin-top:22px; }
.brief__restart{
  margin-top:26px; font-family:var(--font-mono); font-size:12.5px; color:#6b6b5c;
  text-decoration:underline; text-underline-offset:4px;
}
.brief__restart:hover{ color:var(--ink); }

@media(max-width:640px){
  .brief__fields{ grid-template-columns:1fr; }
  .brief__nav{ flex-direction:column-reverse; }
  .brief__nav .btn{ width:100%; }
  .brief__done-actions .btn{ width:100%; justify-content:center; }
}

/* ================= TESTIMONIALS ================= */
.testimonials{ padding:150px 0 130px; text-align:center; }
.testimonials .eyebrow, .testimonials .h2{ padding:0 40px; }
.testimonials .h2{ margin-bottom:60px; }
.marquee-section--testi{ border:none; padding:0; }
.marquee--testi .marquee__track{ animation-duration:46s; align-items:stretch; gap:22px; padding:0 11px; }
.quote-card{
  width:340px; flex-shrink:0; background:var(--paper); border:1.5px solid var(--ink); border-radius:18px;
  padding:28px; font-size:14px; line-height:1.6; text-align:left; white-space:normal;
  display:flex; flex-direction:column; gap:16px; justify-content:space-between;
}
.quote-card cite{ font-style:normal; color:var(--mustard); background:var(--ink); align-self:flex-start; padding:4px 10px; border-radius:6px; font-size:12px; }

/* ================= FAQ ================= */
.faq{ padding:150px 40px; max-width:900px; margin:0 auto; }
.faq .eyebrow, .faq .h2{ text-align:center; }
.faq .h2{ text-align:center; margin-bottom:60px; }
.faq__list{ border-top:1.5px solid var(--ink); }
.faq-item{ border-bottom:1.5px solid var(--ink); }
.faq-item__q{
  width:100%; display:flex; justify-content:space-between; align-items:center; text-align:left;
  padding:26px 4px; font-family:var(--font-display); font-weight:600; font-size:clamp(16px,2vw,20px);
}
.faq-item__icon{ font-size:20px; color:var(--green); transition:transform .4s var(--ease); flex-shrink:0; margin-left:20px; }
.faq-item.open .faq-item__icon{ transform:rotate(45deg); }
.faq-item__a{ height:0; overflow:hidden; }
.faq-item__a p{ padding:0 4px 26px; font-size:14px; line-height:1.7; color:#4d4d40; max-width:640px; }

/* ================= CONTACT ================= */
.contact{
  background:var(--dark); color:var(--paper); padding:160px 40px 130px; text-align:center;
  display:flex; flex-direction:column; align-items:center; gap:44px;
}
.contact__eyebrow{ font-size:13px; letter-spacing:.12em; text-transform:uppercase; color:var(--lime); font-weight:700; }
.contact__title{ font-family:var(--font-display); font-weight:800; font-size:clamp(40px,8vw,110px); line-height:1.02; margin-bottom:22px; }
.contact__link{ display:inline-block; transition:letter-spacing .4s var(--ease); }
.contact__link:hover{ letter-spacing:.01em; color:var(--mustard); }
.contact__row{ display:flex; flex-wrap:wrap; gap:14px; justify-content:center; }

/* ================= FOOTER ================= */
.footer{
  background:var(--dark); color:rgba(236,231,220,.6); padding:26px 40px 40px;
  display:flex; justify-content:space-between; align-items:center; font-size:12px; flex-wrap:wrap; gap:12px;
}
.footer__top:hover{ color:var(--cream); }

/* ================= REVEAL (GSAP hooks; base hidden state) ================= */
[data-reveal]{ opacity:1; }

/* ================= RESPONSIVE ================= */
@media(max-width:600px){
  .hero{ padding:130px 20px 70px; }
  .about, .services, .brief, .faq{ padding-left:20px; padding-right:20px; }
  .work{ padding-left:20px; padding-right:20px; }
  .work-divider, .contact{ padding-left:20px; padding-right:20px; }
  .stats{ grid-template-columns:1fr 1fr; }
}

/* ================= CV / ABOUT PAGE ================= */
.cv-hero{
  display:grid; grid-template-columns:0.8fr 1.2fr; gap:60px; align-items:center;
  max-width:1200px; margin:0 auto; padding:170px 40px 90px;
}
/* portrait starts desaturated and warms to full colour on hover/touch, with a
   small parallax tilt tracking the pointer. perspective lives on the wrapper so
   the tilt reads as depth rather than a flat skew. */
.cv-hero__portrait{
  position:relative; border-radius:24px; overflow:hidden; aspect-ratio:3/4;
  background:var(--cream-2); perspective:900px; cursor:pointer;
  -webkit-tap-highlight-color:transparent; touch-action:manipulation;
}
.cv-hero__portrait img{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:grayscale(.9) sepia(.12) contrast(.94) brightness(1.06);
  transform:scale(1.04);
  transition:filter .55s var(--ease), transform .5s var(--ease);
  will-change:transform, filter;
}
.cv-hero__portrait.is-lit img{
  filter:grayscale(0) sepia(0) contrast(1.04) brightness(1);
  transform:scale(1.08);
}

@media (prefers-reduced-motion: reduce){
  .cv-hero__portrait img{ transform:none !important; transition:filter .3s linear; }
}
.cv-hero__name{
  font-family:var(--font-display); font-weight:800; font-size:clamp(38px,5.4vw,68px);
  line-height:1.02; letter-spacing:-.02em; margin:6px 0 18px;
}
.cv-hero__role{ font-family:var(--font-mono); font-size:13.5px; line-height:1.85; letter-spacing:.04em; color:#4d4d40; }
.cv-hero__lead{ font-size:16px; line-height:1.8; color:#3a3a30; margin:26px 0 28px; max-width:520px; }
.cv-hero__tags{ display:flex; flex-wrap:wrap; gap:9px; margin-bottom:34px; }
.cv-hero__actions{ display:flex; flex-wrap:wrap; gap:12px; }

.cv-section{ max-width:1200px; margin:0 auto; padding:70px 40px; }
.cv-split{ display:grid; grid-template-columns:0.8fr 1.2fr; gap:60px; align-items:start; }
.cv-split__label .h2{ margin-top:6px; }
.cv-split__body p{ font-size:16px; line-height:1.8; color:#3a3a30; margin-bottom:18px; }
.cv-split__body p:last-child{ margin-bottom:0; }
.cv-todo{
  font-family:var(--font-mono); font-style:normal; font-size:12px; font-weight:700;
  background:#f2e2b8; color:#6a5320; padding:2px 8px; border-radius:5px; margin-right:6px;
}

.cv-timeline{ list-style:none; display:flex; flex-direction:column; gap:34px; }
.cv-timeline__item{ padding-left:24px; border-left:1.5px solid rgba(23,25,15,.2); position:relative; }
.cv-timeline__item::before{
  content:""; position:absolute; left:-6px; top:6px; width:10px; height:10px;
  border-radius:50%; background:var(--green);
}
.cv-timeline__year{ font-family:var(--font-mono); font-size:12px; letter-spacing:.07em; color:#6b6b5c; }
.cv-timeline__role{ font-family:var(--font-display); font-weight:700; font-size:20px; margin:8px 0 4px; }
.cv-timeline__org{ font-family:var(--font-mono); font-size:13px; color:var(--green); margin-bottom:10px !important; }
.cv-timeline__desc{ font-size:14.5px !important; line-height:1.75 !important; color:#4d4d40 !important; }

.cv-skills{ display:grid; grid-template-columns:repeat(auto-fit,minmax(215px,1fr)); gap:36px 30px; }
.cv-skills__group h3{ font-family:var(--font-mono); font-size:12.5px; letter-spacing:.08em; text-transform:uppercase; color:#6b6b5c; margin-bottom:16px; }
.cv-skills__group ul{ list-style:none; display:flex; flex-direction:column; gap:11px; }
.cv-skills__group li{ font-size:15px; color:#3a3a30; padding-left:18px; position:relative; }
.cv-skills__group li::before{ content:"—"; position:absolute; left:0; color:var(--green); }

.cv-clients{ list-style:none; display:flex; flex-wrap:wrap; gap:9px; }
.cv-clients li{
  padding:9px 16px; border-radius:100px; border:1.5px solid rgba(23,25,15,.22);
  font-family:var(--font-mono); font-size:12.5px; font-weight:700; color:#3a3a30;
}
.nav__links a.is-current{ color:var(--green); font-weight:700; }

@media(max-width:900px){
  .cv-hero{ grid-template-columns:1fr; gap:36px; padding:130px 40px 60px; }
  .cv-hero__portrait{ max-width:300px; }
  .cv-split{ grid-template-columns:1fr; gap:26px; }
  .cv-skills{ grid-template-columns:1fr; gap:28px; }
}
@media(max-width:600px){
  .cv-hero, .cv-section{ padding-left:20px; padding-right:20px; }
}

/* .btn--solid/.btn--outline carry a global width:100% (inherited from the old
   price cards, where each button filled its card). In these inline button rows
   they should size to their own label instead. */
.cv-hero__actions .btn,
.brief__done-actions .btn,
.brief__nav .btn{ width:auto; }
@media(max-width:640px){
  .brief__nav .btn, .brief__done-actions .btn{ width:100%; }
}
.about__more{
  font-family:var(--font-mono); font-size:13px; font-weight:700; color:var(--green);
  text-decoration:underline; text-underline-offset:5px;
}
.about__more:hover{ color:var(--ink); }

.cv-skills__note{
  margin-top:34px; padding-top:24px; border-top:1.5px solid rgba(23,25,15,.14);
  font-size:14.5px !important; line-height:1.8 !important; color:#4d4d40 !important;
}
.cv-skills__note strong{ color:var(--ink); font-weight:700; }
.cv-clients__more{ background:var(--ink); border-color:var(--ink) !important; color:var(--cream) !important; }
.cv-clients__note{ margin-top:18px; font-family:var(--font-mono); font-size:11.5px; color:#6b6b5c; }

/* ================= CV PAGE — reading order, rhythm, motion ================= */
/* the About page doubles as the portfolio that gets emailed out, so it is
   ordered for a 10-second scan: who → proof numbers → actual work → what I can
   do → the long-form detail underneath. */

.cv-section--tight{ padding-top:20px; padding-bottom:40px; }

/* headline reveal: each line rides up out of its own clipped box */
.cv-hero__name{ overflow:hidden; }
.cv-line{ display:block; overflow:hidden; }
.cv-line > span{ display:block; }

/* --- selected work teaser --- */
.cv-work{ max-width:1200px; margin:0 auto; padding:30px 40px 90px; }
.cv-work__grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:18px; }
.cv-work__tile{ aspect-ratio:4/5; border-radius:16px; }
.cv-work__more{ margin-top:36px; text-align:center; }
.cv-work__more .btn{ width:auto; }

/* --- long-form readability --- */
.cv-split__body{ max-width:640px; }
.cv-lead-p{ font-size:17.5px !important; line-height:1.75 !important; color:var(--ink) !important; }
/* the section label parks itself while its body scrolls past, so you always
   know which part of the CV you are reading */
@media(min-width:901px){
  .cv-split__label{ position:sticky; top:118px; }
}

/* --- AI note --- */
/* no boxed frame: a single hairline rule and a quieter type colour keep this
   reading as a closing thought on the skills list rather than a callout card
   fighting the lists above it. */
.cv-note{
  margin-top:38px; padding-top:28px; border-top:1.5px solid rgba(23,25,15,.16);
}
.cv-note p{ font-size:15px !important; line-height:1.85 !important; color:#55554a !important; margin-bottom:15px !important; }
.cv-note p:last-child{ margin-bottom:0 !important; }
.cv-note strong{ color:var(--ink); font-weight:700; }

@media(max-width:900px){
  .cv-work__grid{ grid-template-columns:repeat(2,1fr); }
  .cv-work{ padding:40px 40px 60px; }
}
@media(max-width:600px){
  .cv-work{ padding-left:20px; padding-right:20px; }
  .cv-work__grid{ gap:12px; }
}

/* the AI group has the longest labels and would otherwise wrap under column 1
   leaving a hole beside it — give it the full row and split its own list */
.cv-skills__group:last-child{ grid-column:1 / -1; }
.cv-skills__group:last-child ul{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:11px 26px;
}
@media(max-width:600px){
  .cv-skills__group:last-child ul{ grid-template-columns:1fr; }
}

/* brief form opt-in gate */
.brief__gate{ text-align:center; }
.brief__gate .btn{ width:auto; }
.brief__gate-note{
  margin-top:16px; font-family:var(--font-mono); font-size:12px; color:#6b6b5c;
}

/* ================= THAI TYPOGRAPHY FIX =================
   Thai stacks up to two marks above a consonant and one below (เ ล ่ า, ก ต ์).
   Two things in the display styles were breaking that:
     1. negative letter-spacing — tracking is applied around each glyph, which
        drags combining marks off their base and produces the classic
        "สระลอย" (floating vowel/tone mark).
     2. line-height near 1.0 — leaves no room for the upper mark tier, so marks
        collide with the line above.
   Thai is the primary language here, so the safe metrics are the default and
   the tight Latin tracking is opted back in with [data-latin] on the handful
   of headings that contain no Thai at all. */
.h2,
.hero__title,
.hero__title--page,
.contact__title,
.cv-hero__name,
.work-divider__script,
.service-row__title,
.brief__q,
.price-card__name,
.cv-timeline__role,
.masonry__overlay h3,
.masonry__overlay-title{
  letter-spacing:normal;
}
.h2{ line-height:1.3; }
.contact__title{ line-height:1.18; }
.hero__title, .hero__title--page{ line-height:1.14; }
.cv-hero__name{ line-height:1.1; }
.service-row__title, .brief__q{ line-height:1.4; }

/* headings that are Latin-only keep the tighter display tracking.
   line-height here has to clear the font's descender (g/y/j/p/q), not just its
   cap height — these headings sit inside a per-line overflow:hidden box (used
   for the GSAP line-reveal), and anything tighter than ~1.15 clips descenders
   against that box. A clipped "g" reads as a different letter (e.g.
   "Pansungnoen" → "Pansunanoen"), which is worse than losing some tightness. */
/* -.02em previously here caused a second real-device failure independent of
   the line-height/descender issue above: "All Projects" (a plain heading with
   no per-line clip-box at all) had its "j" disappear on a real phone, which
   only makes sense as glyph-to-glyph kerning collision from the negative
   tracking itself, not a clipping box. Two unrelated failures from the same
   rule is enough to stop trusting it — tightened tracking saved very little
   visually at these sizes anyway, so it's now barely negative rather than
   removed outright, to keep some of the intended "designed" tightness. */
[data-latin]{ letter-spacing:-.005em !important; }
.h2[data-latin]{ line-height:1.18; }
.cv-hero__name[data-latin]{ line-height:1.18; }
.hero__title[data-latin]{ line-height:1.12; }

/* Thai body copy: a little more leading so upper marks never touch the line
   above, and no forced tracking on mono/eyebrow labels */
p, li, .brief__field span, .brief__hint{ text-rendering:optimizeLegibility; }

/* ---------- story beats + pull quote ----------
   The story used to be five equal paragraphs, which gave the eye no entry
   point. It is now three tagged beats (start → in-house → today) followed by a
   single pulled-out belief, so the section can be skimmed in one pass. */
.cv-beats{ list-style:none; margin:34px 0 0; display:flex; flex-direction:column; gap:2px; }
.cv-beat{
  display:grid; grid-template-columns:104px 1fr; gap:20px; align-items:start;
  padding:20px 0; border-top:1px solid rgba(23,25,15,.12);
}
.cv-beat:last-child{ border-bottom:1px solid rgba(23,25,15,.12); }
.cv-beat__tag{
  font-family:var(--font-mono); font-size:11.5px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--green); padding-top:3px;
}
.cv-beat p{ font-size:15px !important; line-height:1.75 !important; margin:0 !important; color:#3a3a30 !important; }
.cv-beat strong{ color:var(--ink); font-weight:700; }

.cv-quote{
  margin-top:38px; padding-left:22px; border-left:3px solid var(--green);
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(17px,1.9vw,22px); line-height:1.55; color:var(--ink);
}

.cv-note__claim{ margin-top:4px !important; }
.cv-note__claim strong{ color:var(--ink); }

@media(max-width:600px){
  .cv-beat{ grid-template-columns:1fr; gap:8px; }
  .cv-beat__tag{ padding-top:0; }
}

/* ---------- About page v2: fewer sections, no itemized skill/tool lists ----------
   A senior profile states experience and lets the work prove it, rather than
   enumerating every piece of software. These rules support the trimmed-down
   story/experience/clients sections; .cv-skills/.cv-beats/.cv-note above are
   now unused on this page but left in place in case a future page wants them. */
.stats--three{ grid-template-columns:repeat(3,1fr); }
@media(max-width:700px){ .stats--three{ grid-template-columns:1fr; gap:32px; } }

.cv-aside{
  margin-top:26px; font-family:var(--font-mono); font-size:13px; color:#6b6b5c;
}

.cv-timeline--compact .cv-timeline__item{ padding-bottom:0; }
.cv-timeline--compact .cv-timeline__role{ margin-bottom:2px !important; }
.cv-timeline--compact .cv-timeline__org{ margin-bottom:0 !important; }
.cv-edu-line{
  margin-top:30px; padding-top:22px; border-top:1px solid rgba(23,25,15,.12);
  font-family:var(--font-mono); font-size:12.5px; color:#6b6b5c;
}

.cv-clients-line{ font-size:17px !important; line-height:1.8 !important; color:var(--ink) !important; max-width:560px; }
.cv-clients-link{
  display:inline-block; margin-top:20px; font-family:var(--font-mono); font-size:13px; font-weight:700;
  color:var(--green); text-decoration:underline; text-underline-offset:5px;
}
.cv-clients-link:hover{ color:var(--ink); }

/* ---------- mobile perf: backdrop-filter is a known GPU/scroll-jank source on
   phones (Safari iOS especially recomposites it every frame something behind
   it moves). Both blurred layers sit over a near-opaque background already,
   so the blur itself was barely visible — drop it below the desktop
   breakpoint instead of paying for it on the weakest hardware. ---------- */
@media(max-width:820px){
  .lightbox__backdrop{ backdrop-filter:none; }
  .nav__scrim{ backdrop-filter:none; }
}
