/* vangquan.com standalone pages (homepage, contact, 404, unknown link).
   Ported from the approved mockups (round 3 to 5). Tokens follow DESIGN.md. */
@font-face{font-family:"VQ Sans";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/vq/fonts/noto-sans-400.woff2") format("woff2")}
@font-face{font-family:"VQ Sans";font-style:normal;font-weight:700;font-display:swap;src:url("/assets/vq/fonts/noto-sans-700.woff2") format("woff2")}
@font-face{font-family:"VQ Read";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/vq/fonts/wt-cleartext-medium.woff2") format("woff2")}
@font-face{font-family:"VQ Title";font-style:normal;font-weight:600;font-display:swap;src:url("/assets/vq/fonts/noto-serif-display-600.woff2") format("woff2")}

:root{
  --gold:#7F6000;--gold2:#B8963E;--cream:#F7F2E6;--ink:#1D1D1F;--grey:#6E6E73;--hair:#D2D2D7;--fill:#F5F5F7;
  --bg:#FFFFFF;--card:#FFFFFF;--onGold:#FFFFFF;
  --glass:rgba(255,255,255,.62);--glassEdge:rgba(255,255,255,.75);--glassLine:rgba(0,0,0,.08);
  --shadow:0 1px 2px rgba(29,29,31,.05),0 8px 28px rgba(29,29,31,.07);
  --lift:0 6px 24px rgba(0,0,0,.12),0 1px 3px rgba(0,0,0,.08);
  --ui:"VQ Sans","Noto Sans",sans-serif;
  --read:"VQ Read","VQ Sans","Noto Sans",serif;
  --title:"VQ Title","Noto Serif Display",Georgia,serif;
  --ease:cubic-bezier(.2,.8,.2,1);
  --page:var(--bg);
  color-scheme:light;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --gold:#D4B460;--cream:#2A2416;--ink:#F5F5F7;--grey:#A1A1A6;--hair:#38383A;--fill:#1C1C1E;--bg:#000000;--card:#1C1C1E;--onGold:#1D1D1F;
  --glass:rgba(44,44,46,.62);--glassEdge:rgba(255,255,255,.14);--glassLine:rgba(255,255,255,.08);--shadow:0 0 0 .5px #38383A;--lift:0 8px 28px rgba(0,0,0,.5),0 0 0 .5px rgba(255,255,255,.08);color-scheme:dark}}
:root[data-theme="dark"]{
  --gold:#D4B460;--cream:#2A2416;--ink:#F5F5F7;--grey:#A1A1A6;--hair:#38383A;--fill:#1C1C1E;--bg:#000000;--card:#1C1C1E;--onGold:#1D1D1F;
  --glass:rgba(44,44,46,.62);--glassEdge:rgba(255,255,255,.14);--glassLine:rgba(255,255,255,.08);--shadow:0 0 0 .5px #38383A;--lift:0 8px 28px rgba(0,0,0,.5),0 0 0 .5px rgba(255,255,255,.08);color-scheme:dark}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;background:var(--page)}
body{margin:0;min-height:100vh;min-height:100svh;background:var(--page);color:var(--ink);font:400 16px/1.5 var(--ui);-webkit-font-smoothing:antialiased;overflow-wrap:break-word;transition:background-color .3s,color .3s;-webkit-tap-highlight-color:transparent}
a{color:var(--gold)}
button,input{font:inherit;color:inherit}
:focus-visible{outline:3px solid var(--gold2);outline-offset:2px;border-radius:8px}
svg.i{width:1em;height:1em;fill:currentColor;flex:none}
.vq-pending [data-t]{visibility:hidden}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* top bar shared by every page: brand left, language and theme right */
.hbar{display:flex;justify-content:space-between;align-items:center;gap:0 14px;flex-wrap:wrap;
  padding:max(12px,env(safe-area-inset-top)) max(16px,env(safe-area-inset-right)) 0 max(16px,env(safe-area-inset-left));font-size:13px;color:var(--grey)}
.brand{color:var(--grey);text-decoration:none;min-height:44px;display:inline-flex;align-items:center}
.brand b{color:var(--ink);font-weight:700}

/* language and theme controls: same 40px spot on every page; glass where other buttons exist, quiet links on the homepage */
.ctrls{display:flex;gap:8px;margin-left:auto}
.cbtn{display:inline-flex;align-items:center;justify-content:center;height:40px;width:40px;min-width:0;padding:0;border:0;border-radius:99px;background:var(--glass);-webkit-backdrop-filter:blur(20px) saturate(180%);backdrop-filter:blur(20px) saturate(180%);box-shadow:inset 0 0 0 .5px var(--glassEdge),var(--lift);color:var(--ink);font-size:13px;font-weight:700;letter-spacing:.04em;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:transform .12s var(--ease)}
.cbtn:active{transform:scale(.94)}
.cbtn svg{width:18px;height:18px}
@media (hover:hover){.cbtn:hover{background-image:linear-gradient(rgba(127,127,127,.08),rgba(127,127,127,.08))}}
.ctrls.quiet .cbtn{background:none;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none;color:var(--grey);font-weight:400;transition:color .2s,transform .12s var(--ease)}
@media (hover:hover){.ctrls.quiet .cbtn:hover{background-image:none;color:var(--gold)}}
.ctrls.quiet .cbtn:active{color:var(--gold)}
.ctrls.quiet .cbtn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.cbtn .moon{display:block}.cbtn .sun{display:none}
:root[data-theme="dark"] .cbtn .moon{display:none}:root[data-theme="dark"] .cbtn .sun{display:block}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .cbtn .moon{display:none}:root:not([data-theme="light"]) .cbtn .sun{display:block}}

.label{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
.lk{border:0;background:none;padding:0;min-height:44px;display:inline-flex;align-items:center;color:var(--grey);font:inherit;font-size:13px;text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:color .2s}
@media (hover:hover){.lk:hover{color:var(--gold)}}
.lk:active{color:var(--gold)}

/* ---------- homepage: the yeartext, in focus ---------- */
.home{min-height:100vh;min-height:100svh;display:flex;flex-direction:column;background:var(--bg);container-type:inline-size;position:relative}
.home .stage{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px max(16px,env(safe-area-inset-right)) 12px max(16px,env(safe-area-inset-left));text-align:center;min-width:0}
.home .label.off{visibility:hidden}
.wheel{position:relative;width:100%;max-width:36em;height:clamp(240px,calc(100svh - 300px),480px);margin:16px auto 0;overflow:hidden;outline:none;font-family:var(--read);font-weight:500;-webkit-mask-image:linear-gradient(transparent,#000 20%,#000 80%,transparent);mask-image:linear-gradient(transparent,#000 20%,#000 80%,transparent);padding:30px 0;touch-action:none;cursor:grab;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.wheel.drag{cursor:grabbing}
.wheel .in{position:relative;transition:transform .5s var(--ease),opacity .35s var(--ease)}
.wheel .in.jump,.wheel.drag .in{transition:none}
.wheel p{margin:0 auto;transition:opacity .35s var(--ease)}
.wheel p.hid{opacity:0;pointer-events:none}
.wheel i{font-style:italic}
.ctx{font-size:15.5px;line-height:1.5;color:var(--grey);opacity:.6;max-width:31em;padding:6px 8px;border-radius:10px;cursor:pointer;transition:opacity .2s}
.ctx.far{opacity:.28;font-size:14.5px}
@media (hover:hover){.ctx:hover{opacity:.95}}
.wheel p.ctx.near{opacity:1;color:var(--ink)}
.focus{font-family:var(--read);font-weight:500;font-size:clamp(25px,4.6cqi,40px);line-height:1.2;letter-spacing:0;color:var(--ink);padding:18px 4px;text-wrap:balance;cursor:default}
.vn{font-family:var(--ui);font-size:.62em;font-weight:700;color:var(--gold);vertical-align:.42em;margin:0 .22em 0 .05em;font-variant-numeric:tabular-nums}
.focus .vn{font-size:.36em;vertical-align:1em}
.busy{opacity:.4}
.citerow{display:flex;align-items:center;justify-content:center;gap:4px;margin-top:10px;min-height:44px;flex-wrap:wrap;max-width:100%}
.cite{display:inline-flex;align-items:center;min-height:44px;padding:0 18px;border:0;border-radius:99px;background:transparent;color:var(--gold);font-weight:700;font-size:17px;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:transform .12s var(--ease),background-color .2s}
@media (hover:hover){.cite:hover{background:var(--cream)}}
.cite:active{transform:scale(.96);background:var(--cream)}
.mini{width:36px;height:36px;border:0;border-radius:50%;background:transparent;color:var(--grey);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
.mini svg{width:17px;height:17px}
@media (hover:hover){.mini:hover{background:var(--fill);color:var(--gold)}}
.ask{display:none;align-items:center;gap:8px;min-height:44px;padding:0 6px 0 18px;border-radius:99px;background:var(--fill);box-shadow:inset 0 0 0 1px var(--hair);max-width:100%;width:20em}
.ask input{flex:1;min-width:0;border:0;background:transparent;color:var(--ink);font-weight:700;font-size:17px;outline:none;padding:10px 0}
.ask input::placeholder{color:var(--grey);font-weight:400}
.ask kbd{font:12px var(--ui);color:var(--grey);border:1px solid var(--hair);border-radius:6px;padding:1px 6px}
.home.asking .cite,.home.asking .mini{display:none}.home.asking .ask{display:inline-flex}
.msg{min-height:20px;font-size:13px;color:var(--grey);margin-top:4px;max-width:100%}
.home.bad .ask{animation:nope .32s}
@keyframes nope{20%{transform:translateX(-6px)}40%{transform:translateX(5px)}60%{transform:translateX(-3px)}80%{transform:translateX(2px)}}
.back{border:0;background:transparent;color:var(--grey);font-size:13px;cursor:pointer;min-height:32px;padding:0 10px;border-radius:99px}
.back svg{width:13px;height:13px;margin-right:4px;vertical-align:-1px}
@media (hover:hover){.back:hover{color:var(--gold)}}
.home .hfoot{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:0 14px;padding:0 max(16px,env(safe-area-inset-right)) max(8px,env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left));font-size:13px;color:var(--grey)}
.toast{position:fixed;left:50%;bottom:calc(58px + env(safe-area-inset-bottom));transform:translate(-50%,10px);background:var(--ink);color:var(--bg);padding:8px 16px;border-radius:99px;font-size:14px;opacity:0;pointer-events:none;transition:opacity .2s,transform .28s var(--ease);max-width:calc(100vw - 32px)}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* ---------- contact ---------- */
.cpage{background:var(--bg);min-height:100vh;min-height:100svh;padding-bottom:max(32px,env(safe-area-inset-bottom))}
.cpage .in{max-width:760px;margin:0 auto;padding:0 max(16px,env(safe-area-inset-right)) 0 max(16px,env(safe-area-inset-left))}
.cpage .hbar{max-width:760px;margin:0 auto 24px;padding-top:max(20px,env(safe-area-inset-top))}
.ey{font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--gold)}
.cpage h1{font-family:var(--title);font-weight:600;font-size:clamp(28px,6vw,38px);line-height:1.12;letter-spacing:-.01em;margin:6px 0 6px;text-wrap:balance}
.cpage .sub{color:var(--grey);margin:0 0 22px;text-wrap:pretty}
.two{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:16px}
.ccard{background:var(--card);border-radius:22px;box-shadow:var(--shadow);padding:26px 18px 20px;text-align:center;min-width:0}
.ccard .nm{font-size:22px;font-weight:700;letter-spacing:-.01em;margin:0}
.ccard .rl{color:var(--grey);font-size:14px;margin-bottom:18px}
.acts{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}
.act{display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px 2px 8px;border-radius:14px;background:color-mix(in srgb,var(--ink) 5%,transparent);color:var(--gold);text-decoration:none;font-size:11px;font-weight:700;min-width:0;transition:transform .12s var(--ease)}
.act svg{width:24px;height:24px}
.act span{color:var(--ink);font-weight:400;white-space:nowrap}
.act:active{transform:scale(.95)}
@media (hover:hover){.act:hover{background:var(--cream)}}
@media (max-width:400px){.ccard{padding-left:12px;padding-right:12px}.pcard .pp{margin-left:-12px;margin-right:-12px}.acts{gap:5px}.act{padding-left:0;padding-right:0;font-size:10.5px}}
@media (max-width:340px){.acts{gap:4px}.act{font-size:10px}}

/* studio photos on canvas, full width at the top of the card: the backdrop fades into the card and the person fades out at the shoulders.
   Backdrop and person move apart with tilt; the theme change is a shared-element dissolve: same place and size, the outfit softly blurs from one photo into the other */
.pcard{padding-top:0;overflow:hidden}
.pp{aspect-ratio:3/2;margin:0 -18px 12px;overflow:hidden;position:relative;border-radius:22px 22px 0 0}
.pwrap{user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.pp .bg,.pp .fg{will-change:transform}
/* the backdrop layer is 10% larger than the frame and the photos in people/ keep clear space left, right and above, so the largest tilt never shows an edge or cuts hair or shoulders */
.pp .bg{transform:translate(calc(var(--tx,0) * -3px),calc(var(--ty,0) * -2px))}
.pp .fg{transform:translate(calc(var(--tx,0) * 5px),calc(var(--ty,0) * 3px));-webkit-mask-image:linear-gradient(#000 80%,transparent 95%);mask-image:linear-gradient(#000 80%,transparent 95%)}
/* Rise in: once the photos are painted, each person eases up into place and comes into focus (second card a beat later). Plays once per page load. */
.pp .fg{opacity:0}
.pp.rise .fg{opacity:1;animation:vqrise 1s cubic-bezier(.2,.8,.2,1) both}
.pcard:nth-child(2) .pp.rise .fg{animation-delay:.14s}
@keyframes vqrise{from{opacity:0;translate:0 16px;scale:.985;filter:blur(7px)}to{opacity:1;translate:0 0;scale:1;filter:blur(0)}}
.p5ph{position:relative;width:100%;height:100%}
.p5ph .bg,.p5ph .fg{position:absolute;inset:-5%}
.p5ph .bg i{position:absolute;inset:0;transition:opacity .9s cubic-bezier(.4,0,.2,1)}
.p5ph .bg .day{background:linear-gradient(180deg,#EDEDF0 0%,#F5F5F7 50%,transparent 90%)}
.p5ph .bg .eve{background:linear-gradient(180deg,#2E2E30 0%,#252527 50%,transparent 90%);opacity:0}
.p5ph canvas{position:absolute;left:4.545%;top:4.545%;width:90.91%;height:90.91%;transform-origin:50% 100%;pointer-events:none;transition:opacity .9s cubic-bezier(.4,0,.2,1),transform .9s cubic-bezier(.2,.8,.2,1),filter .7s cubic-bezier(.4,0,.2,1)}
.p5ph canvas.day{opacity:1;transform:none;filter:blur(0)}
.p5ph canvas.eve{opacity:0;transform:scale(.99);filter:blur(2.5px)}
:root[data-theme="dark"] .p5ph .bg .day{opacity:0}
:root[data-theme="dark"] .p5ph .bg .eve{opacity:1}
:root[data-theme="dark"] .p5ph canvas.day{opacity:0;transform:scale(.99);filter:blur(2.5px)}
:root[data-theme="dark"] .p5ph canvas.eve{opacity:1;transform:none;filter:blur(0)}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]) .p5ph .bg .day{opacity:0}
:root:not([data-theme="light"]) .p5ph .bg .eve{opacity:1}
:root:not([data-theme="light"]) .p5ph canvas.day{opacity:0;transform:scale(.99);filter:blur(2.5px)}
:root:not([data-theme="light"]) .p5ph canvas.eve{opacity:1;transform:none;filter:blur(0)}
}

/* ---------- simple pages: 404 and unknown link ---------- */
.spage{background:var(--bg);min-height:100vh;min-height:100svh;display:flex;flex-direction:column}
.spage .mid{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:30px max(22px,env(safe-area-inset-right)) max(30px,env(safe-area-inset-bottom)) max(22px,env(safe-area-inset-left));min-width:0}
.spage .code{font:700 12px var(--ui);letter-spacing:.16em;color:var(--gold);margin:0}
.spage h1{font-family:var(--title);font-weight:600;font-size:clamp(28px,6vw,40px);line-height:1.12;margin:10px 0 8px;text-wrap:balance;max-width:16em}
.spage p{color:var(--grey);margin:0 0 20px;max-width:26em;text-wrap:pretty}
.spage .path{display:inline-block;font:400 14px var(--ui);background:var(--fill);border-radius:99px;padding:6px 14px;margin:0 0 18px;color:var(--ink);overflow-wrap:anywhere;max-width:100%}
.spage .btns{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
.spage .btns a{display:inline-flex;align-items:center;justify-content:center;min-height:46px;padding:0 22px;border-radius:99px;font-weight:700;text-decoration:none;background:var(--gold);color:var(--onGold);transition:transform .12s var(--ease)}
.spage .btns a:active{transform:scale(.96)}
.spage .btns a.alt{background:var(--fill);color:var(--gold)}
.spage .verse{font-family:var(--read);font-weight:500;color:var(--grey);font-size:15px;max-width:30em;margin:26px 0 0}
.spage .verse b{font-family:var(--ui);font-weight:700;color:var(--gold);font-size:13px;margin-left:6px;white-space:nowrap}

/* Iris theme change: the old page stays put and the new one opens over it as a circle (the circle itself is animated in vq.js). While it runs, the normal colour fades are off so the new page is already in its final state. */
::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}
::view-transition-old(root){z-index:1}
::view-transition-new(root){z-index:2}
.vq-vt *,.vq-vt *::before,.vq-vt *::after{transition:none!important}
/* The portraits get their own layers: the browser's standard view-transition cross-fade blends the old photo into the new one,
   starting together with the circle and lasting as long (.75s). Both photos are fixed images during the change, so mobile Safari
   has nothing to redraw, and object-fit:none keeps them at their exact size so they can never stretch. */
.pp{contain:paint}
.pp[data-person="vang"]{view-transition-name:vq-vang}
.pp[data-person="quan"]{view-transition-name:vq-quan}
::view-transition-group(vq-vang),::view-transition-group(vq-quan){animation:none}
::view-transition-old(vq-vang),::view-transition-new(vq-vang),
::view-transition-old(vq-quan),::view-transition-new(vq-quan){width:100%;height:100%;object-fit:none;animation-duration:.75s;animation-delay:0s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation-fill-mode:both}
@media (prefers-reduced-motion:reduce){
  .pp .fg{opacity:1}
  *{animation:none!important;transition:none!important}
  .pp .bg,.pp .fg{transform:none}
  html body .pp .p5ph canvas.day,html body .pp .p5ph canvas.eve{transform:none}
}
.home h1.label{margin:0;font-size:11px;line-height:1.5}
.vq-pending .wheel .in,.vq-pending .cite{visibility:hidden}
[hidden]{display:none!important}
