
/* ═══════════════════════════════════════════════════════════════════════
   TOKENS — the bar generator
   The palette is a colour-bar test card pushed toy-bright. Six show
   colours, two grounds, and one rule: dark ink on every bright field
   except blue and violet. That is a broadcast caption convention and it
   is also the only way this much saturation stays readable.
   ═══════════════════════════════════════════════════════════════════ */
:root{
  /* show colours — constant across themes, they are the ink not the paper */
  --c-orange:#FF5B24;  --on-orange:#170F0A;
  --c-pink:#FF2E93;    --on-pink:#170F0A;
  --c-blue:#2B5CFF;    --on-blue:#FFFFFF;
  --c-yellow:#FFD426;  --on-yellow:#170F0A;
  --c-mint:#00D9A3;    --on-mint:#052A20;
  --c-violet:#7B3DFF;  --on-violet:#FFFFFF;

  /* ground — warm paper, the light a call sheet is printed on */
  --bg:#FFF7F0;  --bg-2:#FFEDE2;  --bg-3:#FFE3D2;
  --surface:#FFFFFF;
  --ink:#170F0A;  --ink-2:#6B564A;  --ink-3:#7A6152;
  --line:rgba(23,15,10,.13);
  --line-2:rgba(23,15,10,.26);
  --rule:#170F0A;              /* the hard structural rule */
  --veil:rgba(255,247,240,.82);

  /* Text-safe accents. The bright colours are for FIELDS. Set as small type
     on the page ground several of them fall under 4.5:1 — pink reads 3.0:1 on
     the cream. --acc-t is each accent walked toward black until it clears
     4.5:1 on --bg-2, the worst light ground. In dark mode the bright value is
     already light-on-dark, so --acc-t is just the accent itself. */
  --t-orange:#BF441B; --t-pink:#CC2475; --t-blue:#2B5CFF;
  --t-yellow:#7F6A13; --t-mint:#007D5E; --t-violet:#7B3DFF;

  /* the section accent. Every section overrides these and everything inside
     inherits — chips, rules, buttons, the canvas, the cursor. --acc paints,
     --on-acc is the ink on top of it, --acc-t is the accent as text. */
  --acc:var(--c-orange);
  --on-acc:var(--on-orange);
  --acc-t:var(--t-orange);

  /* depth — offset plus soft blur, never a flat halo */
  --sh-1:0 2px 5px -2px rgba(23,15,10,.10), 0 8px 22px -14px rgba(23,15,10,.22);
  --sh-2:0 6px 14px -7px rgba(23,15,10,.14), 0 30px 62px -34px rgba(23,15,10,.30);
  --sh-3:0 10px 22px -10px rgba(23,15,10,.18), 0 48px 90px -46px rgba(23,15,10,.36);
  --sh-lift:0 14px 26px -12px rgba(23,15,10,.20), 0 46px 84px -44px rgba(23,15,10,.34);

  /* type — back to IBM Plex, the family this site started on.
     Plex Sans Thai tops out at 700, so the display voice carries on size and
     tracking rather than on weight; Plex Mono returns for the things that are
     actually measurements: the timecode, the counters, the tabular figures. */
  --f-display:"IBM Plex Sans Thai",system-ui,-apple-system,sans-serif;
  --f-body:"IBM Plex Sans Thai",system-ui,-apple-system,sans-serif;
  /* IBM Plex Mono has no Thai glyphs, and neither do the generic fallbacks
     after it — so a kicker/tag/date label that happens to hold Thai text
     (the site is bilingual; whenTh, translated tag words, etc. all land in
     --f-mono spots) rendered as blank tofu boxes in Thai mode. IBM Plex Sans
     Thai closes that gap: Latin/numeric characters still take the tracked
     mono look, Thai characters fall through to a face that has them. */
  --f-mono:"IBM Plex Mono","IBM Plex Sans Thai",ui-monospace,SFMono-Regular,monospace;
  --measure:68ch;

  /* shape — playful, generous, never a hairline box */
  --r:12px;  --r-lg:22px;  --r-xl:34px;  --r-pill:999px;

  /* motion */
  --e-out:cubic-bezier(.16,1,.3,1);          /* exponential ease-out */
  --e-io:cubic-bezier(.76,0,.24,1);
  --e-in:cubic-bezier(.55,0,1,.45);
  --e-pop:linear(0,.0063 1.63%,.0242 3.35%,.0946 6.93%,.7113 26.42%,.8402 30.85%,.9426 35.4%,.9817 37.83%,1.0123 40.38%,1.0333 43.11%,1.0439 46.14%,1.0446 49.68%,1.0345 55.31%,1.0011 68.5%,.9968 74.36%,1);
  --t-fast:140ms;  --t-mid:280ms;  --t-slow:560ms;

  /* layout */
  --pad:clamp(18px,4.6vw,72px);
  --maxw:1520px;
  --nav-h:72px;

  --grain:.030;
  color-scheme:light;
}

:root[data-theme="dark"], :root[data-theme="dark"] ::backdrop{
  --bg:#120D0A;  --bg-2:#1B1310;  --bg-3:#251A15;
  --surface:#211711;
  --ink:#FFF6EF;  --ink-2:#C4AFA2;  --ink-3:#9C8474;
  --line:rgba(255,246,239,.14);
  --line-2:rgba(255,246,239,.30);
  --rule:#FFF6EF;
  --veil:rgba(18,13,10,.84);
  --c-orange:#FF7043;  --c-pink:#FF4FA6;  --c-blue:#5C82FF;
  --c-yellow:#FFDD52;  --c-mint:#1FE7B6;  --c-violet:#9A66FF;
  --on-blue:#0A0F2E;   --on-violet:#170A2E;
  --t-orange:var(--c-orange); --t-pink:var(--c-pink); --t-blue:var(--c-blue);
  --t-yellow:var(--c-yellow); --t-mint:var(--c-mint); --t-violet:var(--c-violet);
  --sh-1:0 2px 6px -2px rgba(0,0,0,.55), 0 10px 26px -16px rgba(0,0,0,.80);
  --sh-2:0 8px 18px -8px rgba(0,0,0,.62), 0 34px 70px -36px rgba(0,0,0,.88);
  --sh-3:0 12px 26px -12px rgba(0,0,0,.66), 0 54px 100px -48px rgba(0,0,0,.92);
  --sh-lift:0 16px 30px -14px rgba(0,0,0,.68), 0 52px 92px -46px rgba(0,0,0,.90);
  --grain:.052;
  color-scheme:dark;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#120D0A;  --bg-2:#1B1310;  --bg-3:#251A15;
    --surface:#211711;
    --ink:#FFF6EF;  --ink-2:#C4AFA2;  --ink-3:#9C8474;
    --line:rgba(255,246,239,.14);
    --line-2:rgba(255,246,239,.30);
    --rule:#FFF6EF;
    --veil:rgba(18,13,10,.84);
    --c-orange:#FF7043;  --c-pink:#FF4FA6;  --c-blue:#5C82FF;
    --c-yellow:#FFDD52;  --c-mint:#1FE7B6;  --c-violet:#9A66FF;
    --on-blue:#0A0F2E;   --on-violet:#170A2E;
    --t-orange:var(--c-orange); --t-pink:var(--c-pink); --t-blue:var(--c-blue);
    --t-yellow:var(--c-yellow); --t-mint:var(--c-mint); --t-violet:var(--c-violet);
    --sh-1:0 2px 6px -2px rgba(0,0,0,.55), 0 10px 26px -16px rgba(0,0,0,.80);
    --sh-2:0 8px 18px -8px rgba(0,0,0,.62), 0 34px 70px -36px rgba(0,0,0,.88);
    --sh-3:0 12px 26px -12px rgba(0,0,0,.66), 0 54px 100px -48px rgba(0,0,0,.92);
    --sh-lift:0 16px 30px -14px rgba(0,0,0,.68), 0 52px 92px -46px rgba(0,0,0,.90);
    --grain:.052;
    color-scheme:dark;
  }
}

/* Section accents. The show cuts between colours as you scroll; each
   section paints its own and everything inside inherits. */
[data-acc="orange"]{--acc:var(--c-orange); --on-acc:var(--on-orange); --acc-t:var(--t-orange)}
[data-acc="pink"]  {--acc:var(--c-pink);   --on-acc:var(--on-pink)}
[data-acc="blue"]  {--acc:var(--c-blue);   --on-acc:var(--on-blue)}
[data-acc="yellow"]{--acc:var(--c-yellow); --on-acc:var(--on-yellow); --acc-t:var(--t-yellow)}
[data-acc="mint"]  {--acc:var(--c-mint);   --on-acc:var(--on-mint)}
[data-acc="violet"]{--acc:var(--c-violet); --on-acc:var(--on-violet); --acc-t:var(--t-violet)}

/* ═══════════════════════════════════════════════════════════════ RESET */
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{
  font-family:var(--f-body); font-weight:400; font-size:16.5px; line-height:1.62;
  background:var(--bg); color:var(--ink);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  overflow-x:clip;
  transition:background-color .6s var(--e-out), color .6s var(--e-out);
}
body.is-locked{overflow:hidden}
img,svg,video,canvas{display:block; max-width:100%}
img{height:auto}
a{color:inherit; text-decoration:none}
button{font:inherit; color:inherit; background:none; border:0; cursor:pointer}
input,textarea,select{font:inherit; color:inherit}
ul,ol{list-style:none}

/* ── browser surfaces: the parts we did not draw still carry the design ── */
::selection{background:var(--acc); color:var(--on-acc); text-shadow:none}
input,textarea{caret-color:var(--acc)}
html{scrollbar-color:var(--line-2) transparent; scrollbar-width:thin}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--line-2); border-radius:var(--r-pill);
  border:3.5px solid var(--bg); background-clip:padding-box;
}
::-webkit-scrollbar-thumb:hover{background:var(--acc); background-clip:padding-box}
:focus-visible{
  outline:3px solid var(--acc); outline-offset:3px; border-radius:6px;
}
:focus:not(:focus-visible){outline:none}
/* Prose links get a real underline; navigation and controls do not. Scoped to
   running text so it cannot leak into the nav, the rail, or a card. */
.body a,.lede a,p a:not([class]){
  text-decoration:underline; text-underline-offset:.24em;
  text-decoration-thickness:1.5px; text-decoration-color:var(--acc);
}
[data-num],time,.tnum{font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1}
.tnum{font-family:var(--f-mono)}
::marker{color:var(--acc)}

/* ═══════════════════════════════════════════════════════════ TYPE SCALE */
.display{
  font-family:var(--f-display); font-weight:700; line-height:.88;
  letter-spacing:-.035em; text-transform:uppercase;
}
.h1{font-size:clamp(2.55rem,9.1vw,6.5rem)}
.h2{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.85rem,4.1vw,3.6rem); line-height:1.04;
  letter-spacing:-.03em; max-width:19ch; text-wrap:balance;
}
.h3{
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(1.18rem,2.05vw,1.72rem); line-height:1.16;
  letter-spacing:-.022em; text-wrap:balance;
}
.h4{
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(1rem,1.35vw,1.16rem); line-height:1.24; letter-spacing:-.012em;
}
.lede{font-size:clamp(1rem,1.28vw,1.16rem); line-height:1.66; color:var(--ink-2); max-width:58ch; text-wrap:pretty}
.body{max-width:var(--measure); text-wrap:pretty}
.tag{
  font-family:var(--f-mono); font-weight:500; font-size:.68rem;
  letter-spacing:.14em; text-transform:uppercase; line-height:1;
}
.muted{color:var(--ink-2)}

/* Thai needs air the Latin cut does not: taller line, looser tracking,
   and it never goes to caps because Thai has none. */
:lang(th) .display,:lang(th) .h1{letter-spacing:-.012em; line-height:1.04; text-transform:none}
:lang(th) .h2{letter-spacing:-.008em; line-height:1.22; text-transform:none}
:lang(th) .h3,:lang(th) .h4{letter-spacing:0; line-height:1.34}
:lang(th) body,:lang(th) .lede{line-height:1.78}
:lang(th) .tag{letter-spacing:.06em}

/* ═════════════════════════════════════════════════════════════ LAYOUT */
.wrap{width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad)}
.wrap-narrow{max-width:1100px}
section{position:relative}
.sec{padding-block:clamp(66px,8.2vw,132px)}
.sec-tight{padding-block:clamp(44px,5vw,76px)}

/* ═══════════════════════════════════════════════════════ SHOW FURNITURE */

/* film grain — the control-room monitor never sits perfectly clean */
.grain{
  position:fixed; inset:-40%; z-index:96; pointer-events:none; opacity:var(--grain);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay; will-change:transform;
  animation:grainShift 7s steps(7) infinite;
}
@keyframes grainShift{
  0%{transform:translate3d(0,0,0)}      14%{transform:translate3d(-3%,2%,0)}
  28%{transform:translate3d(2%,-3%,0)}  42%{transform:translate3d(-2%,-2%,0)}
  57%{transform:translate3d(3%,1%,0)}   71%{transform:translate3d(-1%,3%,0)}
  85%{transform:translate3d(2%,2%,0)}   100%{transform:translate3d(0,0,0)}
}

/* the scrub bar — reads as a transport, not a hairline */
.scrub{
  position:fixed; inset-inline:0; top:0; height:4px; z-index:88;
  pointer-events:none; background:transparent;
}
.scrub i{
  display:block; height:100%; width:100%;
  transform-origin:0 50%; transform:scaleX(var(--sp,0));
  background:linear-gradient(90deg,var(--c-orange),var(--c-pink) 34%,var(--c-violet) 62%,var(--c-blue));
  transition:transform .08s linear;
}

/* ═══════════════════════════════════════════════════════════ CONTROLS */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:54px; padding:0 26px; border-radius:var(--r-pill); white-space:nowrap;
  font-family:var(--f-display); font-weight:600; font-size:.96rem; letter-spacing:-.004em;
  border:2px solid transparent; position:relative; isolation:isolate;
  transition:transform var(--t-fast) var(--e-out),
             background-color var(--t-mid) var(--e-out),
             border-color var(--t-mid) var(--e-out),
             color var(--t-mid) var(--e-out),
             box-shadow var(--t-mid) var(--e-out);
}
.btn svg{width:18px; height:18px; flex:none}
.btn-p{background:var(--acc); color:var(--on-acc); box-shadow:var(--sh-1)}
.btn-p:hover{box-shadow:var(--sh-lift); transform:translateY(-2px)}
.btn-s{border-color:var(--line-2); color:var(--ink)}
.btn-s:hover{border-color:var(--acc); color:var(--acc-t); transform:translateY(-2px)}
.btn:active{transform:translateY(0) scale(.975)}
.btn .ico-go{transition:transform var(--t-mid) var(--e-out)}
.btn:hover .ico-go{transform:translateX(4px)}

/* chips — the tally strip vocabulary */
.chip{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  min-height:40px; padding:0 14px; border-radius:var(--r-pill);
  border:1.5px solid var(--line-2); background:var(--surface); color:var(--ink-2);
  font-family:var(--f-mono); font-weight:500; font-size:.69rem;
  letter-spacing:.1em; text-transform:uppercase; line-height:1;
  transition:border-color var(--t-mid) var(--e-out), color var(--t-mid) var(--e-out),
             transform var(--t-fast) var(--e-out), background-color var(--t-mid) var(--e-out);
}
.chip:hover{border-color:var(--acc); color:var(--ink)}
.chip:active{transform:scale(.94)}
.chip svg{width:16px; height:16px; flex:none}

/* the tally light. Red when live, and it actually breathes. */
.tally{
  display:inline-flex; align-items:center; gap:9px;
  padding:8px 16px 8px 13px; border-radius:var(--r-pill);
  background:var(--acc); color:var(--on-acc);
  font-family:var(--f-mono); font-weight:600; font-size:.68rem;
  letter-spacing:.16em; text-transform:uppercase; line-height:1;
}
:lang(th) .tally{letter-spacing:.04em}
.tally s{
  width:9px; height:9px; border-radius:50%; background:currentColor;
  text-decoration:none; flex:none; animation:tallyPulse 1.9s var(--e-io) infinite;
}
@keyframes tallyPulse{
  0%,100%{opacity:1; transform:scale(1)}
  50%{opacity:.28; transform:scale(.72)}
}

/* ═══════════════════════════════════════════════════════ REVEAL LAYER
   Everything is visible by default and the .in class is what animates.
   No content is ever hidden behind a script that failed to run. */
[data-rv]{
  opacity:0; transform:translate3d(0,26px,0);
  transition:opacity .72s var(--e-out) var(--d,0ms), transform .72s var(--e-out) var(--d,0ms);
}
[data-rv].in{opacity:1; transform:none}
[data-rv="fade"]{transform:none}
[data-rv="scale"]{transform:translate3d(0,20px,0) scale(.955)}
[data-rv="scale"].in{transform:none}
[data-rv="left"]{transform:translate3d(-30px,0,0)}
[data-rv="right"]{transform:translate3d(30px,0,0)}
[data-rv="clip"]{
  opacity:1; transform:none; clip-path:inset(0 0 102% 0);
  transition:clip-path .9s var(--e-out) var(--d,0ms);
}
[data-rv="clip"].in{clip-path:inset(0 0 -12% 0)}
[data-rv="wipe"]{
  opacity:1; transform:none; clip-path:inset(0 102% 0 0);
  transition:clip-path .8s var(--e-io) var(--d,0ms);
}
[data-rv="wipe"].in{clip-path:inset(0 -2% 0 0)}
/* body.no-js is removed by the first line of the script. While it is still
   there — script blocked, script threw, script never arrived — the page has
   to be readable, which means no reveal is allowed to hide content and the
   preroll is not allowed to exist at all. Without this rule a visitor with
   JavaScript off sees a full-screen overlay and nothing else. */
.no-js [data-rv]{opacity:1 !important; transform:none !important; clip-path:none !important}
.no-js .pre,.no-js .cursor,.no-js .scrub{display:none !important}
.no-js .hero-name .ch{transform:none !important}

/* per-character hero cut-in */
.ln{display:block; overflow:hidden; padding-block:.02em .12em}
:lang(th) .ln{padding-block:.1em .16em}
.ch{display:inline-block; will-change:transform}

/* ══════════════════════════════════════════════════ REDUCED MOTION
   Kill travel and loops. Keep colour, keep state, keep everything
   readable — a stilled page is not a broken one. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
  [data-rv]{opacity:1 !important; transform:none !important; clip-path:none !important}
  .grain{animation:none}
}

/* ═══════════════════════════════════════════════════════════════════════
   b-css2 — the sections.
   Tokens, type, buttons, chips and the reveal primitives live in a-head.
   Everything here is composition. Class names and the state classes JS
   toggles are fixed by CONTRACT.md.
   ═══════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════ SKIP LINK */
.skip{
  position:fixed; top:10px; left:10px; z-index:200;
  padding:12px 20px; border-radius:var(--r-pill);
  background:var(--c-orange); color:var(--on-orange);
  font-family:var(--f-display); font-weight:700; font-size:.9rem;
  transform:translateY(-180%); transition:transform var(--t-mid) var(--e-out);
}
.skip:focus-visible{transform:none}

/* ══════════════════════════════════════════════════════ CUSTOM CURSOR
   Two parts: a ring that lags and grows, and a label plate that only
   appears over something you can actually open. */
.cursor{
  position:fixed; left:0; top:0; z-index:190; pointer-events:none;
  translate:var(--x,-200px) var(--y,-200px);
  opacity:0; transition:opacity .28s var(--e-out);
}
.cursor.on{opacity:1}
.cursor i,.cursor b{
  position:absolute; left:0; top:0; display:block; border-radius:50%;
  transform:translate(-50%,-50%);
}
.cursor i{
  width:32px; height:32px; border:2px solid var(--acc-now,var(--c-orange));
  transform:translate(-50%,-50%) scale(1);
  transition:transform .34s var(--e-out), background-color .34s var(--e-out),
             border-color .3s var(--e-out), opacity .26s var(--e-out);
}
.cursor b{
  width:76px; height:76px; display:grid; place-items:center;
  background:var(--acc-now,var(--c-orange)); color:var(--on-acc-now,var(--on-orange));
  font-family:var(--f-display); font-weight:700; font-size:.74rem;
  letter-spacing:.03em; text-align:center; line-height:1.1; padding:6px;
  opacity:0; scale:.4;
  transition:opacity .3s var(--e-out), scale .42s var(--e-pop);
}
.cursor.grow i{transform:translate(-50%,-50%) scale(1.7);
  background:color-mix(in srgb,var(--acc-now,var(--c-orange)) 16%,transparent)}
.cursor.view i{opacity:0}
.cursor.view b{opacity:1; scale:1}
@media (pointer:coarse),(prefers-reduced-motion:reduce){.cursor{display:none}}

/* ═══════════════════════════════════════════════════════════ PREROLL
   Colour bars stand up, the leader counts, the whole thing wipes off the
   top. The only full-screen moment in the build. */
.pre{
  position:fixed; inset:0; z-index:150; background:var(--bg);
  display:grid; place-items:center; overflow:hidden;
  clip-path:inset(0 0 0 0);
  transition:clip-path .82s var(--e-io) .1s, opacity .38s var(--e-out) .52s;
}
.pre.done{clip-path:inset(0 0 100% 0); opacity:0; pointer-events:none}
.pre-bars{position:absolute; inset:0; display:grid; grid-template-columns:repeat(6,1fr)}
.pre-bars s{
  display:block; text-decoration:none; transform-origin:50% 100%; opacity:.15;
  transform:scaleY(0); animation:barUp .74s var(--e-out) forwards;
  animation-delay:calc(var(--i) * 62ms);
}
.pre-bars s:nth-child(1){background:var(--c-orange)}
.pre-bars s:nth-child(2){background:var(--c-pink)}
.pre-bars s:nth-child(3){background:var(--c-violet)}
.pre-bars s:nth-child(4){background:var(--c-blue)}
.pre-bars s:nth-child(5){background:var(--c-mint)}
.pre-bars s:nth-child(6){background:var(--c-yellow)}
@keyframes barUp{to{transform:scaleY(1)}}

.pre-inner{
  position:relative; z-index:2; display:flex; flex-direction:column;
  align-items:center; gap:28px; width:min(520px,78vw);
}
.pre-lead{position:relative; width:128px; height:128px; display:grid; place-items:center}
.pre-lead svg{position:absolute; inset:0; width:100%; height:100%; overflow:visible}
.pre-ring{fill:none; stroke:var(--line); stroke-width:2}
.pre-arc{
  fill:none; stroke:var(--c-orange); stroke-width:3; stroke-linecap:round;
  stroke-dasharray:327; stroke-dashoffset:327;
  transform:rotate(-90deg); transform-origin:50% 50%;
  animation:leadSweep 1.7s var(--e-io) infinite;
}
@keyframes leadSweep{
  0%{stroke-dashoffset:327} 55%{stroke-dashoffset:64} 100%{stroke-dashoffset:-327}
}
.pre-cross{stroke:var(--line); stroke-width:1.4}
.pre-num{
  position:relative; z-index:2;
  font-family:var(--f-mono); font-weight:500; font-size:2.4rem;
  letter-spacing:-.045em; line-height:1; color:var(--ink);
}
.pre-row{display:flex; justify-content:space-between; align-items:baseline; width:100%; gap:16px}
.pre-name{font-family:var(--f-display); font-weight:700; font-size:.86rem; letter-spacing:-.015em}
.pre-say{font-weight:600; font-size:.7rem; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-3)}
:lang(th) .pre-say{letter-spacing:.05em}
.pre-bar{width:100%; height:3px; background:var(--line); border-radius:var(--r-pill); overflow:hidden}
.pre-bar i{
  display:block; height:100%; width:100%; border-radius:inherit;
  background:linear-gradient(90deg,var(--c-orange),var(--c-pink) 50%,var(--c-violet));
  transform-origin:0 50%; transform:scaleX(var(--p,0));
  transition:transform .3s var(--e-out);
}

/* ═══════════════════════════════════════════════════════════════ NAV */
.nav{
  position:fixed; inset-inline:0; top:0; z-index:100; height:var(--nav-h);
  display:flex; align-items:center;
  background:color-mix(in srgb,var(--bg) 76%,transparent);
  backdrop-filter:blur(18px) saturate(160%); -webkit-backdrop-filter:blur(18px) saturate(160%);
  border-bottom:1.5px solid transparent;
  transition:transform .42s var(--e-out), border-color .34s var(--e-out),
             background-color .34s var(--e-out);
}
.nav.stuck{border-bottom-color:var(--line)}
.nav.hide{transform:translateY(-102%)}
.nav .wrap{display:flex; align-items:center; justify-content:space-between; gap:18px; width:100%}

.brand{
  display:flex; align-items:center; gap:11px;
  font-family:var(--f-display); font-weight:700; font-size:1.04rem; letter-spacing:-.03em;
  translate:var(--mx,0) var(--my,0); transition:translate .4s var(--e-out);
}
.brand-mark{display:flex; gap:2.5px; flex:none}
.brand-mark i{
  display:block; width:4.5px; height:22px; border-radius:2px;
  transform-origin:50% 100%; transition:transform .38s var(--e-pop);
}
.brand-mark i:nth-child(1){background:var(--c-orange)}
.brand-mark i:nth-child(2){background:var(--c-pink); transition-delay:40ms}
.brand-mark i:nth-child(3){background:var(--c-blue); transition-delay:80ms}
.brand:hover .brand-mark i{transform:scaleY(.62)}
.brand:hover .brand-mark i:nth-child(2){transform:scaleY(1.18)}

.nav-links{display:flex; align-items:center; gap:2px; position:relative}
.nav-links a{
  position:relative; z-index:2; padding:9px 14px; border-radius:var(--r-pill);
  font-family:var(--f-body); font-weight:600; font-size:.86rem; white-space:nowrap;
  color:var(--ink-2); transition:color .26s var(--e-out);
}
.nav-links a:hover{color:var(--ink)}
.nav-links a.on{color:var(--on-acc-now,var(--ink))}
.nav-ink{
  position:absolute; z-index:1; left:0; top:50%; height:36px;
  width:var(--w,0); translate:var(--x,0) -50%;
  border-radius:var(--r-pill); background:var(--acc-now,var(--c-orange)); opacity:0;
  /* width is animated on purpose. The pill is absolutely positioned, so it is
     out of flow and reflows nothing but itself, and it only moves when the
     section in view changes -- not every frame. A scaleX would distort the
     end caps at this radius. */
  transition:translate .46s var(--e-out), width .46s var(--e-out),
             opacity .3s var(--e-out), background-color .5s var(--e-out);
}
.nav-ink.on{opacity:1}

.nav-tools{display:flex; align-items:center; gap:8px}
.chip.mag{translate:var(--mx,0) var(--my,0)}
.lang-chip{width:66px; overflow:hidden; position:relative}
.lang-chip i{font-style:normal; display:block; transition:transform .42s var(--e-out), opacity .26s}
.lang-chip.swap i{transform:translateY(-140%); opacity:0}
#themeLbl{font-size:.68rem}
.burger{display:none; width:44px; padding:0}
.burger span{
  display:block; width:17px; height:2px; background:currentColor; border-radius:2px;
  position:relative; transition:transform .34s var(--e-out);
}
.burger span::before,.burger span::after{
  content:""; position:absolute; left:0; width:17px; height:2px;
  background:currentColor; border-radius:2px;
  transition:transform .34s var(--e-out), opacity .2s;
}
.burger span::before{top:-6px} .burger span::after{top:6px}
.burger.open span{transform:rotate(45deg)}
.burger.open span::before{transform:translateY(6px) rotate(-90deg)}
.burger.open span::after{opacity:0; transform:translateY(-6px)}

/* ══════════════════════════════════════════════════════════════ HERO */
.hero{
  position:relative; min-height:100svh; display:flex; flex-direction:column;
  justify-content:flex-end; padding-top:calc(var(--nav-h) + 22px);
  padding-bottom:clamp(22px,3.4vw,46px); overflow:clip;
}
.bars{
  position:absolute; inset:0; width:100%; height:100%; z-index:0;
  filter:blur(34px) saturate(200%); opacity:1; transform:scale(1.1);
}
:root[data-theme="dark"] .bars{opacity:.8; filter:blur(38px) saturate(165%)}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .bars{opacity:.8; filter:blur(38px) saturate(165%)}
}
/* The veil is directional, not a uniform fade: colour stays committed across
   the top and behind the portrait, and one clean pocket opens at the lower
   left where the name and the copy have to be read. */
.bars-veil{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    radial-gradient(86% 68% at 12% 88%, var(--bg) 14%,
                    color-mix(in srgb,var(--bg) 55%,transparent) 48%, transparent 72%),
    linear-gradient(to bottom, transparent 46%,
                    color-mix(in srgb,var(--bg) 72%,transparent) 78%, var(--bg) 99%);
}
.hero-wrap{position:relative; z-index:2; display:grid; gap:clamp(24px,3.4vw,46px)}

/* The portrait sets the row height; the copy centres against it rather than
   sitting on its baseline, which otherwise strands the name in the lower
   third under a viewport of empty wash. */
.hero-stage{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.6fr);
  gap:clamp(18px,3vw,52px); align-items:stretch;
}
.hero-copy{display:grid; gap:clamp(13px,1.7vw,21px); align-content:center; min-width:0}
.hero-tally{justify-self:start}
/* --fit is a multiplier the script writes after measuring the longest line:
   1 when the name fits, less when Thai runs long. It scales the clamp, it is
   not a length. */
.hero-name{
  margin:0; color:var(--ink);
  font-size:calc(clamp(2.6rem,10.8vw,7.6rem) * var(--fit,1));
}
.hero-name .ln{display:block; overflow:hidden}
.hero-name .ch{
  display:inline-block; transform:translate3d(0,106%,0) rotate(3.5deg);
  transition:transform .86s var(--e-out);
  transition-delay:calc(var(--i) * 26ms + 110ms);
}
.hero-name.in .ch{transform:none}
.hero-name .ch.sp{width:.26em}
.hero-say{max-width:44ch}

.hero-figure{position:relative; margin:0; align-self:end; min-width:0}
/* The portrait asset alpha-fades out over its bottom fifth, so the plate is
   anchored to the baseline and the figure dissolves into it. Ending the
   plate early instead leaves a visible seam where the fade crosses it. */
.hero-plate{
  position:absolute; inset:auto 0 0 0; height:72%; z-index:0;
  border-radius:var(--r-xl) var(--r-xl) 0 0; background:var(--c-orange);
  transform:translateX(4%) rotate(-2.4deg); transform-origin:50% 100%;
}
.hero-figure img{
  position:relative; z-index:1; width:100%; height:auto;
  object-fit:contain; object-position:bottom center;
  max-height:min(60svh,600px); margin-inline:auto;
  filter:drop-shadow(0 24px 44px rgba(23,15,10,.30));
}
:root[data-theme="dark"] .hero-figure img{filter:drop-shadow(0 24px 44px rgba(0,0,0,.62))}
.hero-badge{
  position:absolute; z-index:2; left:-7%; bottom:11%;
  width:clamp(82px,8.6vw,114px); aspect-ratio:1;
  display:grid; place-items:center; border-radius:50%;
  background:var(--c-yellow); color:var(--on-yellow); box-shadow:var(--sh-2);
}
.hero-badge svg{width:100%; height:100%; animation:badgeSpin 19s linear infinite}
.hero-badge text{font-family:var(--f-display); font-weight:700; font-size:9.2px;
  letter-spacing:.055em; fill:currentColor}
@keyframes badgeSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.hero-badge svg{animation:none}}

.rail{
  display:flex; flex-wrap:wrap; align-items:center; gap:clamp(13px,2vw,28px);
  padding-top:clamp(17px,2.2vw,25px); border-top:1.5px solid var(--line);
}
.rail-time{
  font-family:var(--f-mono); font-weight:500; font-size:.78rem; letter-spacing:.04em;
  color:var(--ink-3); padding:6px 12px; border-radius:var(--r-pill); border:1.5px solid var(--line);
}
.rail-fact{display:flex; align-items:baseline; gap:8px; font-size:.9rem; color:var(--ink-2)}
.rail-fact b{font-family:var(--f-display); font-weight:700; font-size:1.32rem;
  letter-spacing:-.03em; color:var(--ink)}
.rail-acts{display:flex; flex-wrap:wrap; gap:10px; margin-inline-start:auto}
.btn.mag{translate:var(--mx,0) var(--my,0)}

.hero-scroll{
  position:absolute; left:50%; bottom:10px; z-index:3; translate:-50% 0;
  width:22px; height:34px; border:1.5px solid var(--line-2); border-radius:var(--r-pill);
  display:grid; justify-items:center; padding-top:6px;
}
.hero-scroll i{display:block; width:3px; height:7px; border-radius:2px; background:var(--acc);
  animation:scrollHint 2s var(--e-io) infinite}
@keyframes scrollHint{
  0%{transform:translateY(0); opacity:0} 22%{opacity:1}
  70%{transform:translateY(12px); opacity:0} 100%{opacity:0}
}
@media (max-width:900px){.hero-scroll{display:none}}

/* ════════════════════════════════════════════════════════════ TICKER */
.mq{border-block:1.5px solid var(--rule); background:var(--c-yellow); color:var(--on-yellow); overflow:hidden}
.mq-row{overflow:hidden; display:flex; padding-block:11px}
.mq-row-b{border-top:1.5px solid color-mix(in srgb,var(--on-yellow) 20%,transparent)}
.mq-track{display:flex; flex:none; will-change:transform;
  animation:mqRun var(--sec,26s) linear infinite}
.mq-row[data-dir="-1"] .mq-track{animation-direction:reverse}
.mq:hover .mq-track{animation-play-state:paused}
@keyframes mqRun{to{transform:translate3d(-50%,0,0)}}
.mq-run{display:flex; align-items:center; flex:none}
.mq-run b{
  font-family:var(--f-display); font-weight:700; font-size:clamp(1.02rem,1.75vw,1.46rem);
  letter-spacing:-.022em; white-space:nowrap; text-transform:uppercase;
}
:lang(th) .mq-run b{text-transform:none; letter-spacing:0}
.mq-dot{font-size:0; line-height:0; flex:none;
  width:clamp(26px,2.6vw,44px); display:grid; place-items:center}
.mq-dot::before{
  content:""; width:7px; height:7px; background:currentColor;
  border-radius:1.5px; transform:rotate(45deg); opacity:.5;
}
@media (prefers-reduced-motion:reduce){.mq-track{animation:none}}

/* ═════════════════════════════════════════════════════════════ STATS
   Drenched: the strip owns its colour edge to edge. */
.statsec{background:var(--acc); color:var(--on-acc); border-bottom:1.5px solid var(--rule)}
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(198px,1fr)); gap:clamp(20px,2.6vw,38px)}
.stat{
  display:grid; gap:8px; align-content:start; padding-inline-start:18px;
  border-inline-start:2px solid color-mix(in srgb,var(--on-acc) 32%,transparent);
}
.stat-n{
  font-family:var(--f-mono); font-weight:600; line-height:.92;
  font-size:clamp(2.2rem,4vw,3.5rem); letter-spacing:-.045em;
}
.stat span{font-size:.92rem; line-height:1.5; max-width:26ch;
  color:var(--on-acc); opacity:.9}

/* ═════════════════════════════════════════════════ SECTION HEADINGS */
.shead{display:grid; gap:13px; margin-bottom:clamp(32px,4.4vw,62px); max-width:62ch}
.shead .h2{color:var(--ink)}

/* ══════════════════════════════════════════ WORK / THE MULTIVIEWER
   Five feeds. Each owns a colour, alternates side, leans on the scroll.
   No cards — a monitor is a framed image with a tally edge. */
.work{background:var(--bg)}
.mv{display:grid; gap:clamp(54px,7.6vw,126px)}
.mv-item{
  display:grid; grid-template-columns:minmax(0,1.26fr) minmax(0,1fr);
  gap:clamp(20px,3.4vw,56px); align-items:center;
  padding-inline:var(--pad); max-width:var(--maxw); margin-inline:auto; width:100%;
  opacity:0; transform:translate3d(0,42px,0);
  transition:opacity .8s var(--e-out), transform .8s var(--e-out);
}
.mv-item.in{opacity:1; transform:none}
.mv-item:nth-child(even){grid-template-columns:minmax(0,1fr) minmax(0,1.26fr)}
.mv-item:nth-child(even) .mv-shot{order:2}
.mv-item:nth-child(even) .mv-meta{order:1}

.mv-shot{
  position:relative; overflow:hidden; border-radius:var(--r-lg);
  border:1.5px solid var(--line); background:var(--bg-2);
  aspect-ratio:16/10; box-shadow:var(--sh-2);
  transition:box-shadow .5s var(--e-out), border-color .5s var(--e-out);
}
.mv-item.on .mv-shot{box-shadow:var(--sh-3); border-color:color-mix(in srgb,var(--acc) 52%,var(--line))}
.mv-shot img{
  width:100%; height:118%; object-fit:cover;
  transform:translate3d(0,calc(var(--pr,.5) * -14%),0) scale(1.02);
  will-change:transform;
}
.mv-shot::after{
  content:""; position:absolute; inset-inline:0; bottom:0; height:4px; background:var(--acc);
  transform-origin:0 50%; transform:scaleX(0); transition:transform .72s var(--e-out);
}
.mv-item.on .mv-shot::after{transform:scaleX(1)}
.mv-year{
  position:absolute; top:14px; left:14px; z-index:2; padding:7px 13px;
  border-radius:var(--r-pill); background:var(--acc); color:var(--on-acc);
  font-family:var(--f-mono); font-weight:500; font-size:.74rem; letter-spacing:.04em;
}

.mv-meta{display:grid; gap:15px; align-content:center; min-width:0}
.mv-title{color:var(--ink); max-width:18ch}
.mv-roles{display:flex; flex-wrap:wrap; gap:7px}
.mv-roles li{
  padding:6px 13px; border-radius:var(--r-pill); color:var(--ink);
  border:1.5px solid color-mix(in srgb,var(--acc) 44%,transparent);
  background:color-mix(in srgb,var(--acc) 11%,transparent);
  font-weight:600; font-size:.76rem; letter-spacing:.01em;
}
.mv-desc{color:var(--ink-2); max-width:46ch}
.mv-thumbs{display:flex; gap:10px; margin-top:3px}
.mv-thumb{
  width:88px; aspect-ratio:4/3; overflow:hidden; border-radius:var(--r); flex:none;
  border:1.5px solid var(--line); background:var(--bg-2);
  transition:transform .34s var(--e-out), border-color .3s var(--e-out);
}
.mv-thumb img{width:100%; height:100%; object-fit:cover; transition:scale .5s var(--e-out)}
.mv-thumb:hover{transform:translateY(-3px); border-color:var(--acc)}
.mv-thumb:hover img{scale:1.08}

/* ═══════════════════════════════════════════ PATH / THE RUNDOWN
   A run of show: the line draws itself as you read down it. */
.path{background:var(--bg-2); border-block:1.5px solid var(--line)}
.tl{position:relative; display:grid; gap:clamp(30px,4vw,50px); padding-inline-start:clamp(26px,4vw,58px)}
.tl-line{position:absolute; left:0; top:6px; bottom:6px; width:2px; background:var(--line)}
.tl-line i{
  position:absolute; inset:0 0 auto 0; width:100%; height:calc(var(--dl,0) * 100%);
  background:linear-gradient(to bottom,var(--c-pink),var(--c-violet)); border-radius:2px;
}
.tl-item{
  position:relative; display:grid;
  grid-template-columns:minmax(148px,.3fr) minmax(0,1fr); gap:clamp(14px,2.4vw,40px);
  opacity:0; transform:translate3d(0,30px,0);
  transition:opacity .72s var(--e-out), transform .72s var(--e-out);
}
.tl-item.in{opacity:1; transform:none}
.tl-item::before{
  content:""; position:absolute; left:calc(clamp(26px,4vw,58px) * -1); top:.6em;
  width:11px; height:11px; border-radius:50%; translate:-4.5px 0;
  background:var(--bg-2); border:2.5px solid var(--acc); scale:0;
  transition:scale .52s var(--e-pop) .12s;
}
.tl-item.in::before{scale:1}
.tl-item:first-of-type::before{background:var(--acc)}
.tl-when{font-family:var(--f-mono); font-weight:500; font-size:.8rem;
  letter-spacing:.03em; color:var(--acc-t); padding-top:.14em}
.tl-body{display:grid; gap:10px; min-width:0}
.tl-body .h3{color:var(--ink)}
.tl-org{font-weight:600; font-size:.94rem; color:var(--ink-2)}
.tl-desc{color:var(--ink-2); max-width:56ch}
.tl-wins{display:flex; flex-wrap:wrap; gap:7px; margin-top:2px}
.tl-wins li{
  padding:5px 12px; border-radius:var(--r-pill); color:var(--ink);
  background:color-mix(in srgb,var(--acc) 14%,transparent);
  border:1.5px solid color-mix(in srgb,var(--acc) 36%,transparent);
  font-weight:600; font-size:.75rem;
}

.also{margin-top:clamp(32px,4.4vw,54px); padding-top:clamp(24px,3vw,34px); border-top:1.5px solid var(--line)}
.also-label{color:var(--ink-3); margin-bottom:13px; display:block}
.also-list{display:grid; gap:9px}
.also-list li{position:relative; padding-inline-start:22px; color:var(--ink-2); font-size:.95rem}
.also-list li::before{
  content:""; position:absolute; left:0; top:.62em; width:9px; height:2px;
  background:var(--acc); border-radius:2px;
}

/* ═════════════════════════════════════════════════════ CRAFT / THE WALL
   True masonry via multicol; --ratio holds each slot before the image
   lands so the wall never reflows under the reader. */
.craft{background:var(--bg)}
.craft-grid{columns:var(--cols,4); column-gap:clamp(10px,1.2vw,17px)}
.craft-card{
  display:block; width:100%; break-inside:avoid; margin-bottom:clamp(10px,1.2vw,17px);
  position:relative; overflow:hidden; border-radius:var(--r);
  border:1.5px solid var(--line); background:var(--bg-2);
  opacity:0; transform:translate3d(0,24px,0);
  transition:opacity .62s var(--e-out), transform .62s var(--e-out),
             border-color .34s var(--e-out), box-shadow .38s var(--e-out);
  transition-delay:calc(min(var(--i,0),12) * 34ms);
}
.craft-card.in{opacity:1; transform:none}
.craft-card img{width:100%; aspect-ratio:var(--ratio,1); object-fit:cover;
  transition:scale .62s var(--e-out)}
.craft-card:hover{border-color:var(--acc); box-shadow:var(--sh-2)}
.craft-card:hover img{scale:1.05}
.craft-cap{
  position:absolute; inset:auto 0 0 0; padding:26px 13px 11px;
  font-weight:600; font-size:.8rem; line-height:1.35; text-align:left; color:#FFF;
  background:linear-gradient(to top,rgba(10,6,4,.88),rgba(10,6,4,0));
  opacity:0; translate:0 8px;
  transition:opacity .34s var(--e-out), translate .38s var(--e-out);
}
.craft-card:hover .craft-cap,.craft-card:focus-visible .craft-cap{opacity:1; translate:0}
.craft-more{margin-top:clamp(26px,3.2vw,38px)}

/* ═══════════════════════════════════════════════════════════ SKILLS
   Four columns, four colours, each under its own rule. Not cards. */
.skills{background:var(--bg-2); border-block:1.5px solid var(--line)}
.skill-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(228px,1fr)); gap:clamp(18px,2.4vw,32px)}
.skill{
  position:relative; display:grid; gap:14px; align-content:start;
  padding-top:21px; border-top:3px solid var(--acc);
  opacity:0; transform:translate3d(0,26px,0);
  transition:opacity .68s var(--e-out), transform .68s var(--e-out);
  transition-delay:calc(var(--i) * 88ms);
}
.skill.in{opacity:1; transform:none}
.skill-ico{
  width:46px; height:46px; display:grid; place-items:center; border-radius:var(--r);
  background:var(--acc); color:var(--on-acc); transition:transform .44s var(--e-pop);
}
.skill:hover .skill-ico{transform:rotate(-7deg) scale(1.07)}
.skill-ico svg{width:24px; height:24px}
.skill .h4{color:var(--ink)}
.skill ul{display:grid; gap:8px}
.skill li{position:relative; padding-inline-start:19px; font-size:.92rem; color:var(--ink-2)}
.skill li::before{
  content:""; position:absolute; left:0; top:.58em; width:8px; height:8px;
  border-radius:2px; background:var(--acc); opacity:.6;
}

/* ════════════════════════════════════════════════════════ DOCUMENTS */
.docs{background:var(--bg)}
/* 380 not 308: at four across the titles wrapped to two lines and the row
   stopped scanning. Three across gives every title one line. */
.doc-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(378px,1fr)); gap:clamp(12px,1.5vw,17px)}
.doc{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto auto; align-items:center;
  gap:16px; padding:18px 20px; border-radius:var(--r-lg);
  border:1.5px solid var(--line); background:var(--surface);
  translate:var(--mx,0) var(--my,0);
  opacity:0; transform:translate3d(0,20px,0);
  transition:opacity .6s var(--e-out), transform .6s var(--e-out),
             translate .4s var(--e-out), border-color .3s var(--e-out),
             box-shadow .34s var(--e-out);
  transition-delay:calc(var(--i) * 62ms);
}
.doc.in{opacity:1; transform:none}
.doc:hover{border-color:var(--acc); box-shadow:var(--sh-2)}
.doc-ico{
  width:44px; height:44px; display:grid; place-items:center; border-radius:var(--r);
  background:color-mix(in srgb,var(--acc) 17%,transparent); color:var(--acc-t);
  transition:background-color .3s var(--e-out), color .3s var(--e-out);
}
.doc:hover .doc-ico{background:var(--acc); color:var(--on-acc)}
.doc-ico svg{width:22px; height:22px}
.doc-body{display:grid; gap:3px; min-width:0}
.doc-body b{color:var(--ink); font-weight:700}
.doc-body span{font-size:.85rem; color:var(--ink-2); line-height:1.45}
.doc-ext{
  font-family:var(--f-mono); font-weight:500; font-size:.66rem; letter-spacing:.08em;
  padding:5px 9px; border-radius:6px; border:1.5px solid var(--line); color:var(--ink-3);
}
.doc-go{display:grid; place-items:center; color:var(--ink-3);
  transition:transform .34s var(--e-out), color .3s var(--e-out)}
.doc-go svg{width:19px; height:19px}
.doc:hover .doc-go{transform:translateY(3px); color:var(--acc-t)}

/* ═══════════════════════════════════════════════════════════ CONTACT */
.contact{background:var(--bg-2); border-top:1.5px solid var(--line)}
.contact-grid{display:grid; grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
  gap:clamp(30px,4.6vw,76px); align-items:start}
.contact-say{display:grid; gap:17px; align-content:start}
.mailto{
  justify-self:start; margin-top:6px; position:relative; padding-bottom:6px;
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.1rem,2.6vw,2rem); letter-spacing:-.032em; color:var(--ink);
  translate:var(--mx,0) var(--my,0);
  transition:translate .4s var(--e-out), color .3s var(--e-out);
  overflow-wrap:anywhere;
}
.mailto::after{
  content:""; position:absolute; inset:auto 0 0 0; height:3px; background:var(--acc);
  transform-origin:0 50%; scale:0 1; transition:scale .52s var(--e-out);
}
.mailto:hover{color:var(--acc-t)}
.mailto:hover::after{scale:1 1}

.links{display:grid; border-top:1.5px solid var(--line)}
.link{
  display:grid; grid-template-columns:minmax(86px,.32fr) minmax(0,1fr) auto;
  align-items:center; gap:14px; padding:17px 4px; border-bottom:1.5px solid var(--line);
  translate:calc(var(--mx,0px) + var(--slide,0px)) var(--my,0);
  transition:translate .4s var(--e-out), color .3s var(--e-out);
}
a.link:hover{--slide:12px}
.link-k{font-weight:600; font-size:.72rem; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-3)}
:lang(th) .link-k{letter-spacing:.04em}
.link-v{font-weight:500; font-size:.95rem; color:var(--ink); overflow-wrap:anywhere;
  transition:color .3s var(--e-out)}
a.link:hover .link-v{color:var(--acc-t)}
.link svg{width:17px; height:17px; color:var(--ink-3); justify-self:end; transition:color .3s var(--e-out)}
a.link:hover svg{color:var(--acc-t)}

.foot{
  display:flex; flex-wrap:wrap; align-items:center; gap:16px;
  margin-top:clamp(44px,6vw,80px); padding-top:25px; border-top:1.5px solid var(--line);
  font-size:.85rem; color:var(--ink-3);
}
.foot-mark{display:flex; gap:3px; flex:none}
.foot-mark i{display:block; width:14px; height:9px; border-radius:2px}
.foot-mark i:nth-child(1){background:var(--c-orange)}
.foot-mark i:nth-child(2){background:var(--c-pink)}
.foot-mark i:nth-child(3){background:var(--c-violet)}
.foot-mark i:nth-child(4){background:var(--c-blue)}
.foot-mark i:nth-child(5){background:var(--c-mint)}
.foot-mark i:nth-child(6){background:var(--c-yellow)}
.foot p{flex:1 1 220px}
.top{
  display:inline-flex; align-items:center; gap:8px; font-weight:600; font-size:.85rem;
  color:var(--ink-2); translate:var(--mx,0) var(--my,0);
  transition:translate .4s var(--e-out), color .3s var(--e-out);
}
.top:hover{color:var(--acc-t)}
.top svg{width:16px; height:16px; transition:transform .34s var(--e-out)}
.top:hover svg{transform:translateY(-3px)}

/* ══════════════════════════════════════════════════════════ LIGHTBOX */
.lb{
  position:fixed; inset:0; z-index:180; display:grid;
  grid-template-rows:auto minmax(0,1fr) auto; gap:10px; padding:16px;
  background:color-mix(in srgb,var(--bg) 92%,transparent);
  backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%);
  opacity:0; transition:opacity .34s var(--e-out);
}
.lb.open{opacity:1}
.lb[hidden]{display:none}
.lb-bar{display:flex; align-items:center; gap:14px}
.lb-title{font-family:var(--f-display); font-weight:700; font-size:.98rem;
  color:var(--ink); flex:1 1 auto; min-width:0}
.lb-count{font-weight:600; font-size:.78rem; color:var(--ink-2); letter-spacing:.06em}
.lb-btn{
  width:44px; height:44px; flex:none; display:grid; place-items:center;
  border-radius:var(--r-pill); border:1.5px solid var(--line); background:var(--surface);
  color:var(--ink-2); translate:var(--mx,0) var(--my,0);
  transition:translate .4s var(--e-out), border-color .26s var(--e-out),
             color .26s var(--e-out), scale .18s var(--e-out);
}
.lb-btn:hover{border-color:var(--acc-now,var(--c-orange)); color:var(--ink)}
.lb-btn:active{scale:.93}
.lb-btn svg{width:20px; height:20px}
.lb-stage{
  display:grid; place-items:center; min-height:0; overflow:hidden;
  translate:var(--dx,0px) 0; transition:translate .42s var(--e-out); touch-action:pan-y;
}
.lb-stage.dragging{transition:none}
.lb-stage img{
  max-width:100%; max-height:100%; width:auto; object-fit:contain;
  border-radius:var(--r); box-shadow:var(--sh-3);
  opacity:0; scale:.97; transition:opacity .34s var(--e-out), scale .44s var(--e-out);
}
.lb.open .lb-stage img{opacity:1; scale:1}
.lb-nav{display:flex; align-items:center; justify-content:center; gap:16px}
.lb-hint{font-size:.76rem; color:var(--ink-3); text-align:center}
@media (max-width:640px){.lb-hint{display:none}}

/* ═════════════════════════════════════════════ ANCHOR OFFSETS */
#work,#path,#craft,#skills,#docs,#contact,#top{scroll-margin-top:calc(var(--nav-h) + 14px)}

/* ═══════════════════════════════════════════════════════ RESPONSIVE */
@media (max-width:1080px){
  .hero-stage{grid-template-columns:1fr; align-items:start; gap:20px}
  .hero-figure{order:-1; max-width:min(320px,62vw); justify-self:end; margin-block-end:-4px}
  .hero-figure img{max-height:38svh}
  .hero-badge{width:76px; left:auto; right:-6px; bottom:5%}
  .mv-item,.mv-item:nth-child(even){grid-template-columns:1fr; gap:20px}
  .mv-item:nth-child(even) .mv-shot,.mv-item:nth-child(even) .mv-meta{order:0}
  .contact-grid{grid-template-columns:1fr; gap:32px}
}
@media (max-width:1000px){
  .nav-links{
    position:fixed; inset:var(--nav-h) 0 auto 0; flex-direction:column; align-items:stretch; gap:0;
    background:var(--bg); border-bottom:1.5px solid var(--line);
    padding:6px var(--pad) 22px; max-height:calc(100svh - var(--nav-h)); overflow-y:auto;
    clip-path:inset(0 0 100% 0); opacity:0; visibility:hidden;
    transition:clip-path .46s var(--e-io), opacity .3s var(--e-out), visibility .46s;
  }
  .nav-links.open{clip-path:inset(0 0 0 0); opacity:1; visibility:visible}
  .nav-links a{padding:15px 4px; border-bottom:1.5px solid var(--line); border-radius:0; font-size:1.02rem}
  .nav-links a:last-of-type{border-bottom:0}
  .nav-ink{display:none}
  .burger{display:inline-flex}
}
@media (max-width:760px){
  :root{--nav-h:62px}
  .hero{min-height:auto; padding-bottom:32px}
  .hero-stage{gap:15px}
  .hero-figure{max-width:min(258px,56vw)}
  .rail{gap:13px}
  .rail-time{display:none}
  .rail-acts{margin-inline-start:0; width:100%}
  .rail-acts .btn{flex:1 1 auto}
  .tl-item{grid-template-columns:1fr; gap:8px}
  .tl-when{padding-top:0}
  .doc{grid-template-columns:auto minmax(0,1fr) auto; gap:13px; padding:15px 16px}
  .doc-ext{display:none}
  .stat{padding-inline-start:14px}
  .mv-thumb{width:70px}
}
@media (max-width:520px){
  .brand b{display:none}
  .chip{min-height:38px; padding:0 11px; font-size:.66rem}
  .lang-chip{width:56px}
}

/* ═══════════════════════════════════════════════════════════ COOKIE BAR
   First-party visit counter, consent to opt in. Same six-colour test-card
   rule as the rest of the site in one 3px strip, so it reads as part of
   this system rather than a bolted-on legal widget. */
.cookiebar{
  position:fixed; left:16px; right:16px; bottom:16px; z-index:80;
  max-width:640px; margin-inline:auto; overflow:hidden;
  background:var(--surface); color:var(--ink);
  border-radius:var(--r-lg); box-shadow:var(--sh-2);
  padding:18px 18px 16px; display:flex; gap:14px; align-items:center; flex-wrap:wrap;
  transform:translateY(140%); opacity:0; pointer-events:none;
  transition:transform var(--t-slow) var(--e-out), opacity var(--t-slow) var(--e-out);
  font:inherit; font-size:.86rem; line-height:1.5;
}
.cookiebar::before{
  content:""; position:absolute; inset:0 0 auto 0; height:3px;
  background:linear-gradient(90deg,
    var(--c-orange) 0 16.66%, var(--c-pink) 16.66% 33.33%, var(--c-violet) 33.33% 50%,
    var(--c-blue) 50% 66.66%, var(--c-mint) 66.66% 83.33%, var(--c-yellow) 83.33% 100%);
}
.cookiebar.on{transform:translateY(0); opacity:1; pointer-events:auto}
.cookiebar p{flex:1 1 260px; margin:0; color:var(--ink-2)}
.cookiebar .cb-acts{display:flex; gap:8px; flex:0 0 auto; margin-inline-start:auto}
.cookiebar button{
  font:inherit; font-weight:600; font-size:.82rem; border-radius:var(--r-pill); padding:9px 18px; cursor:pointer;
  border:1px solid var(--line); background:transparent; color:var(--ink); white-space:nowrap;
  transition:transform var(--t-fast) var(--e-out);
}
.cookiebar button:hover{transform:translateY(-1px)}
.cookiebar button.cb-accept{background:var(--acc); color:var(--on-acc); border-color:transparent}
@media (max-width:560px){
  .cookiebar{left:10px; right:10px; bottom:10px; padding:16px 14px 14px; max-width:none}
  .cookiebar .cb-acts{flex:1 1 100%; margin-inline-start:0}
  .cookiebar button{flex:1 1 0}
}

/* ═══════════════════════════════════════════════════════════ PRINT */
@media print{
  .nav,.pre,.cursor,.scrub,.grain,.mq,.hero-scroll,.lb,.skip,.craft-more,.cookiebar{display:none !important}
  body{background:#fff; color:#000}
  .sec{padding-block:18px; break-inside:avoid}
  [data-rv],.mv-item,.tl-item,.skill,.doc,.craft-card{opacity:1 !important; transform:none !important}
  .bars,.bars-veil{display:none}
}

/* Preserve the broadcast palette; remove interaction blockers and improve small screens. */
.pre{display:none!important}.cursor{display:none!important}body,a,button{cursor:auto}a,button{cursor:pointer}
.hero-name{max-width:100%;overflow:visible}.sec{scroll-margin-top:96px}button,a,input,select{touch-action:manipulation}
.studio-consent{position:fixed;z-index:150;bottom:20px;left:20px;width:min(490px,calc(100vw - 40px));padding:22px;background:var(--bg);color:var(--ink);border:1px solid var(--line);border-radius:14px;box-shadow:0 8px 32px #0002;font:400 1rem/1.65 'IBM Plex Sans Thai',sans-serif}
.studio-consent p{margin:0 0 16px}.studio-consent>div{display:flex;gap:10px}.studio-consent button{padding:10px 15px;border:1px solid var(--line);border-radius:9px;color:var(--ink);background:var(--bg-2);font:600 .9375rem/1.4 inherit;cursor:pointer}.studio-consent button:last-child{background:var(--c-orange);color:var(--on-orange);border-color:transparent}
.studio-preview{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:150;display:flex;align-items:center;gap:20px;background:#15171c;color:#fff;padding:14px 22px;border-radius:12px;font:500 1rem/1.5 'IBM Plex Sans Thai',sans-serif;max-width:calc(100vw - 28px);box-shadow:0 8px 30px #0003}.studio-preview a{color:#ff9d7a;white-space:nowrap}.studio-footer-controls{display:flex;justify-content:center;gap:26px;align-items:center;padding:24px;font-size:.875rem}.studio-footer-controls button,.studio-footer-controls a{background:none;border:0;color:inherit;opacity:.8;font:inherit;text-decoration:underline;text-underline-offset:4px;cursor:pointer}.studio-footer-controls button:hover,.studio-footer-controls a:hover{opacity:1}
@media(max-width:600px){.studio-consent{bottom:12px;left:12px;width:calc(100vw - 24px);padding:18px}.studio-preview{font-size:.875rem;gap:12px;padding:12px 14px;align-items:center}.studio-consent button{flex:1}.nav .nav-tools button{min-width:40px;min-height:40px}.doc .doc-body b{overflow-wrap:anywhere}}
@media(prefers-reduced-motion:reduce){.bars,.grain,.mq-track,.hero-name .ch{animation:none!important;transform:none!important}}
.doc-grid{grid-template-columns:repeat(auto-fit,minmax(min(378px,100%),1fr))}

.spark-status{max-width:640px;margin:15vh auto;padding:32px;font-family:sans-serif;line-height:1.6}.spark-status button,.spark-status a{display:inline-block;margin:12px;padding:12px;color:inherit}
