/* Fanntasy teaser (D-367). One static page, two views:
   desk  = a wide screen with a mouse: the cursor is a keyhole you move around to find four hidden things;
   phone = everything else: a keyhole in the middle you press and hold to open the door.
   Colours are the app's Scarlet night (D-130); type is Gloock, Bodoni Moda Italic and Bricolage. */

@font-face { font-family: "Gloock"; src: url("fonts/gloock.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Bodoni Moda"; src: url("fonts/bodoni-italic.woff2") format("woff2"); font-weight: 500 650; font-style: italic; font-display: swap; }
@font-face { font-family: "Bricolage Grotesque"; src: url("fonts/bricolage.woff2") format("woff2"); font-weight: 400 700; font-display: swap; }

:root {
  --night: #0e0306; --edge: #1c0609; --scarlet: #e0233f; --wine: #a81a30; --alta: #ff2742;
  --moon: #fff3f5; --soft: rgb(255 243 245 / .66); --faint: rgb(255 243 245 / .38); --brass: #f0c9a0;
  --serif: "Gloock", Georgia, serif;
  --ital: "Bodoni Moda", Georgia, serif;
  --ui: "Bricolage Grotesque", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --st: env(safe-area-inset-top, 0px); --sb: env(safe-area-inset-bottom, 0px);
  --sl: env(safe-area-inset-left, 0px); --sr: env(safe-area-inset-right, 0px);
  /* the keyhole, soft-edged; JS sets its size and place */
  --key: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-20 -20 240 320'%3E%3Cfilter id='b' x='-40%25' y='-40%25' width='180%25' height='180%25'%3E%3CfeGaussianBlur stdDeviation='3.5'/%3E%3C/filter%3E%3Cpath filter='url(%23b)' d='M67.8 138A62 62 0 1 1 132.2 138L146 280H54Z'/%3E%3C/svg%3E");
  --mw: 0px; --mh: 0px; --mx: -999px; --my: -999px;
  /* phone portal: the keyhole's own box (124 × 257 in its drawing) */
  --pw: clamp(96px, min(30vw, 14.5svh), 150px);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  overflow: hidden; overscroll-behavior: none; position: fixed; inset: 0;
  background: var(--night); color: var(--moon); font-family: var(--ui);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  touch-action: none;
}
/* film grain over everything */
body::after {
  content: ""; position: fixed; inset: -50%; z-index: 9; pointer-events: none; opacity: .09; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- layers ---------- */
.layer { position: fixed; inset: 0; overflow: hidden; }
.out {
  background:
    radial-gradient(75% 55% at 92% -4%, rgb(224 35 63 / .62) 0%, rgb(168 26 48 / .32) 32%, rgb(80 16 28 / .12) 58%, transparent 78%),
    radial-gradient(60% 45% at -6% 104%, rgb(120 14 36 / .45), transparent 70%),
    linear-gradient(180deg, var(--edge) 0%, var(--night) 34%);
}
.in {
  z-index: 2; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 40%, #ffffff 0%, #fffafa 45%, #fbefee 100%);
  -webkit-mask: var(--key) no-repeat; mask: var(--key) no-repeat;
  -webkit-mask-size: var(--mw) var(--mh); mask-size: var(--mw) var(--mh);
  -webkit-mask-position: var(--mx) var(--my); mask-position: var(--mx) var(--my);
}
.in::before { /* a whisper of shade at the edges of the white room */
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(90% 70% at 50% 45%, transparent 55%, rgb(120 10 30 / .08) 100%);
}

.giant { position: absolute; left: 50%; bottom: -3vw; width: 112vw; transform: translateX(-50%); opacity: .055; pointer-events: none; }
.giant svg { display: block; width: 100%; height: auto; }

.rim { position: fixed; left: 0; top: 0; z-index: 3; width: 240px; height: 320px; transform-origin: 0 0; pointer-events: none; will-change: transform, opacity; opacity: 0; }
.rim svg { display: block; width: 100%; height: 100%; overflow: visible; }
.rim path { fill: none; stroke: var(--brass); stroke-width: 1.4; vector-effect: non-scaling-stroke; filter: drop-shadow(0 0 6px rgb(255 120 130 / .55)); }

/* ---------- centre copy, the same box in both layers so "Not yet." and "Soon." sit on each other ---------- */
.center { position: absolute; display: flex; flex-direction: column; }
.hl { margin: 0; font-weight: 400; line-height: .92; letter-spacing: -.02em; }
.out .hl { font-family: var(--serif); color: var(--moon); }
.in .hl { font-family: var(--ital); font-style: italic; font-weight: 560; color: var(--scarlet); letter-spacing: -.01em; }
.sub { margin: 0; font-size: 18px; line-height: 1.45; color: var(--soft); max-width: 30ch; }
.in .sub { color: #b3132e; }
.hint { margin: 0; font-family: var(--ital); font-style: italic; font-weight: 560; color: var(--alta); }
.in .hint { color: var(--scarlet); }

.spot { position: absolute; display: flex; flex-direction: column; align-items: center; gap: 6px; transform: rotate(var(--r, 0deg)); animation: float 7s ease-in-out infinite; animation-delay: var(--d, 0s); }
.spot .shape { display: block; width: var(--sw, 180px); height: auto; filter: drop-shadow(0 10px 18px rgb(120 10 30 / .16)); }
.word { font-family: var(--ital); font-style: italic; font-weight: 560; line-height: 1; color: var(--scarlet); letter-spacing: -.01em; }
@keyframes float { 50% { transform: rotate(var(--r, 0deg)) translateY(-12px); } }

.portal { flex: none; display: grid; place-items: center; }
.cycle { font-family: var(--ital); font-style: italic; font-weight: 560; color: var(--scarlet); transition: opacity .35s ease, filter .35s ease; transform: translateY(-18%); }
.cycle.fade { opacity: 0; filter: blur(4px); }

/* ---------- chrome ---------- */
.chromewrap { position: fixed; inset: 0; z-index: 5; pointer-events: none; }
.chrome { position: absolute; left: 0; right: 0; pointer-events: auto; }
.cut { stroke: var(--cut, #0e0306); }
/* desk: the real chrome has a keyhole cut out of it, and a red copy (.ghost, made by teaser.js) sits in the white room */
.desk .chromewrap {
  -webkit-mask-image: linear-gradient(#000 0 0), var(--key); mask-image: linear-gradient(#000 0 0), var(--key);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%, var(--mw) var(--mh); mask-size: 100% 100%, var(--mw) var(--mh);
  -webkit-mask-position: 0 0, var(--mx) var(--my); mask-position: 0 0, var(--mx) var(--my);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.ghost { display: none; position: absolute; inset: 0; z-index: 1; --cut: #fff; }
.desk .ghost { display: block; }
.ghost .chrome { animation: none; }
.ghost .mark, .ghost .ig, .ghost .found em { color: var(--scarlet); }
.ghost .meta, .ghost .secret, .ghost .found { color: rgb(200 16 46 / .6); }
.ghost .ig { border-color: rgb(224 35 63 / .35); }
.mark { display: block; color: var(--moon); }
.meta, .found, .secret { margin: 0; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); }
.ig { color: var(--moon); font-size: 14px; text-decoration: none; letter-spacing: .02em; border-bottom: 1px solid rgb(255 243 245 / .3); padding-bottom: 2px; transition: border-color .2s, color .2s; }
.ig:hover, .ig:focus-visible { color: #fff; border-color: var(--alta); outline: none; }
.found em { font-family: var(--ital); font-style: italic; font-weight: 560; text-transform: none; letter-spacing: 0; font-size: 15px; color: var(--moon); }
.found .gap { opacity: .4; }

.hold {
  position: relative; display: inline-flex; align-items: center; gap: 12px; height: 56px; padding: 0 26px 0 12px;
  border-radius: 999px; border: 1px solid rgb(255 243 245 / .28); color: var(--moon); font: 500 16px/1 var(--ui);
  background: rgb(28 6 9 / .55); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  touch-action: none; cursor: pointer; transition: transform .2s ease, border-color .2s;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.hold:active, .hold.on { transform: scale(.96); border-color: rgb(255 39 66 / .7); }
.hold:focus-visible { outline: 2px solid var(--alta); outline-offset: 3px; }
.ring { --p: 0; position: relative; width: 34px; height: 34px; border-radius: 50%;
  background: conic-gradient(var(--alta) calc(var(--p) * 1turn), rgb(255 243 245 / .16) 0); }
.ring::after { /* a little keyhole in the ring */
  content: ""; position: absolute; inset: 3px; border-radius: 50%; background: #1a0508 no-repeat center / 12px 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='38 20 124 262'%3E%3Cpath fill='%23fff3f5' d='M67.8 138A62 62 0 1 1 132.2 138L146 280H54Z'/%3E%3C/svg%3E");
}

/* phone, door open: the white room is behind the chrome, so the chrome turns red */
.chrome .mark, .meta, .secret, .ig, .hold { transition: color .3s ease, background-color .3s ease, border-color .3s ease; }
.open .chrome .mark, .open .ig { color: var(--scarlet); }
.open .chromewrap { --cut: #fff; }
.open .meta, .open .secret { color: rgb(200 16 46 / .6); }
.open .ig { border-color: rgb(224 35 63 / .35); }
.open .hold { color: var(--scarlet); background: rgb(255 255 255 / .7); border-color: rgb(224 35 63 / .45); }
.open .ring::after { background-color: #fff; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='38 20 124 262'%3E%3Cpath fill='%23e0233f' d='M67.8 138A62 62 0 1 1 132.2 138L146 280H54Z'/%3E%3C/svg%3E"); }

/* ---------- arrival ---------- */
.out .center > *, .chrome { animation: rise .9s cubic-bezier(.2,.7,.2,1) both; }
.out .hl { animation-delay: .1s; } .out .sub { animation-delay: .25s; } .out .hint { animation-delay: .4s; }
.foot { animation-delay: .55s; }
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }

/* =================================================================
   PHONE view (default): portal in the middle, hold to open the door
   ================================================================= */
.top { top: 0; padding: calc(var(--st) + 22px) 20px 0; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.top .mark { width: 124px; height: auto; }
.top .meta { font-size: 10.5px; }

.center { inset: calc(var(--st) + 92px) calc(var(--sr) + 22px) calc(var(--sb) + 168px) calc(var(--sl) + 22px); align-items: center; justify-content: center; text-align: center; gap: 0; }
.portal { width: var(--pw); height: calc(var(--pw) * 257 / 124); margin-bottom: clamp(26px, 4.5svh, 42px); }
.cycle { font-size: calc(var(--pw) * .3); }
.hl { font-size: clamp(54px, 17vw, 88px); }
.sub { margin-top: 12px; font-size: 16px; }
.out .hint { display: none; }
.in .hint { margin-top: 10px; font-size: 22px; }
.in .hl { position: relative; top: .1em; }
.desk .in .hl { top: 0; }
.in .sub { max-width: 28ch; }

.foot { bottom: 0; padding: 0 20px calc(var(--sb) + 18px); display: flex; flex-direction: column; align-items: center; gap: 14px; }
.foot .found { display: none; }
.foot .secret { font-size: 10.5px; }

.giant { width: 160vw; bottom: 0; opacity: .045; }

.spot { --sw: 120px; }
.word { font-size: 30px; }
.s-kiss    { top: calc(var(--st) + 7%); left: -6%;  --r: -14deg; --sw: 118px; }
.s-bitten  { top: calc(var(--st) + 9%); right: -2%; --r: 8deg;  --sw: 92px; --d: -2s; }
.s-worn    { bottom: 14%; right: 1%; --r: -8deg; --sw: 84px; --d: -4s; }
.s-stepped { bottom: 10%; left: 2%;    --r: 10deg; --sw: 62px;  --d: -1s; }

@media (max-height: 600px) {
  .top { padding-top: calc(var(--st) + 14px); } .top .mark { width: 104px; }
  .center { top: calc(var(--st) + 70px); bottom: calc(var(--sb) + 150px); }
  .sub { font-size: 14.5px; }
}

/* =================================================================
   DESK view: a wide screen with a mouse; the cursor is the keyhole
   ================================================================= */
.desk body { cursor: none; }
.desk .ig { cursor: pointer; }
.desk .top { padding: 36px 48px 0; flex-direction: row; justify-content: space-between; align-items: center; }
.desk .top .mark { width: 168px; }
.desk .top .meta { font-size: 12px; }

.desk .center { inset: 0 auto 0 8vw; width: 64vw; align-items: flex-start; text-align: left; justify-content: center; }
.desk .portal { display: none; }
.desk .hl { font-size: clamp(120px, 14.5vw, 260px); }
.desk .sub { margin-top: 28px; font-size: clamp(18px, 1.35vw, 24px); max-width: 34ch; }
.desk .out .hint { display: block; margin-top: 14px; font-size: clamp(26px, 2vw, 36px); }
.desk .in .hint { margin-top: 14px; font-size: clamp(26px, 2vw, 36px); }
.desk .in .sub { margin-top: 28px; }

.desk .foot { padding: 0 48px 34px; flex-direction: row; justify-content: space-between; align-items: flex-end; gap: 24px; }
.desk .foot .hold { display: none; }
.desk .foot .found { display: block; order: 0; margin-right: auto; font-size: 11.5px; }
.desk .foot .ig { order: 1; }
.desk .foot .secret { order: 2; font-size: 11.5px; }

.desk .giant { width: 112vw; bottom: -10vw; opacity: .04; }

.desk .word { font-size: clamp(56px, 6.4vw, 118px); }
.desk .s-kiss    { top: 9%;  left: 44%;  --r: -10deg; --sw: clamp(150px, 13vw, 240px); }
.desk .s-bitten  { top: 14%; right: 6%;  --r: 8deg;   --sw: clamp(120px, 9vw, 170px); --d: -2s; }
.desk .s-worn    { bottom: 12%; right: 12%; --r: -4deg; --sw: clamp(120px, 9.5vw, 180px); --d: -4s; }
.desk .s-stepped { bottom: 6%; left: 30%; --r: 12deg; --sw: clamp(70px, 5.4vw, 104px); --d: -1s; }

@media (prefers-reduced-motion: reduce) {
  .spot, .out .center > *, .chrome { animation: none; }
  .cycle { transition: none; }
}

.defs { position: absolute; width: 0; height: 0; }
