/* cocoawagner clone - layout in Readymag design units (1024 desktop / 320 phone) scaled by --su */
:root { --su: calc(100vw / 1024); }
@media (max-width: 768px) { :root { --su: calc(100vw / 320); } }
@font-face { font-family: 'CocoaHand'; src: url('/fonts/cocoa-hand.ttf') format('truetype'); font-display: swap; }
@font-face { font-family: 'TitleFont'; src: url('/fonts/archivo-black.woff2') format('woff2'); font-weight: 400 700; font-display: swap; }
* { box-sizing: border-box; }
/* overflow-x: clip (not hidden) so body never becomes its own scroll container: with "hidden" + overscroll-behavior,
   Chrome refused to chain a wheel scroll from the body to the page once the decorative pictures stopped catching the pointer */
html { -webkit-text-size-adjust: 100%; overflow-x: hidden; overflow-x: clip; background: #fff; }
body { margin: 0; min-height: 100vh; overflow-x: hidden; overflow-x: clip; font-family: 'CocoaHand', 'Courier New', monospace; color: #222; -webkit-tap-highlight-color: transparent; }
a { color: inherit; }
img, video { display: block; }
.bg { position: fixed; inset: 0; z-index: 0; background-size: cover; background-position: center; pointer-events: none; }
.page { position: relative; z-index: 1; width: 100%; }

/* ---- hand-drawn star cursor (Readymag project setting), 28x33 with a 20x23 star over anything clickable.
   Layered declarations so each browser takes the sharpest form it supports: plain PNG, then SVG with a 2x raster inside,
   then image-set 1x/2x/3x (later valid declarations win). Built by scripts/make-cursor.mjs. ---- */
html, body { cursor: url('/img/cursor.png') 14 16, auto; cursor: url('/img/cursor.svg') 14 16, auto; cursor: -webkit-image-set(url('/img/cursor.png') 1x, url('/img/cursor@2x.png') 2x, url('/img/cursor@3x.png') 3x) 14 16, auto; cursor: image-set(url('/img/cursor.png') 1x, url('/img/cursor@2x.png') 2x, url('/img/cursor@3x.png') 3x) 14 16, auto; }
a, button, [role="button"], .card .a, .dd a, .sound-badge.show { cursor: url('/img/cursor-hover.png') 10 12, pointer; cursor: url('/img/cursor-hover.svg') 10 12, pointer; cursor: -webkit-image-set(url('/img/cursor-hover.png') 1x, url('/img/cursor-hover@2x.png') 2x, url('/img/cursor-hover@3x.png') 3x) 10 12, pointer; cursor: image-set(url('/img/cursor-hover.png') 1x, url('/img/cursor-hover@2x.png') 2x, url('/img/cursor-hover@3x.png') 3x) 10 12, pointer; }
@media (hover: none) and (pointer: coarse) { html, body, a, button, .card .a, .dd a { cursor: auto; } .dd { display: none !important; } }

/* ---- widgets ---- */
.w { position: absolute; width: calc(var(--dw) * var(--su)); height: calc(var(--dh) * var(--su)); z-index: var(--z, 1); }
.w > .a { width: 100%; height: 100%; transform-origin: 50% 50%; }
.w .a > a, .w .a > img, .w .a > div { display: block; width: 100%; height: 100%; }
.w img { width: 100%; height: 100%; -webkit-user-drag: none; user-select: none; transform: rotate(var(--rot, 0deg)) scaleX(var(--fh, 1)) scaleY(var(--fv, 1)); }
/* decorative pictures and text never catch the pointer, so clouds that have faded out cannot block the buttons under them */
.w.pic:not(.lnk), .w.text { pointer-events: none; }
/* desktop anchoring: (x,y) = offset of the widget centre from the anchor; page-relative uses top-left in a 1024 frame */
@media (min-width: 769px) {
  .fx-n, .fx-c, .fx-s { position: fixed; left: calc(50% + (var(--dx) - var(--dw) / 2) * var(--su)); }
  .fx-n { top: calc(var(--dy) * var(--su)); }
  .fx-c { top: calc(50% + (var(--dy) - var(--dh) / 2) * var(--su)); }
  .fx-s { bottom: calc(var(--dy) * var(--su)); }
  .fx-p { left: calc(50% + (var(--dx) - 512) * var(--su)); top: calc(var(--dy) * var(--su)); }
  .row .fx-c, .row .fx-n, .row .fx-s { position: absolute; }
  .w { --rot: var(--dr, 0deg); }
  .d-hide { display: none !important; }
}
@media (max-width: 768px) {
  .w { width: calc(var(--pw) * var(--su)); height: calc(var(--ph) * var(--su)); --rot: var(--pr, 0deg); }
  .pfx-n, .pfx-c, .pfx-s { position: fixed; left: calc(50% + (var(--px) - var(--pw) / 2) * var(--su)); }
  .pfx-n { top: calc(var(--py) * var(--su)); }
  .pfx-c { top: calc(50% + (var(--py) - var(--ph) / 2) * var(--su)); }
  .pfx-s { bottom: calc(var(--py) * var(--su)); }
  .pfx-p { left: calc(50% + (var(--px) - 160) * var(--su)); top: calc(var(--py) * var(--su)); }
  .m-hide { display: none !important; }
}

/* ---- moon + "client work" / sun + "personal projects" buttons: hovering either part animates the graphic ---- */
.btn img { transform-origin: 50% 50%; will-change: transform; }
.moon.hot img { animation: rock 2.6s ease-in-out infinite; }
.sun.hot img { animation: pulse 1.8s ease-in-out infinite; }
@keyframes rock { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } }
/* contact page: the big envelope rocks on hover and shows the address under itself as a second mailto link (web only) */
.mail-btn img { transform-origin: 50% 50%; will-change: transform; }
.mail-btn:hover img, .mail-btn:focus-within img { animation: rock-mail 1.6s ease-in-out infinite; }
@keyframes rock-mail { 0%, 100% { transform: rotate(-8deg); } 50% { transform: rotate(8deg); } }
.w .a > a.mail-addr { position: absolute; left: 50%; top: 100%; width: auto; height: auto; transform: translateX(-50%); padding-top: calc(6 * var(--su)); font-size: calc(17 * var(--su)); line-height: 1.2; color: #222; text-decoration: underline; text-underline-offset: .15em; text-decoration-thickness: 1px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .15s; }
.w.mail-btn:hover .a > a.mail-addr, .w.mail-btn:focus-within .a > a.mail-addr { opacity: 1; pointer-events: auto; }
@media (hover: none) and (pointer: coarse) { .w .a > a.mail-addr { display: none; } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }

/* ---- shared banner: portfolio drop-down ---- */
.nav-portfolio .a { position: relative; }
.dd { position: absolute; left: 16%; /* lines up with the p of "portfolio" (ink starts ~40px into the 250px image) */ top: 100%; margin: 0; padding: calc(10 * var(--su)) 0 0; list-style: none; display: none; min-width: 100%; }
.nav-portfolio:hover .dd, .nav-portfolio:focus-within .dd, .nav-portfolio.open .dd { display: block; }
.dd li { margin: 0 0 calc(3 * var(--su)); }
.dd a { display: inline-block; text-decoration: none; color: #9a9a9a; font-size: calc(22 * var(--su)); line-height: 1.2; letter-spacing: .02em; padding: 0 calc(3 * var(--su)); white-space: nowrap; transition: color .15s; }
.dd a:hover, .dd a:focus-visible { color: #222; }
.dd a.active { text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px; }
@media (max-width: 768px) {
  .dd { display: none !important; } /* no drop-down in the mobile layout: tapping "portfolio" goes straight to the portfolio page */
}

/* ---- text ---- */
.w.text { font-size: calc(var(--fs) * var(--su)); line-height: calc(var(--lh) * var(--su)); letter-spacing: calc(var(--ls, 0) * var(--su)); white-space: pre-wrap; overflow-wrap: anywhere; }
.w.text .a { display: flex; flex-direction: column; justify-content: var(--vj, flex-start); }
.f-hand { font-family: 'CocoaHand', 'Courier New', monospace; font-weight: 400; }
.f-title { font-family: 'TitleFont', 'Arial Black', Impact, sans-serif; font-weight: 400; text-transform: uppercase; }
@media (max-width: 768px) { .w.text { font-size: calc(var(--pfs, var(--fs)) * var(--su)); line-height: calc(var(--plh, var(--lh)) * var(--su)); } }

/* ---- video cards ---- */
.card { margin: 0; }
.card .a { position: relative; }
.card video { width: 100%; height: 100%; object-fit: cover; background: #000; transform: scale(.9); opacity: .8; transition: transform .45s cubic-bezier(.2,.7,.2,1), opacity .45s ease; transform-origin: 50% 50%; }
/* the title sits inside the minimised (90%) thumbnail; site.js shrinks the font until the words fit */
.card .title { position: absolute; inset: 9% 8%; display: flex; align-items: center; justify-content: center; text-align: center; color: #fff; font-size: calc(var(--fs) * var(--su) * .82); line-height: 1; letter-spacing: calc(var(--ls, .6) * var(--su)); padding: 0; margin: 0; pointer-events: none; transition: opacity .12s ease; overflow-wrap: normal; word-break: normal; overflow: hidden; }
.card.on video, .card.big video { transform: none; opacity: 1; }
.card.on .title, .card.big .title { opacity: 0; transition: none; }
.card.personal video { opacity: .6; }
.card.personal.on video, .card.personal.big video { opacity: 1; }
.dim { position: fixed; inset: 0; z-index: 200; background: #000; opacity: 0; pointer-events: none; transition: opacity .45s ease; }
body.dimmed .dim { opacity: .5; }
body.expanded .dim { opacity: .88; pointer-events: auto; }
.sound-badge { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 400; background: rgba(34,34,34,.85); color: #fff; font: 400 15px/1 'CocoaHand', monospace; padding: 10px 16px; border-radius: 999px; opacity: 0; pointer-events: none; transition: opacity .3s; }
.sound-badge.show { opacity: 1; pointer-events: auto; }

/* client desktop row + affordances */
.row { position: fixed; inset: 0; z-index: 2; will-change: transform; }
.hint { position: fixed; z-index: 300; font: 400 calc(17 * var(--su)) / 1 'CocoaHand', monospace; color: #222; opacity: .9; pointer-events: none; transition: opacity .5s; display: flex; align-items: center; gap: .5em; }
.hint.gone { opacity: 0; }
.hint-h { right: calc(28 * var(--su)); bottom: calc(22 * var(--su)); flex-direction: row; }
.hint-h .chev { width: calc(34 * var(--su)); height: calc(34 * var(--su)); animation: nudge-x 1.4s ease-in-out infinite; }
.hint-v { left: 50%; bottom: calc(14 * var(--su)); transform: translateX(-50%); z-index: 600; /* above the grid cards (Readymag z up to ~400), below the dim and the expanded card */ flex-direction: column; background: rgba(255,255,255,.75); padding: calc(6 * var(--su)) calc(12 * var(--su)); border-radius: 999px; font-size: calc(11 * var(--su)); }
.hint-v .chev { width: calc(16 * var(--su)); height: calc(16 * var(--su)); animation: nudge-y 1.4s ease-in-out infinite; }
@keyframes nudge-x { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(8px); } }
@keyframes nudge-y { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
.progress { position: fixed; left: 0; right: 0; bottom: 0; height: 3px; z-index: 300; background: rgba(34,34,34,.12); }
.progress > i { display: block; height: 100%; width: 0; background: #222; opacity: .6; transition: width .1s linear; }
.arrow { position: fixed; top: 50%; z-index: 310; width: calc(44 * var(--su)); height: calc(44 * var(--su)); margin-top: calc(-22 * var(--su)); border: 0; border-radius: 50%; background: rgba(255,255,255,.85); box-shadow: 0 1px 6px rgba(0,0,0,.15); display: grid; place-items: center; padding: 0; opacity: .9; transition: opacity .3s, transform .2s; }
.arrow:hover { transform: scale(1.06); }
.arrow[disabled] { opacity: 0; pointer-events: none; }
.arrow.left { left: calc(14 * var(--su)); } .arrow.right { right: calc(14 * var(--su)); }
.arrow svg { width: 55%; height: 55%; }

/* mobile galleries */
@media (max-width: 768px) {
  .row { position: static; inset: auto; transform: none !important; z-index: auto; will-change: auto; }
  .dim { z-index: 1000; }
  .gallery .card.big { z-index: 1001; }
  .gallery { position: relative; z-index: auto; display: grid; grid-template-columns: repeat(2, 1fr); gap: calc(10 * var(--su)); padding: calc(64 * var(--su)) calc(12 * var(--su)) calc(14 * var(--su)); }
  .gallery .card { position: relative !important; left: auto !important; top: auto !important; bottom: auto !important; width: auto !important; height: auto !important; aspect-ratio: 9 / 16; }
  .gallery .card video { transform: none; opacity: 1; border-radius: calc(4 * var(--su)); }
  .gallery .card.personal video { opacity: 1; }
  .gallery .card .title { inset: 6%; font-size: calc(13 * var(--su)); letter-spacing: .04em; }
  .gallery .card.big video { position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; height: 100dvh; object-fit: contain; z-index: 250; border-radius: 0; background: transparent; }
  .hint-h, .arrow, .progress { display: none; }
  body.expanded { overflow: hidden; }
  /* the grid defines the page height: nothing to scroll past the last clip */
  body.personal .page, body.client .page { height: auto !important; }
}
@media (min-width: 769px) { .hint-v { display: none; } .gallery { display: contents; } }

/* page heights */
body.landing .page { height: calc(100vh + var(--reveal, 1000) * var(--su)); }
@media (max-width: 768px) { body.landing .page { height: 100vh; height: 100dvh; } body.landing { overflow: hidden; } }
body.client .page { height: calc(100vh + var(--travel, 1700) * var(--su)); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
@media (prefers-reduced-motion: reduce) { .hint .chev, .arrow, .moon.hot img, .sun.hot img, .mail-btn:hover img { animation: none; } }

/* ---- landing: the banner lives under the clouds and only appears (and becomes clickable) once they have gone ---- */
body.landing .banner { opacity: 0; transition: opacity .7s ease .1s; }
body.landing.revealed .banner { opacity: 1; }
body.landing:not(.revealed) .banner .w { pointer-events: none; }

/* ---- "click/tap for sound" on a clip that is playing muted (the browser refused sound before any interaction) ---- */
.card .snd { position: absolute; left: 50%; bottom: 7%; transform: translateX(-50%); display: inline-flex; align-items: center; gap: .45em; background: rgba(34,34,34,.84); color: #fff; font: 400 calc(12 * var(--su)) / 1 'CocoaHand', 'Courier New', monospace; padding: calc(6 * var(--su)) calc(11 * var(--su)); border-radius: 999px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .25s; z-index: 5; }
.card .snd svg { width: 1.25em; height: 1.25em; flex: none; }
.card .snd b { font-weight: 400; }
.card.on.mute .snd, .card.big.mute .snd { opacity: 1; animation: snd-pulse 1.5s ease-in-out infinite; }
@keyframes snd-pulse { 0%, 100% { transform: translateX(-50%) scale(1); } 50% { transform: translateX(-50%) scale(1.07); } }
@media (max-width: 768px) { .gallery .card.big .snd { position: fixed; left: 50%; bottom: calc(28px + env(safe-area-inset-bottom)); z-index: 260; font-size: 14px; padding: 9px 14px; } }
@media (prefers-reduced-motion: reduce) { .card .snd { animation: none !important; } }
