/* Jinky by Patrick Broderick, Rotodesign. Freeware; its licence travels with
   it in fonts/Rotodesign License.txt */
@font-face {
  font-family: "Jinky";
  src: url("../assets/photos/fonts/JINKY.ttf") format("truetype");
  font-display: swap;
  /* everything except the comma (2C) and apostrophe (27), which Jinky draws
     as filled blobs; those two fall through to Caveat */
  unicode-range: U+0020-0026, U+0028-002B, U+002D-007E, U+00A0-024F, U+2190-21FF;
}

:root {
  --bg: #111110;
  --ink: #d8d4ca;
  --ink-dim: #7a756d;
  --paper: #dedcd6;
  --paper-edge: #c6c3bb;
  --paper-ink: #3a3631;
  /* shows while a photo loads; close to the page so loading stays quiet */
  --photo-wash: #1d1c19;

  --title: "Jinky", "Caveat", cursive;
  /* all the lettering on the canvas; only the photo captions use --pen */
  --hand: "Jinky", "Caveat", cursive;
  --pen: "Reenie Beanie", "Caveat", cursive;

  --gutter: clamp(16px, 4vw, 56px);
  /* the collage's 6% margin, so header and footer line up with the prints */
  --inset: calc(var(--gutter) + .06 * (100vw - 2 * var(--gutter)));
  --ease: cubic-bezier(.32, .72, 0, 1);
}

* { box-sizing: border-box; }

html {
  background: var(--bg);
  /* reserve the scrollbar space so the collage width never jumps */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ---------- handwriting ---------- */

.hand {
  font-family: var(--hand);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: .02em;
  margin: 0;
}
.hand--xl { font-size: clamp(34px, 4.2vw, 52px); line-height: 1.02; text-transform: uppercase; }
.hand--md { font-size: clamp(22px, 2vw, 28px); }
.hand--sm { font-size: 19px; }
.dim { color: var(--ink-dim); }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--ink); }

/* ---------- intro ---------- */

.intro {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 32px;
  padding: clamp(48px, 7vw, 96px) var(--inset) clamp(80px, 10vw, 160px);
}

.intro h1 {
  margin: 0;
  font-family: var(--title);
  font-weight: 400;
  font-size: clamp(44px, 7vw, 112px);
  line-height: .74;
  color: var(--ink);
}
.intro h1 .line { display: block; white-space: nowrap; }

/* the scenery icon sits inline after "lens", sized to the lettering */
.title-icon {
  display: inline-block;
  /* a touch shorter than the capitals */
  width: .52em;
  height: auto;
  margin-left: .2em;
  vertical-align: .02em;
  transform: rotate(-9deg);
  fill: none;
  stroke: var(--ink);
  stroke-width: .7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the block stays on the right; its lines read left-aligned */
.intro-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}

.subtitle {
  max-width: 32ch;
  text-wrap: balance;
  margin: 0;
  /* the one running sentence on the page, so it gets the more readable hand */
  font-family: "Caveat", cursive;
  font-weight: 500;
  font-size: clamp(21px, 1.8vw, 26px);
  line-height: 1.25;
  color: #b3aea3;
}

.tidy {
  margin-top: 14px;
  background: none;
  border: 0;
  padding: 4px 0;
  font-family: var(--hand);
  font-size: 28px;
  color: var(--ink-dim);
  cursor: pointer;
}
.tidy:hover { color: var(--ink); }
.tidy[hidden] { display: none; }

/* ---------- ways out ---------- */

/* shown only when this page is the portfolio's Sidekick sheet */
.sheet-close {
  display: none;
  position: fixed;
  top: clamp(14px, 2vw, 24px);
  right: var(--gutter);
  z-index: 3000;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 8px;
  border: 0;
  border-radius: 999px;
  background: rgba(17, 17, 16, .72);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  font-family: var(--hand);
  font-size: 26px;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
}
.is-embedded .sheet-close { display: inline-flex; }
.sheet-close svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  transition: transform .3s var(--ease);
}
.sheet-close:hover svg { transform: rotate(90deg); }
.sheet-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* shown only when the page is opened on its own */
.page-back {
  position: absolute;
  top: clamp(16px, 2.4vw, 32px);
  left: var(--inset);
  font-family: var(--hand);
  font-size: 24px;
  color: var(--ink-dim);
}
.page-back { display: inline-flex; align-items: center; gap: 8px; }
.page-back svg {
  width: 26px;
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .3s var(--ease);
}
.page-back:hover { color: var(--ink); }
.page-back:hover svg { transform: translateX(-4px); }
.is-embedded .page-back { display: none; }

/* ---------- canvas ---------- */

.canvas {
  position: relative;
  z-index: 1;
  margin: 0 var(--gutter);
  /* height is set by app.js once the layout is known */
  min-height: 60vh;
}

/* ---------- doodles and words between the prints ---------- */

.scribble {
  position: absolute;
  z-index: 0;
  margin: 0;
  pointer-events: none;
  user-select: none;
}
.scribble--icon {
  width: clamp(48px, 5vw, 76px);
  height: auto;
  fill: none;
  stroke: var(--ink);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .8;
}
/* ---------- the doodles move a little ---------- */
/* motion lives on the inner group; transform-box makes origins relative to
   the drawing itself, so "center" means the middle of the icon */

.scribble--icon .motion,
.scribble--icon .needle,
.scribble--icon .rays,
.scribble--icon .trail {
  transform-box: view-box;
  transform-origin: 50px 50px;
}

/* paper plane: a slow looping glide, with the trail drifting behind it */
.is-fly .motion { animation: fly 7s ease-in-out infinite; }
.is-fly .trail  { animation: trail 7s ease-in-out infinite; }
@keyframes fly {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  25%      { transform: translate(7px, -6px) rotate(-5deg); }
  50%      { transform: translate(14px, -2px) rotate(2deg); }
  75%      { transform: translate(6px, 4px) rotate(-2deg); }
}
@keyframes trail {
  0%, 100% { opacity: .9; transform: translate(0, 0); }
  50%      { opacity: .35; transform: translate(-6px, 3px); }
}

/* mountains, the arrow: drawn stroke by stroke, held, then drawn again */
.is-draw path {
  stroke-dasharray: 1;
  animation: draw 8s ease-in-out infinite;
  animation-delay: calc(var(--i) * .45s);
}
@keyframes draw {
  0%        { stroke-dashoffset: 1; opacity: 1; }
  30%       { stroke-dashoffset: 0; }
  86%       { stroke-dashoffset: 0; opacity: 1; }
  96%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* compass: the needle swings, settles, then twitches again */
.is-compass .needle { animation: needle 6s ease-out infinite; }
.is-compass .motion { animation: jitter 6s linear infinite; }
@keyframes needle {
  0%   { transform: rotate(0deg); }
  8%   { transform: rotate(-38deg); }
  18%  { transform: rotate(24deg); }
  28%  { transform: rotate(-14deg); }
  38%  { transform: rotate(8deg); }
  48%  { transform: rotate(-3deg); }
  58%, 100% { transform: rotate(0deg); }
}
@keyframes jitter {
  0%, 30%, 100% { transform: translate(0, 0); }
  4%  { transform: translate(-1px, .5px); }
  8%  { transform: translate(1px, -.5px); }
  12% { transform: translate(-.5px, 0); }
}

/* the quieter ones */
.is-bob .motion    { animation: bob 3.2s ease-in-out infinite; }
.is-sway .motion   { transform-origin: 50px 92px; animation: sway 4.5s ease-in-out infinite; }
.is-shine .rays    { animation: spin 24s linear infinite; }
.is-hop .motion    { transform-origin: 50px 88px; animation: hop 5s ease-in-out infinite; }
.is-wiggle .motion { animation: wiggle 6s ease-in-out infinite; }
@keyframes bob    { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes sway   { 0%, 100% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } }
@keyframes spin   { to { transform: rotate(360deg); } }
@keyframes hop {
  0%, 70%, 100% { transform: translateY(0) scaleY(1); }
  76% { transform: translateY(0) scaleY(.94); }
  84% { transform: translateY(-7px) scaleY(1.02); }
  92% { transform: translateY(0) scaleY(.97); }
}
@keyframes wiggle {
  0%, 80%, 100% { transform: rotate(0deg); }
  84% { transform: rotate(-4deg); }
  88% { transform: rotate(3deg); }
  92% { transform: rotate(-2deg); }
}

@media (prefers-reduced-motion: reduce) {
  .scribble--icon *,
  .scribble--icon .motion { animation: none !important; }
  .is-draw path { stroke-dashoffset: 0; }
}

.scribble--word {
  font-family: var(--hand);
  font-weight: 400;
  font-size: clamp(26px, 2.4vw, 36px);
  line-height: .95;
  color: #c4bfb4;
  white-space: pre;
  text-align: center;
}

/* ---------- polaroid ---------- */

.polaroid {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  padding: 9px 9px 0;
  background: var(--paper);
  border-radius: 2px;
  box-shadow:
    inset 0 0 0 1px var(--paper-edge),
    0 1px 2px rgba(0,0,0,.35),
    0 14px 30px -12px rgba(0,0,0,.6);
  cursor: zoom-in;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  will-change: transform;
  transition: box-shadow .25s var(--ease);
}
/* `will-change` for the length of the move only: the print's z-index is
   raised on the same frame the scale starts, and without a stable compositor
   layer that forces a re-rasterise part-way through, which shows as a flicker.
   Dropped again with the class so idle prints hold no extra layers. */
.polaroid.is-settling {
  transition: transform .5s var(--ease), box-shadow .35s var(--ease);
  will-change: transform;
}

/* tapped: lifted and scaled up in place */
.polaroid.is-zoomed {
  cursor: zoom-out;
  box-shadow:
    inset 0 0 0 1px var(--paper-edge),
    0 4px 8px rgba(0,0,0,.35),
    0 40px 70px -20px rgba(0,0,0,.85);
}
.polaroid:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.polaroid.is-lifted {
  cursor: grabbing;
  box-shadow:
    inset 0 0 0 1px var(--paper-edge),
    0 2px 4px rgba(0,0,0,.35),
    0 34px 60px -18px rgba(0,0,0,.8);
}

.polaroid .photo {
  display: block;
  position: relative;
  overflow: hidden;
  background: var(--photo-wash);
}

.polaroid img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  -webkit-user-drag: none;
}

/* soft inner vignette so the print feels like a print */
.polaroid .photo::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 18px rgba(0,0,0,.25);
  pointer-events: none;
}

.caption {
  display: block;
  font-family: var(--pen);
  font-size: 22px;
  line-height: 1;
  color: var(--paper-ink);
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 9px 4px 11px;
  min-height: 42px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- outro ---------- */
/* mirrors the header: a closing note in the title face on the left,
   the way back up on the right, sharing a bottom line */

.outro {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 24px;
  padding: clamp(64px, 9vw, 140px) var(--inset) clamp(48px, 6vw, 88px);
}

.outro-note {
  margin: 0;
  font-family: var(--title);
  font-size: clamp(34px, 4.4vw, 64px);
  line-height: .8;
  text-transform: uppercase;
  color: var(--ink);
}

.to-top {
  flex: none;
  font-family: var(--hand);
  font-size: clamp(26px, 2vw, 32px);
  color: var(--ink-dim);
}
.to-top:hover { color: var(--ink); }

/* hand-drawn arrow in the same pencil line as the doodles */
.to-top-arrow {
  display: inline-block;
  width: .5em;
  height: auto;
  margin-left: .3em;
  vertical-align: -.08em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transform: rotate(4deg);
  transition: transform .3s var(--ease);
}
.to-top-arrow .ghost { stroke-width: .8; opacity: .5; }
.to-top:hover .to-top-arrow { transform: rotate(4deg) translateY(-4px); }

/* ---------- small screens ---------- */

@media (max-width: 760px) {
  :root { --inset: var(--gutter); }
  .outro { flex-direction: column; align-items: flex-start; gap: 28px; }
  .to-top { align-self: flex-end; }
  .intro { flex-direction: column; align-items: flex-start; gap: 20px; }
  .intro-meta { align-items: flex-start; text-align: left; }
}

@media (max-width: 640px) {
  .caption { font-size: 17px; min-height: 32px; padding: 7px 2px 8px; }
  .polaroid { padding: 6px 6px 0; }
}

/* on touch, a finger on a print should scroll the page, not grab the print */
@media (pointer: coarse) {
  .polaroid { touch-action: pan-y; cursor: pointer; }
}

@media (prefers-reduced-motion: reduce) {
  .polaroid, .polaroid.is-settling { transition: none; }
}
