/* =========================================================
   a95c.com — 95 Creations
   TOKENS: 95key reads/writes this block (colors, font, sizes)
   ========================================================= */
:root {
  --wine: #844345;
  --rose: #e1a8a1;
  --blood: #320000;
  --black: #000000;
  --white: #ffffff;

  --title: #7a7a7a;      /* section titles on white */
  --text: #555555;       /* body text on white */
  --strong: #222222;     /* sub lines, menu */
  --hair: rgba(50, 0, 0, .14);   /* thin lines: --blood at 14% */

  --font: "IBM Plex Sans Thai", system-ui, -apple-system, "Segoe UI", sans-serif;
  --fs-title: clamp(1.4rem, min(2.15vw, 4.3vh), 2.1rem);
  --fs-sub: 0.875rem;
  --fs-body: 0.9375rem;
  --track-title: 0.26em;

  --ease-pop: cubic-bezier(.3, 1.6, .5, 1);
}

/* ---------- fonts (self-hosted) ---------- */
@font-face { font-family: "IBM Plex Sans Thai"; font-weight: 300; font-display: swap; src: url(../fonts/plex-latin-300.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans Thai"; font-weight: 400; font-display: swap; src: url(../fonts/plex-latin-400.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans Thai"; font-weight: 500; font-display: swap; src: url(../fonts/plex-latin-500.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans Thai"; font-weight: 300; font-display: swap; src: url(../fonts/plex-thai-300.woff2) format("woff2"); unicode-range: U+0E01-0E5B, U+200C-200D, U+25CC; }
@font-face { font-family: "IBM Plex Sans Thai"; font-weight: 400; font-display: swap; src: url(../fonts/plex-thai-400.woff2) format("woff2"); unicode-range: U+0E01-0E5B, U+200C-200D, U+25CC; }
@font-face { font-family: "IBM Plex Sans Thai"; font-weight: 500; font-display: swap; src: url(../fonts/plex-thai-500.woff2) format("woff2"); unicode-range: U+0E01-0E5B, U+200C-200D, U+25CC; }

@property --a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --in { syntax: "<number>"; inherits: true; initial-value: 0; }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth; -webkit-text-size-adjust: 100%; overflow-x: clip;
  /* desktop layout: 1rem = 16px on normal screens, shrinks with min(vh, vw) on short ones (down to 70%) */
  font-size: clamp(70%, min(calc(100vh * 16 / 700), calc(100vw * 16 / 1200)), 100%);
}
body {
  margin: 0; font-family: var(--font); font-weight: 400; color: var(--text);
  background: var(--white); line-height: 1.6; overflow-x: clip;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
img, video { display: block; max-width: 100%; }
h1, h2, p, figure, address { margin: 0; }
address { font-style: normal; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
:focus-visible { outline: 2px solid var(--wine); outline-offset: 3px; border-radius: 4px; }
.skip { position: absolute; left: -999px; top: 8px; z-index: 100; background: #fff; padding: .5em 1em; }
.skip:focus { left: 8px; }

/* scroll-linked values: JS writes --e (enter 0→1) and --p (pinned 0→1).
   Without JS everything shows in its final state. */
[data-scene] { --e: 1; --p: 0; }
.js [data-scene]:not(.hero) { --e: 0; }

.scene { position: relative; }
.stage { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: clip; }

/* ---------- shared type ---------- */
.title {
  font-size: var(--fs-title); font-weight: 300; letter-spacing: var(--track-title);
  color: var(--title); line-height: 1.25;
}
@media (orientation: landscape) and (min-width: 768px), (min-width: 1101px) { .title { white-space: nowrap; } }
.sub { margin-top: 1.1em; font-size: var(--fs-sub); font-weight: 500; color: var(--strong); }
.body { margin-top: .6em; font-size: var(--fs-body); max-width: 38ch; }
.btns { display: flex; gap: .75rem; margin-top: 2rem; flex-wrap: wrap; }
.btn {
  display: inline-block; padding: .6em 1.9em; border: 1px solid var(--wine); border-radius: 999px;
  font-size: .8125rem; letter-spacing: .08em; color: var(--strong); background: transparent;
  transition: transform .3s var(--ease-pop), box-shadow .3s;
}
.btn:hover { transform: translateY(-3px); box-shadow: 0 8px 14px -8px rgba(132, 67, 69, .6); }

/* =========================================================
   MENU
   ========================================================= */
.nav {
  --w-open: min(1180px, calc(100vw - 3rem));
  position: fixed; z-index: 50; top: max(1.875rem, env(safe-area-inset-top)); left: 50%;
  height: 4.375rem; width: 4.375rem; border-radius: 2.1875rem;
  display: flex; align-items: center; transform: translateX(-50%);
  box-shadow: 0 12px 20px -12px rgba(132, 67, 69, .65), 0 1px 3px rgba(0, 0, 0, .06);
  transition: width .8s cubic-bezier(.7, 0, .2, 1);
}
.nav.is-open { width: var(--w-open); }
/* glow running around the edge:
   ::before = white fill + sharp running line, ::after = soft glow behind (no mask, so it can spread) */
.nav::before, .nav::after {
  content: ""; position: absolute; border-radius: inherit; pointer-events: none;
  --ring: conic-gradient(from var(--a), transparent 0 45%, var(--rose) 66%, var(--wine) 84%, transparent 97%);
  animation: spin 5s linear infinite;
}
.nav::before {
  inset: -2px; z-index: -1; border: 2px solid transparent;
  background: linear-gradient(var(--white), var(--white)) padding-box, var(--ring) border-box;
}
.nav::after { inset: -3px; z-index: -2; background: var(--ring); filter: blur(16px); opacity: .9; }
@keyframes spin { to { --a: 360deg; } }

.nav-logo {
  flex: 0 0 4.375rem; height: 4.375rem; display: grid; place-items: center; border-radius: 2.1875rem;
  transition: transform .3s var(--ease-pop);
}
.nav-logo img { width: 2.75rem; height: 2.75rem; }
.nav-logo:hover { transform: translateY(-2px); }
.nav-links, .nav-icons { opacity: 0; visibility: hidden; transition: opacity .4s .5s, visibility 0s .5s; white-space: nowrap; }
.nav.is-open .nav-links, .nav.is-open .nav-icons { opacity: 1; visibility: visible; }
.nav-links { display: flex; gap: .6rem; padding-left: 1.1rem; margin-left: .3rem; border-left: 1px solid #eee; }
.nav-links a {
  display: inline-block; padding: .5em .95em; font-size: 1rem; color: var(--strong);
  transition: transform .3s var(--ease-pop), color .2s;
}
.nav-links a:hover { transform: translateY(-2px); color: var(--wine); }
.nav-icons { display: flex; gap: .35rem; margin-left: auto; padding-right: 1.125rem; }
.nav-icons a { display: grid; place-items: center; width: 2.625rem; height: 3rem; transition: transform .3s var(--ease-pop); }
.nav-icons a:hover { transform: translateY(-3px); }
.nav-icons svg { width: 1.6875rem; height: 1.6875rem; fill: var(--wine); }
.nav-icons .o { fill: none; stroke: var(--wine); stroke-width: 1.7; stroke-linejoin: round; }
.nav-icons .w { fill: var(--white); }
.nav-icons text { font: 700 4.4px/1 Arial, sans-serif; }

/* =========================================================
   1 HERO
   ========================================================= */
/* --g = how gathered the hero is (1 = everything pulled small into the middle, 0 = open).
   Opening: CSS animation eases --in 1 → 0 (no JS wait, no flash). Leaving: --p (scroll) pulls it back to 1. */
.hero {
  z-index: 1; height: 160vh; height: 160svh;
  --in: 0; --g: max(var(--in), var(--p));
  animation: hero-open 1.9s .4s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes hero-open { from { --in: 1; } to { --in: 0; } }
.hero-bg {
  position: absolute; inset: 0; background: #d4c6b8 url(../img/hero-bg.webp) center / cover no-repeat;
  opacity: calc(1 - var(--g));   /* background only fades in / out, no shrinking */
}
.floats { --H: 100svh; --u: min(calc(var(--H) / 900), calc(100vw / 1200)); position: absolute; inset: 0; }
.drift {
  --end: min(0px, calc(100vw - var(--u) * 3600));
  position: absolute; left: 0; top: 50%; height: calc(var(--u) * 900); width: calc(var(--u) * 3600);
  margin-top: calc(var(--u) * -450); animation: drift 75s linear infinite alternate; will-change: transform;
}
.hero.is-off .drift { animation-play-state: paused; }
@keyframes drift { to { transform: translateX(var(--end)); } }

/* each image: 15% bigger, and pulled toward the middle by --g.
   JS writes --gx/--gy = distance from the image to the screen centre. */
.fl {
  --gx: 0px; --gy: 0px; --k: 1;
  position: absolute; height: auto; box-shadow: 0 14px 24px -10px rgba(40, 20, 10, .45);
  transform: translate3d(calc(var(--gx) * var(--g) * var(--k)), calc(var(--gy) * var(--g) * var(--k)), 0) scale(calc(1.15 - var(--g) * 1.13));
  opacity: calc((1 - var(--p)) * 3.5);   /* stays visible while gathering, fades at the very end */
}
.fl.dev { box-shadow: none; filter: drop-shadow(0 12px 14px rgba(40, 20, 10, .35)); }
/* positions from hero-layout.png (3600 × 900) */
.f02  { left: calc(var(--u) * 59);   top: calc(var(--u) * 87);  width: calc(var(--u) * 281); }
.f08  { left: calc(var(--u) * 570);  top: calc(var(--u) * 95);  width: calc(var(--u) * 261); }
.f03  { left: calc(var(--u) * 342);  top: calc(var(--u) * 548); width: calc(var(--u) * 316); }
.f01  { left: calc(var(--u) * 931);  top: calc(var(--u) * 558); width: calc(var(--u) * 285); }
.f05  { left: calc(var(--u) * 1226); top: calc(var(--u) * 87);  width: calc(var(--u) * 215); }
.f12  { left: calc(var(--u) * 1286); top: calc(var(--u) * 690); width: calc(var(--u) * 550); }
.f09  { left: calc(var(--u) * 1689); top: calc(var(--u) * -32); width: calc(var(--u) * 433); }
.f07  { left: calc(var(--u) * 1883); top: calc(var(--u) * 342); width: calc(var(--u) * 226); }
.f06b { left: calc(var(--u) * 2031); top: calc(var(--u) * 743); width: calc(var(--u) * 239); }
.f04  { left: calc(var(--u) * 2315); top: calc(var(--u) * 394); width: calc(var(--u) * 204); }
.f06  { left: calc(var(--u) * 2639); top: calc(var(--u) * 73);  width: calc(var(--u) * 248); }
.f11  { left: calc(var(--u) * 2735); top: calc(var(--u) * 497); width: calc(var(--u) * 495); }
.f10  { left: calc(var(--u) * 3203); top: calc(var(--u) * 95);  width: calc(var(--u) * 360); }

.hero-copy {
  position: absolute; left: 50%; top: 50%; width: min(94vw, 1240px); text-align: center;
  transform: translate(-50%, -50%) scale(calc(1 - var(--g) * .97)); opacity: calc((1 - var(--p)) * 3);
}
.hero-copy::before {
  content: ""; position: absolute; inset: -3rem -2rem; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(232, 224, 216, .82), rgba(232, 224, 216, 0));
}
.hero-title {
  font-size: clamp(2.2rem, min(4.2vw, 8.4vh), 4.4rem); font-weight: 400; letter-spacing: .16em;
  color: var(--wine); line-height: 1.2; margin-right: -.16em;
}
.br-m { display: none; }
.hero-sub { margin-top: 1.2rem; font-size: clamp(1rem, min(1.3vw, 2.6vh), 1.25rem); color: #3f3532; letter-spacing: .04em; }

/* =========================================================
   2 SOCIAL
   ========================================================= */
/* Pulled up under the hero (margin-top) so it arrives while the hero is still gathering.
   --i  = arriving (from --e)
   --t  = carousel → row of images (JS, from scroll)
   --z  = slight zoom while the row is pulled right (JS)
   --q  = fades out while the row is being pulled */
.social {
  z-index: 3; height: 420vh; height: 420svh; margin-top: -100vh; margin-top: -100svh;
  --i: clamp(0, calc((var(--e) - .6) * 2.5), 1);
  --t: 0; --z: 1;
  --q: clamp(0, calc((var(--p) - .5) * 2.9), 1);
}
.social-show {
  --ph: min(84svh, 85vw, 820px); --pw: calc(var(--ph) * .47);
  position: absolute; left: 10vw; top: 50%; width: var(--pw); height: var(--ph); margin-top: calc(var(--ph) / -2);
  transform: translateX(calc((1 - var(--i)) * -30vw));
  opacity: calc(var(--i) * (1 - var(--q)));
  touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none;
}
.social-show.is-drag { cursor: grabbing; }
.phone-outline {
  position: absolute; inset: 0; border: 2px solid #cfcfcf; border-radius: calc(var(--pw) * .16);
  opacity: calc(1 - var(--t) * 1.6);
}
/* small logo at the top of the phone frame, sized by the frame */
.phone-logo { position: absolute; left: 50%; top: calc(var(--ph) * .04); width: calc(var(--pw) * .14); height: auto; transform: translateX(-50%); }
.slides {
  position: absolute; left: 6%; top: 50%; width: 88%; height: 88%; z-index: 1;
  transform: translateY(-50%) scale(var(--z)); transform-origin: 0 50%;
}
/* JS writes --x, --s, --sa, --zi per slide */
.slide {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-start;
  transform: translate3d(var(--x, 0px), 0, 0) scale(var(--s, 1)); transform-origin: 0 50%;
  opacity: var(--sa, 1); z-index: var(--zi, 1); will-change: transform, opacity;
}
.slide img { flex: none; width: 100%; height: auto; pointer-events: none; -webkit-user-drag: none; }
.slide.sq img { width: 165%; max-width: none; }
.social-copy {
  position: absolute; left: 50vw; top: 50%; width: min(44vw, 760px);
  transform: translate(calc(var(--t) * -3vw), -50%); opacity: calc(var(--i) - var(--t) * 1.8);
}
/* section type size (shared with 3 VIDEO and 4 WEB) */
.social .title, .video .title, .web .title, .about .title, .packs .title { font-size: clamp(2rem, min(3vw, 6vh), 3.2rem); letter-spacing: .14em; }
.social .sub, .video .sub, .web .sub { font-size: clamp(1rem, min(1.1vw, 2.2vh), 1.125rem); }
.social .body, .video .body, .web .body { font-size: clamp(1.0625rem, min(1.25vw, 2.5vh), 1.3125rem); max-width: 32ch; }
.video .body { max-width: 46ch; }   /* video: longer lines */
.social .body { max-width: 36em; }  /* social: lines a little wider than the title */
/* "Read more" under long text: shown only on the mobile layout (see MOBILE LAYOUT) */
.more {
  display: none; margin-top: .5rem; padding: .25em 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .9375rem; color: inherit; text-decoration: underline; text-underline-offset: .25em;
}
.social .btn, .video .btn, .web .btn { font-size: .9375rem; padding: .7em 2.2em; }

/* =========================================================
   3 VIDEO
   ========================================================= */
/* In:  videos slide in → text fades in → background fades in   (from --e)
   Out: background fades out → text fades out → videos slide out (from --p) */
.video {
  /* 270svh: stays on screen for 85svh of scrolling before it starts to leave */
  z-index: 2; height: 270vh; height: 270svh;
  --v-in: clamp(0, calc(var(--e) * 2), 1);
  --t-in: clamp(0, calc((var(--e) - .45) * 2.5), 1);
  --b-in: clamp(0, calc((var(--e) - .6) * 2.5), 1);
  --b-out: clamp(0, calc((var(--p) - .5) * 6.8), 1);
  --t-out: clamp(0, calc((var(--p) - .6176) * 6.8), 1);
  --v-out: clamp(0, calc((var(--p) - .7353) * 4.25), 1);
}
/* big backgrounds load only when the section is near (JS adds .is-near) */
.video:not(.is-near) .video-bg, .web:not(.is-near) { background-image: none; }
/* stays fixed under the previous section while it slides away */
.video .stage { transform: translateY(calc((var(--e) - 1) * 100svh)); }
.video-inner { position: absolute; inset: 0; }
.video-bg {
  position: absolute; inset: 0; background: #8f3f42 url(../img/silk-bg.webp) center / cover no-repeat;
  opacity: calc(var(--b-in) - var(--b-out));
}
.video-copy {
  position: absolute; left: 8vw; top: 50%; width: min(38vw, 560px); transform: translateY(-50%);
  color: rgba(255, 255, 255, .88); opacity: calc(var(--t-in) - var(--t-out));
}
.video .title { white-space: normal; }
.video .title { color: rgba(255, 255, 255, .92); }
.video .sub { color: var(--white); }
.video .btn { border-color: rgba(255, 255, 255, .85); color: var(--white); }
.video .btn:hover { box-shadow: 0 8px 14px -8px rgba(0, 0, 0, .5); }

.dev-tablet, .dev-phone { position: absolute; overflow: hidden; background: #111; }
.dev-tablet video, .dev-phone video { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.dev-tablet {
  /* a little above middle: top = 46svh - half its height, but never under the menu (7.5rem) */
  left: 54vw; top: max(calc(46svh - min(19.5vw, 32svh)), 7.5rem); width: 52vw; aspect-ratio: 4 / 3; max-height: 64svh;
  padding: 10px; background: #ececec; border-radius: 26px;
  box-shadow: 0 30px 50px -20px rgba(0, 0, 0, .55);
  transform: translateX(calc((1 - var(--v-in) + var(--v-out)) * 100vw));
}
.dev-tablet video { border-radius: 16px; }
.dev-phone {
  /* iPhone Pro body shape (150 × 71.9 mm) */
  height: min(50svh, 37.5vw); aspect-ratio: 71.9 / 150; padding: 5px; border-radius: 34px;
  box-shadow: 0 30px 40px -18px rgba(0, 0, 0, .6), inset 0 0 0 1px #444;
}
.dev-phone video { border-radius: 29px; }
.video .dev-phone {
  left: 43vw; top: 36svh; transform: translateX(calc((1 - var(--v-in) + var(--v-out)) * -100vw));
}

/* =========================================================
   4 WEB
   ========================================================= */
.web {
  position: relative; z-index: 4; text-align: center; height: 150vh; height: 150svh;
  background: var(--white) url(../img/web-bg.webp) center / cover no-repeat;
  /* pinned: image first (fade + zoom out), then text and buttons */
  --d: clamp(0, calc((var(--e) - .7) * 2 + var(--p) * 5), 1);
  --t: clamp(0, calc((var(--p) - .08) * 3.2), 1);
  /* menu link #web: land where the text is fully in (p ≈ .44 of the 50svh pin), not at the very top */
  scroll-margin-top: -22svh;
}
.web-in {
  position: sticky; top: 0; height: 100vh; height: 100svh; overflow: clip;
  display: flex; flex-direction: column; justify-content: flex-start; padding: 14vh 6vw 4svh;
}
/* text on top; the demo sites + Price fill the space below, centred in it (where the devices image was) */
.web-copy { flex: 1; min-height: 0; display: flex; flex-direction: column; width: 100%; max-width: 1500px; margin: 0 auto; opacity: var(--t); transform: translateY(calc((1 - var(--t)) * 2vh)); }
.web .body { margin-inline: auto; max-width: 62ch; }
.web .btns { justify-content: center; margin-bottom: auto; }
.web .more { align-self: center; }
/* web (all screens): text shows 2 lines + "Read more" so the demo sites get the room.
   Open: full text, demo sites hide. The full text stays in the HTML. */
.js .web .body { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.js .web.is-more .body { display: block; -webkit-line-clamp: unset; line-clamp: none; overflow: visible; }
.js .web .more { display: inline-block; }
.js .web .more[hidden] { display: none; }
.web.is-more .demos { display: none; }
.web-devices {
  /* sits on the bottom edge of the screen */
  width: min(101vw, 162svh, 1612px); max-width: none; height: auto; margin: auto 0 0; align-self: center; padding-top: 4vh; transform-origin: 50% 100%;
  opacity: var(--d); transform: scale(calc(1.18 - var(--d) * .18));
}
.web-devices { display: none; }   /* replaced by the demo sites below (kept in the HTML for data-k) */

/* demo sites: website in a browser window + a small phone, each links to the live demo.
   --cw = card width, from min(vw, vh) */
.demos {
  --cw: min(43vw, 44rem, calc((82svh - 23rem) * 1.6));   /* height left after ~23rem of text + buttons */
  display: flex; justify-content: center; gap: 2.5rem; margin-top: auto; padding-top: 2rem; }
.demo { display: block; width: var(--cw); color: var(--strong); transition: transform .3s var(--ease-pop); }
.demo:hover { transform: translateY(-4px); }
.demo-shot {
  position: relative; display: block; aspect-ratio: 16 / 10; border-radius: .5rem; background: #ececec;
  box-shadow: 0 18px 30px -18px rgba(40, 20, 10, .55), 0 0 0 1px rgba(0, 0, 0, .08);
  container-type: inline-size;
}
.demo-bar { position: absolute; left: 0; right: 0; top: 0; height: 7%; display: flex; align-items: center; gap: 1.4%; padding-left: 3%; }
.demo-bar i { width: 2.2%; aspect-ratio: 1; border-radius: 50%; background: #c4c4c4; }
.demo-web { position: absolute; left: 0; top: 7%; width: 100%; height: 93%; object-fit: cover; border-radius: 0 0 .5rem .5rem; }
.demo-tag {
  position: absolute; left: 6%; right: 18%; top: 34%; text-align: center; color: var(--white);
  font-size: .5rem; font-size: 3.6cqw; line-height: 1.3; letter-spacing: .14em; text-shadow: 0 1px 6px rgba(0, 0, 0, .5);
}
.demo-phone {
  position: absolute; right: -5%; bottom: -7%; width: auto; height: 74%; max-width: none; aspect-ratio: 71.9 / 150;
  object-fit: cover; border: .1875rem solid #111; border-radius: 16% / 8%; background: #111;
  box-shadow: 0 12px 18px -10px rgba(0, 0, 0, .55);
}
.demo-villa .demo-phone { object-position: 52% 50%; }
.demo-beach .demo-phone { object-position: 30% 50%; }
.demo-name { display: block; margin-top: 1.1rem; font-size: .9375rem; font-weight: 500; letter-spacing: .06em; }
.demo-name::after { content: " \2192"; color: var(--wine); }

/* =========================================================
   5 ABOUT + FOOTER
   ========================================================= */
.about {
  position: relative; z-index: 5; background: var(--white);
  padding: 19vh 8vw 10vh;
  --t: clamp(0, calc((var(--e) - .05) * 2.5), 1);
  --o: clamp(0, calc((var(--e) - .3) * 3), 1);
}
.about-copy { width: min(50vw, 700px); }
.about-title {
  white-space: nowrap; transform-origin: 0 50%;
  transform: translateX(calc((1 - var(--t)) * -45vw)) scale(calc(1 + (1 - var(--t)) * 1.4));
}
.about-body { margin-top: 1.6rem; opacity: var(--o); font-size: clamp(1.0625rem, min(1.25vw, 2.5vh), 1.3125rem); }
.about-body p + p { margin-top: 1em; }
.about-phone { right: 12vw; bottom: -24vh; height: min(64vh, 45vw); opacity: var(--o); }

.foot { position: relative; z-index: 4; background: var(--blood); color: rgba(255, 255, 255, .7); padding: 10.8vh 8vw 3.6vh; }
.foot-in { display: flex; gap: 8vw; align-items: flex-start; max-width: 62vw; }
.foot-cta { font-size: clamp(1.375rem, min(1.8vw, 3.6vh), 1.75rem); font-weight: 300; color: rgba(255, 255, 255, .5); letter-spacing: .06em; line-height: 1.5; }
.foot-cta b { font-weight: 500; color: var(--white); }
.foot-name { font-size: clamp(2rem, min(3vw, 6vh), 3.2rem); font-weight: 300; letter-spacing: .14em; color: rgba(255, 255, 255, .8); }
.foot-brand address { margin-top: .6rem; font-size: clamp(1rem, min(1.1vw, 2.2vh), 1.125rem); line-height: 1.6; }
.foot-brand a:hover { color: var(--white); }
.foot-services { margin-top: 7vh; text-align: center; font-size: clamp(1rem, min(1.1vw, 2.2vh), 1.125rem); color: var(--white); }
.foot-copy { margin-top: 2.5vh; text-align: center; font-size: .875rem; color: rgba(255, 255, 255, .55); }

/* =========================================================
   TABLET + MOBILE
   ========================================================= */
@media (max-width: 1024px) {
  .social-show { left: 6vw; }
  .social-copy { left: 52vw; width: 44vw; }
  .social .title { white-space: normal; }
  .video-copy { width: 40vw; }
}

/* MOBILE LAYOUT = portrait up to 1100px (phones + portrait tablets).
   Phones (≤ 767px) use exactly these values; portrait tablets scale them up below. */
@media (orientation: portrait) and (max-width: 1100px) {
  html { font-size: 100%; }
  :root { --fs-title: 1.2rem; --track-title: .26em; }
  .nav { --w-open: calc((100vw - 24px) * .9); top: max(18px, env(safe-area-inset-top)); width: 52px; height: 52px; border-radius: 26px; }
  .nav-logo { flex-basis: 52px; height: 52px; }
  .nav-logo img { width: 32px; height: 32px; }
  .nav-links { display: none; }
  .nav-icons { flex: 1; justify-content: flex-end; padding: 0 10px 0 4px; gap: .375rem; }
  .nav-icons a { width: 32px; height: 44px; }
  .nav-icons svg { width: 20px; height: 20px; }

  /* mobile: own float positions, track 1500 units wide */
  .floats { --H: 100svh; --u: calc(100vw / 700); }
  .drift {
    --end: calc(100vw - var(--u) * 1500); width: calc(var(--u) * 1500); animation-duration: 40s;
    height: var(--H); margin-top: calc(var(--H) / -2);
  }
  .fl:not(.m) { display: none; }
  .f09 { left: calc(var(--u) * 300);  top: calc(var(--u) * 160);  width: calc(var(--u) * 430); }
  .f05 { left: calc(var(--u) * 20);   top: calc(var(--u) * 300);  width: calc(var(--u) * 220); }
  .f07 { left: calc(var(--u) * 500);  top: calc(var(--u) * 960);  width: calc(var(--u) * 230); }
  .f12 { left: calc(var(--u) * 60);   top: calc(var(--u) * 1080); width: calc(var(--u) * 480); }
  .f06 { left: calc(var(--u) * 960);  top: calc(var(--u) * 280);  width: calc(var(--u) * 270); }
  .f03 { left: calc(var(--u) * 820);  top: calc(var(--u) * 1040); width: calc(var(--u) * 300); }
  .f02 { left: calc(var(--u) * 1180); top: calc(var(--u) * 700);  width: calc(var(--u) * 260); }
  .hero-bg { background-image: url(../img/hero-bg-m.webp); }
  .hero-title { font-size: 2rem; letter-spacing: .14em; margin-right: -.14em; }
  .br-m { display: inline; }
  .hero-sub { font-size: .9375rem; max-width: 30ch; margin-inline: auto; }

  .slide.sq img { width: 140%; }
  /* frame: 15% smaller, and never taller than the space above the text (text needs ~19rem) */
  .social-show { --ph: min(44svh, calc(82svh - 19rem)); left: 50%; top: 12svh; margin-top: 0; margin-left: calc(var(--pw) / -2); }
  .social-copy { left: 8vw; right: 8vw; width: auto; top: auto; bottom: 6svh; transform: none; text-align: center; }
  .social .title, .video .title, .web .title, .about .title, .packs .title { font-size: 1.6rem; letter-spacing: .1em; }
  .social .body, .video .body, .web .body { font-size: 1rem; }
  .social .body { margin-inline: auto; }
  .btns { justify-content: center; }
  .phone-logo { display: none; }   /* the menu logo is right above it */

  /* long text: 2 lines + "Read more" (JS). The full text stays in the HTML.
     Open: the full text shows and the images above hide, so nothing overlaps. */
  .js .social .body, .js .video .body, .js .web .body {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  }
  .js .is-more .body { display: block; -webkit-line-clamp: unset; line-clamp: none; overflow: visible; }
  .js .more { display: inline-block; }
  .js .more[hidden] { display: none; }
  .is-more .social-show, .is-more .dev-tablet, .is-more .dev-phone { visibility: hidden; }

  .video-bg { background-image: url(../img/silk-bg-m.webp); }
  /* devices: ~18% smaller, and their bottom stays above the text (top + height <= 93svh - 18rem) */
  .dev-tablet { left: 20vw; top: 20svh; width: min(74vw, calc((73svh - 18rem) * 4 / 3)); padding: 6px; border-radius: 16px; }
  .dev-tablet video { border-radius: 11px; }
  .dev-phone { height: min(30svh, calc(74svh - 18rem)); border-radius: 22px; padding: 4px; }
  .dev-phone video { border-radius: 18px; }
  .video .dev-phone { left: 7vw; top: 19svh; }
  .video-copy { left: 8vw; right: 8vw; width: auto; top: auto; bottom: 7svh; transform: none; text-align: center; }
  .video .body { margin-inline: auto; }

  .web-in { padding-top: 13vh; padding-inline: 8vw; }
  .web-devices { width: 145vw; }
  /* demo sites: one column, card width from the height left over (~23.5rem of text + buttons) */
  .demos { --cw: min(84vw, calc((83svh - 23.5rem) * .8)); flex-direction: column; align-items: center; gap: 1.25rem; padding-top: 1.25rem; }
  .demo-phone { border-width: 2px; }
  .demo-name { margin-top: .8rem; }
  .web .btns { margin-top: 1.25rem; }

  /* flow-root: the phone's negative margin then pulls the footer up under it,
     instead of stretching this white section over the footer */
  .about { display: flow-root; padding: 16vh 8vw 0; text-align: left; }
  .about-body { font-size: 1rem; }
  .about-copy { width: auto; }
  /* phone sits across the line between this section and the footer (half above, half below) */
  .about-phone { position: relative; right: auto; bottom: auto; height: 60svh; margin: 6vh auto -30svh; }
  .foot { padding-top: calc(30svh + 7.2vh); text-align: center; }
  .foot-in { flex-direction: column; align-items: center; gap: 5vh; max-width: none; }
  .foot-services { margin-top: 5vh; }
}

/* PORTRAIT TABLET (768–1100px): the mobile layout above, scaled up to fit.
   1rem grows by min(vw, vh) against a 390 × 844 phone; the px sizes of the mobile block are re-set in rem. */
@media (orientation: portrait) and (min-width: 768px) and (max-width: 1100px) {
  html { font-size: min(calc(100vw * 16 / 390), calc(100vh * 16 / 844)); }
  .nav { --w-open: min(calc((100vw - 1.5rem) * .9), 20.5875rem); top: max(1.125rem, env(safe-area-inset-top)); width: 3.25rem; height: 3.25rem; border-radius: 1.625rem; }
  .nav-logo { flex-basis: 3.25rem; height: 3.25rem; }
  .nav-logo img { width: 2rem; height: 2rem; }
  .nav-icons { padding: 0 .625rem 0 .25rem; }
  .nav-icons a { width: 2rem; height: 2.75rem; }
  .nav-icons svg { width: 1.25rem; height: 1.25rem; }

  /* floats: same track as the phone, sized by min(vw, vh) so it fits the taller-than-wide screen */
  .floats { --u: min(calc(100vw / 700), calc(100svh / 1515)); }
  .drift { --end: min(0px, calc(100vw - var(--u) * 1500)); }

  /* devices sized by min(vw, vh) so they stay above the text */
  .dev-tablet { left: calc(7vw + 6svh); width: min(74vw, 46svh, calc((73svh - 18rem) * 4 / 3)); padding: .375rem; border-radius: 1rem; }
  .dev-tablet video { border-radius: .6875rem; }
  .dev-phone { border-radius: 1.375rem; padding: .25rem; }
  .dev-phone video { border-radius: 1.125rem; }
  .web-devices { width: min(145vw, 80svh); }
  /* demo sites: two columns, card width from min(vw, height left over ~21.5rem) */
  .demos { --cw: min(calc((84vw - 1.5rem) / 2), calc((83svh - 21.5rem) * 1.6)); flex-direction: row; align-items: flex-start; gap: 1.5rem; }
  .demo-phone { border-width: .125rem; }
}

/* =========================================================
   MOBILE BROWSER TOOLBARS
   When the toolbars hide on scroll the screen grows from 100svh to 100lvh.
   Pinned screens fill 100lvh (no white strip), content stays placed against 100svh (no jump).
   On desktop svh = lvh, so nothing changes. Browsers without lvh keep the rules above.
   ========================================================= */
@supports (height: 100lvh) {
  .stage, .web-in { height: 100lvh; }
  .drift { top: 50svh; }
  .hero-copy { top: 50svh; }
  @media (orientation: landscape), (min-width: 1101px) {
    .social-show, .social-copy, .video-copy { top: 50svh; }
  }
  @media (orientation: portrait) and (max-width: 1100px) {
    .social-copy { bottom: calc(6svh + 100lvh - 100svh); }
    .video-copy { bottom: calc(7svh + 100lvh - 100svh); }
  }
}

/* =========================================================
   REDUCED MOTION: no pinning, no drifting, final states
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .scene, .web { height: auto !important; }
  .web-in { position: relative; height: auto; }
  .web { scroll-margin-top: 0; }
  .social { margin-top: 0; }
  .stage { position: relative; }
  [data-scene], .js [data-scene]:not(.hero) { --e: 1 !important; --p: 0 !important; }
  .hero { animation: none; }
  .drift, .nav::before, .nav::after { animation: none; }
  .nav, .btn, .nav-links a, .nav-icons a, .nav-logo { transition: none; }
}

/* 404 */
.e404-in { min-height: 100vh; display: grid; place-content: center; justify-items: center; text-align: center; gap: 1rem; padding: 8vw; }
.e404 .btns { justify-content: center; margin-top: .5rem; }

/* =========================================================
   4b PACKAGES
   Two groups (Normal / Full), 3 packages each. A package fills wine on mouse-over / tap (JS adds .is-on on tap).
   Mobile layout: packages stacked.
   ========================================================= */
.packs { position: relative; z-index: 5; background: var(--white); padding: 12vh 8vw 9vh; }
.packs-in { max-width: 1100px; margin: 0 auto; }
.packs-header { text-align: center; }
.packs-sub { margin-top: .9rem; font-size: .8125rem; font-weight: 500; letter-spacing: .2em; color: var(--wine); }

.pk-group { position: relative; margin-top: 3rem; }
/* short hairline between the two groups */
.pk-group + .pk-group { margin-top: 2.25rem; padding-top: 2.25rem; }
.pk-group + .pk-group::before { content: ""; position: absolute; top: 0; left: 25%; right: 25%; border-top: 1px solid var(--hair); }

/* group label on the left (lined up with the package text), thick wine bar on the right */
.pk-head { position: relative; padding: 0 12rem 0 1.6rem; }
.pk-head::after { content: ""; position: absolute; right: 0; top: .45rem; width: min(9rem, 22%); height: .3125rem; background: var(--wine); }
.pk-label { font-size: .8125rem; font-weight: 500; letter-spacing: .3em; color: var(--wine); }
.pk-hsub { margin-top: .2rem; font-size: .8125rem; color: var(--strong); }

.pk-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem; margin-top: 1.25rem; }
.pk {
  position: relative; isolation: isolate; display: flex; flex-direction: column; padding: 1.25rem 1.6rem 1.35rem;
  border-radius: .5rem; color: var(--strong); cursor: default;
}
/* the wine fill fades in (opacity only) */
.pk::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--wine); opacity: 0; transition: opacity .3s; }
.pk-name { font-size: 1.25rem; font-weight: 500; letter-spacing: .04em; line-height: 1.3; color: var(--wine); }
.pk-tag { margin-top: .5rem; font-size: .75rem; font-weight: 500; letter-spacing: .06em; line-height: 1.45; }
.pk-items { margin-top: .6rem; font-size: .8125rem; line-height: 1.55; letter-spacing: .03em; }
/* prices line up at the bottom of every package */
.pk-price {
  margin-top: auto; padding-top: 1.1rem; font-size: clamp(1.75rem, min(2.6vw, 5.2vh), 2.4rem); font-weight: 300;
  line-height: 1.1; letter-spacing: .14em; font-variant-numeric: tabular-nums; color: var(--wine);
}
/* on: mouse-over (real hover only) or tapped */
.pk.is-on::before { opacity: 1; }
.pk.is-on { color: rgba(255, 255, 255, .82); }
.pk.is-on .pk-name, .pk.is-on .pk-price { color: var(--rose); }
@media (hover: hover) {
  .pk:hover::before { opacity: 1; }
  .pk:hover { color: rgba(255, 255, 255, .82); }
  .pk:hover .pk-name, .pk:hover .pk-price { color: var(--rose); }
}

@media (orientation: portrait) and (max-width: 1100px) {
  .packs { padding: 9vh 8vw 7vh; }
  .pk-group { margin-top: 2rem; }
  .pk-head { padding: 0 6.5rem 0 1.4rem; }
  .pk-head::after { width: 5rem; }
  .pk-list { grid-template-columns: minmax(0, 1fr); gap: .75rem; margin-top: 1.25rem; }
  .pk { padding: 1.1rem 1.4rem 1.2rem; }
  .pk-tag { font-size: .875rem; }
  .pk-items { font-size: .9375rem; }
  .pk-price { padding-top: .8rem; font-size: 2rem; }
}

/* =========================================================
   PRICE LIST POP-UP (Social "Price" button)
   ========================================================= */
.price-box {
  width: min(92vw, 1000px); max-width: none; max-height: 94svh; padding: 1rem 1rem 1.25rem; border: 0; border-radius: 1rem;
  background: var(--white); box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .5); overflow: auto;
}
.price-box::backdrop { background: rgba(50, 0, 0, .55); }
.price-box img { width: 100%; height: auto; max-height: calc(94svh - 7rem); object-fit: contain; border-radius: .5rem; }
.price-box .btns { justify-content: center; margin-top: 1rem; }
.price-box .btn { font: inherit; font-size: .9375rem; padding: .7em 2.2em; cursor: pointer; }
.price-box .btn { border-color: var(--wine); color: var(--strong); }   /* also inside the dark Video section */
.price-box .btn-fill { background: var(--wine); color: var(--white); }
html:has(.price-box[open]) { overflow: hidden; }   /* page doesn't scroll behind it */
