/* Pupa — portfolio.
   The photographs are the only colour on this site. Everything the site
   itself draws is achromatic, so nothing competes with the images. The one
   risk taken here: no accent hue at all. Typography has to carry the page. */

:root {
  --ground:   #e8eae7;   /* pale sea glass, faintly green */
  --surface:  #f4f5f3;
  --ink:      #14181a;
  --ink-soft: #3b4244;
  --muted:    #6e7472;
  --line:     #cdd1cd;
  --line-2:   #b6bcb7;
  --hatch:    rgba(20, 24, 26, .06);
  --slot:     #dbdfda;   /* empty photo slot: a real step off the ground */
  --slot-2:   #cfd4ce;
  --scrim:    rgba(10, 13, 14, .58);
  --on-scrim: #f4f5f3;

  --f-display: "Bodoni Moda", "Didot", "Times New Roman", serif;
  --f-body:    "Karla", "Helvetica Neue", Arial, sans-serif;
  --f-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --bar-h: 5.4rem;
  --heart: #ff4a86;   /* the only saturated colour on the page */
  --gutter: clamp(1.15rem, 5vw, 4.5rem);
  --measure: 34rem;
  --max: 78rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:   #0b0e0f;
    --surface:  #14181a;
    --ink:      #edeeeb;
    --ink-soft: #c6cac6;
    --muted:    #8c9391;
    --line:     #232829;
    --line-2:   #333a3b;
    --hatch:    rgba(237, 238, 235, .05);
    --slot:     #1b2124;
    --slot-2:   #232a2d;
    --scrim:    rgba(5, 7, 8, .55);
    --on-scrim: #f4f5f3;
  }
}
:root[data-theme="dark"] {
  --ground:   #0b0e0f;
  --surface:  #14181a;
  --ink:      #edeeeb;
  --ink-soft: #c6cac6;
  --muted:    #8c9391;
  --line:     #232829;
  --line-2:   #333a3b;
  --hatch:    rgba(237, 238, 235, .05);
  --slot:     #1b2124;
  --slot-2:   #232a2d;
  --scrim:    rgba(5, 7, 8, .55);
  --on-scrim: #f4f5f3;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}
body.modal-open { overflow: hidden; }

p { margin: 0; }
img { display: block; max-width: 100%; }

a { color: inherit; text-decoration-color: var(--line-2); text-underline-offset: 4px; }
a:hover { text-decoration-color: currentColor; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── type roles ─────────────────────────────────────────── */

.wordmark {
  font-family: var(--f-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 0.86;
  margin: 0;
  font-size: clamp(4.5rem, 19vw, 13rem);
  /* the load reveal: the word rises out of its own clip */
  overflow: hidden;
}
.wordmark span { display: block; }
.wordmark--small { font-size: clamp(2.5rem, 8vw, 4rem); }

.eyebrow, .section-label, .place, .year, .frame::after, dt {
  font-family: var(--f-mono);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}

.section-label {
  color: var(--muted);
  margin: 0 0 1.5rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line);
}

.lead {
  font-family: var(--f-display);
  font-size: clamp(1.3rem, 1.1rem + 1vw, 1.85rem);
  line-height: 1.42;
  letter-spacing: -0.01em;
}

.fineprint { font-size: 0.82rem; color: var(--muted); }

/* ── frames: a photograph, or a designed slot waiting for one ── */

.frame {
  position: relative;
  overflow: hidden;
  /* An empty slot should read as a deliberate reservation, not as a hole:
     hatched, hairlined, and labelled with what belongs in it. */
  background:
    repeating-linear-gradient(135deg, transparent 0 11px, var(--hatch) 11px 12px),
    linear-gradient(148deg, var(--slot-2) 0%, var(--slot) 52%, var(--slot-2) 100%);
  box-shadow: inset 0 0 0 1px var(--line-2);
}
.frame::after {
  content: attr(data-slot);
  position: absolute;
  inset: auto 0 50% 0;
  transform: translateY(50%);
  text-align: center;
  color: var(--muted);
  font-size: 0.63rem;
  letter-spacing: 0.14em;
  padding: 0 1rem;
  word-break: break-word;
}
.frame img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .5s ease;
}
.frame[data-loaded] { box-shadow: none; background: none; }
.frame[data-loaded]::after { content: none; }
.frame[data-loaded] img { opacity: 1; }

.frame:not(.frame--hero)::before {
  content: "";
  position: absolute;
  inset: 0.75rem;
  border: 1px solid var(--hatch);
  clip-path: polygon(0 0, 1.4rem 0, 1.4rem 1px, 1px 1px, 1px 1.4rem, 0 1.4rem,
                     0 100%, 1.4rem 100%, 1.4rem calc(100% - 1px), 1px calc(100% - 1px), 1px calc(100% - 1.4rem), 0 calc(100% - 1.4rem),
                     100% 100%, 100% calc(100% - 1.4rem), calc(100% - 1px) calc(100% - 1.4rem), calc(100% - 1px) calc(100% - 1px), calc(100% - 1.4rem) calc(100% - 1px), calc(100% - 1.4rem) 100%,
                     100% 0, calc(100% - 1.4rem) 0, calc(100% - 1.4rem) 1px, calc(100% - 1px) 1px, calc(100% - 1px) 1.4rem, 100% 1.4rem);
}
.frame[data-loaded]::before { content: none; }

.frame--16x9 { aspect-ratio: 16 / 9; }
.frame--4x5  { aspect-ratio: 4 / 5; }
.frame--1x1  { aspect-ratio: 1 / 1; }

/* ── hero ───────────────────────────────────────────────── */

.hero { position: relative; min-height: 100svh; display: grid; }
.frame--hero { grid-area: 1 / 1; min-height: 100svh; box-shadow: none; }
.frame--hero::after { inset: auto 0 3rem 0; transform: none; }
.frame--hero::before {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, var(--scrim) 0%, transparent 52%);
}

.hero-type {
  grid-area: 1 / 1;
  z-index: 2;
  align-self: end;
  padding: var(--gutter);
  padding-bottom: clamp(2.5rem, 8vh, 5rem);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  color: var(--on-scrim);
  max-width: var(--max);
  width: 100%;
  margin: 0 auto;
  text-shadow: 0 1px 30px rgba(0, 0, 0, .35);
}
.hero-type .eyebrow { color: var(--on-scrim); opacity: .82; }
.hero-line {
  font-family: var(--f-display);
  font-style: italic;
  font-size: clamp(1.05rem, 0.95rem + 0.6vw, 1.4rem);
  line-height: 1.4;
  opacity: .92;
}

.scroll-cue {
  grid-area: 1 / 1;
  z-index: 2;
  align-self: end;
  justify-self: end;
  margin: 0 var(--gutter) clamp(2.5rem, 8vh, 5rem) 0;
  color: var(--on-scrim);
  font-size: 1.1rem;
  text-decoration: none;
  opacity: .7;
}
.scroll-cue:hover { opacity: 1; }

/* ── shared section rhythm ──────────────────────────────── */

main {
  display: flex;
  flex-direction: column;
  gap: clamp(4rem, 11vw, 8.5rem);
  padding: clamp(4rem, 11vw, 8rem) var(--gutter) 0;
  max-width: var(--max);
  margin: 0 auto;
}

.story { max-width: var(--measure); display: flex; flex-direction: column; gap: 1.15rem; }
.story p + p { color: var(--ink-soft); }

/* ── route ──────────────────────────────────────────────── */

.route { display: flex; flex-direction: column; gap: clamp(2rem, 5vw, 3.5rem); }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(0.75rem, 2vw, 1.75rem); }
@media (max-width: 44rem) { .pair { grid-template-columns: 1fr; gap: 2.25rem; } }

.shot { margin: 0; display: flex; flex-direction: column; gap: 0.8rem; }
figcaption { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.9rem; }
.place { color: var(--ink); }
.year  { color: var(--muted); }
.note {
  flex: 1 1 100%;
  font-size: 0.93rem;
  color: var(--muted);
  max-width: 34rem;
}
.shot--wide .note { max-width: 42rem; }

.route-now {
  font-family: var(--f-display);
  font-size: clamp(1.4rem, 1.1rem + 1.4vw, 2.2rem);
  letter-spacing: -0.01em;
  padding-top: 0.5rem;
}
.route-now .place, .route-now .year {
  font-family: inherit; font-size: inherit; letter-spacing: -0.01em; text-transform: none;
}
.route-now .year { color: var(--muted); }

/* ── work ───────────────────────────────────────────────── */

.work-lead { max-width: var(--measure); color: var(--ink-soft); margin-bottom: 2rem; }
.work-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(0.75rem, 2vw, 1.75rem);
}

/* ── facts ──────────────────────────────────────────────── */

.facts dl {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
}
.facts dl > div {
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
  padding-right: 1.5rem;
}
.facts dt { color: var(--muted); margin-bottom: 0.25rem; }
.facts dd { margin: 0; font-size: 0.98rem; }

/* ── exits: ruled rows, not cards ───────────────────────── */

.exit-list { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.exit {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0.2rem 1rem;
  padding: 1.35rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: var(--ink);
}
.exit-label {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 1.2rem + 1.6vw, 2.4rem);
  line-height: 1.1;
  letter-spacing: -0.015em;
  transition: transform .3s cubic-bezier(.2, .7, .3, 1);
}
.exit:hover .exit-label { transform: translateX(0.6rem); }
.exit-note { grid-column: 1; color: var(--muted); font-size: 0.9rem; }
.exit-badge {
  grid-row: 1; grid-column: 2;
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.exit-badge img { width: 44px; height: 22px; opacity: .8; }
.exit-heart { width: 1.15rem; height: 1.15rem; fill: var(--heart); flex: none; }
.links-note { margin-top: 1.1rem; font-size: 0.85rem; color: var(--muted); }

button { font: inherit; cursor: pointer; }
.btn {
  padding: 0.72rem 1.35rem;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--ground);
  font-family: var(--f-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 0;
}
.btn:hover { background: none; color: var(--ink); }
.btn-quiet {
  padding: 0.72rem 0.9rem;
  border: 1px solid transparent;
  background: none;
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.btn-quiet:hover { color: var(--ink); }

/* ── footer ─────────────────────────────────────────────── */

footer {
  max-width: var(--max);
  margin: clamp(5rem, 12vw, 9rem) auto 0;
  padding: 2rem var(--gutter) 3rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
footer .wordmark { overflow: visible; opacity: .28; }

/* ── age gate ───────────────────────────────────────────── */

.gate {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: 1.25rem;
  /* Solid rgba rather than backdrop-filter: the filter forces a compositing
     layer that some mobile browsers render as a black rectangle. */
  background: rgba(8, 10, 11, .78);
}
.gate[hidden] { display: none; }
.gate-panel {
  width: 100%; max-width: 23rem;
  background: var(--surface);
  border: 1px solid var(--line-2);
  padding: 1.6rem;
  display: flex; flex-direction: column; gap: 0.9rem;
}
.gate-panel h2 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: 1.45rem;
  line-height: 1.2;
  margin: 0;
}
.gate-panel p { font-size: 0.94rem; color: var(--ink-soft); }
.gate-actions { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.2rem; }
.gate-actions .btn, .gate-actions .btn-quiet { text-align: center; }

/* ── motion ─────────────────────────────────────────────── */

.wordmark span { animation: rise 1.05s cubic-bezier(.16, .84, .32, 1) both; }
@keyframes rise { from { transform: translateY(102%); } to { transform: none; } }

.fx-fade { opacity: 0; transform: translateY(18px); }
.fx-fade.in { opacity: 1; transform: none; transition: opacity .8s ease, transform .8s cubic-bezier(.16,.84,.32,1); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .fx-fade { opacity: 1; transform: none; }
}

/* ── legal documents ────────────────────────────────────── */

.doc {
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(3rem, 9vw, 6rem) var(--gutter) 5rem;
  display: flex;
  flex-direction: column;
  gap: 2.25rem;
}
.doc-head { display: flex; flex-direction: column; gap: 0.6rem; }
.doc-head h1 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: clamp(2.1rem, 1.6rem + 2.2vw, 3rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0;
}
.doc section { display: flex; flex-direction: column; gap: 0.7rem; }
.doc h2 {
  font-family: var(--f-mono);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  padding-bottom: 0.55rem;
  border-bottom: 1px solid var(--line);
}
.doc p { color: var(--ink-soft); }
.doc footer { margin-top: 1rem; padding: 1.5rem 0 0; max-width: none; }

/* ── ratios that match the photographs, rather than forcing them ── */

.frame--3x2 { aspect-ratio: 3 / 2; }
.frame--3x4 { aspect-ratio: 3 / 4; }

/* A single portrait carries the Serbia beat, so it gets its caption alongside
   instead of underneath — the one asymmetric block on the page. */
.feature {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
  gap: clamp(1.25rem, 4vw, 3.5rem);
  align-items: center;
}
.feature .shot { margin: 0; }
.feature-text { display: flex; flex-direction: column; gap: 0.85rem; }
.feature-label { display: flex; gap: 0.9rem; align-items: baseline; }
.feature-body {
  font-family: var(--f-display);
  font-size: clamp(1.1rem, 1rem + 0.7vw, 1.5rem);
  line-height: 1.42;
}
.feature-body + .feature-body { font-size: 1rem; font-family: var(--f-body); color: var(--muted); }

/* Mixed orientations in one row read as a mistake when aligned, and as
   composition when offset. */
.pair--stagger { align-items: start; }
.pair--stagger > :nth-child(2) { margin-top: clamp(1rem, 9%, 5rem); }

@media (max-width: 44rem) {
  .feature { grid-template-columns: 1fr; }
  .pair--stagger > :nth-child(2) { margin-top: 0; }
}


/* ── top banner ─────────────────────────────────────────────────────────
   A thin black rail, the first thing on the page and the first link in it.
   The heart is the single saturated pixel on an otherwise achromatic site,
   which is exactly why it reads from across the room. */

.bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  min-height: var(--bar-h);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  padding: 0.6rem 1rem;
  background: #000;
  color: #fff;
  text-decoration: none;
  font-family: var(--f-mono);
  font-size: 0.82rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  line-height: 1.35;
}
.bar-text { text-align: center; }
.bar-heart {
  width: 1.25rem; height: 1.25rem;
  flex: none;
  fill: var(--heart);
  transition: transform .25s cubic-bezier(.2,.7,.3,1);
}
.bar:hover .bar-heart, .bar:focus-visible .bar-heart { transform: scale(1.18); }
.bar:focus-visible { outline: 2px solid var(--heart); outline-offset: -3px; }

body { padding-top: var(--bar-h); }
.hero, .frame--hero { min-height: calc(100svh - var(--bar-h)); }

.gate-mark { width: 52px; height: 26px; opacity: .8; margin-bottom: 0.1rem; }

@media (max-width: 26rem) {
  .bar { font-size: 0.72rem; letter-spacing: 0.07em; }
}


/* ── reveal control ─────────────────────────────────────────────────────
   The link rows do not exist until this is tapped. Styled as a wide, plain
   row so it reads as "open this", not as a loud call-to-action. */
.reveal {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.35rem 0;
  border: 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: none;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--f-display);
  font-size: clamp(1.35rem, 1.1rem + 1.4vw, 2.1rem);
  letter-spacing: -0.015em;
  text-align: left;
}
.reveal:hover .reveal-text { transform: translateX(0.4rem); }
.reveal-text { transition: transform .3s cubic-bezier(.2,.7,.3,1); }
.reveal-heart { width: 1.5rem; height: 1.5rem; fill: var(--heart); flex: none; }
.reveal:focus-visible { outline: 2px solid var(--heart); outline-offset: 3px; }


/* ── Safari escape splash (iOS in-app browsers only) ────────────────────── */
.safari-gate {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem calc(1.5rem + env(safe-area-inset-right)) 1.5rem calc(1.5rem + env(safe-area-inset-left));
  background: var(--ground);
}
.safari-gate[hidden] { display: none; }
.safari-gate-card {
  max-width: 22rem; width: 100%;
  display: flex; flex-direction: column; gap: 0.9rem;
  text-align: center;
}
.safari-gate h2 {
  font-family: var(--f-display); font-weight: 400;
  font-size: clamp(2rem, 1.5rem + 2vw, 2.7rem);
  line-height: 1.05; letter-spacing: -0.02em; margin: 0;
}
.safari-gate .sg-body { color: var(--muted); font-size: 0.98rem; }
.safari-gate .sg-hint { color: var(--muted); font-size: 0.8rem; opacity: .8; margin-top: -0.4rem; }
.safari-gate .sg-btn { padding: 1rem; font-size: 0.8rem; margin-top: 0.3rem; }
.safari-gate .btn-quiet { align-self: center; }
.sg-manual {
  color: var(--muted); font-size: 0.85rem;
  margin-top: 0.6rem; padding-top: 0.9rem; border-top: 1px solid var(--line);
}
.sg-manual strong { color: var(--ink); }


/* spinner shown while the host app is handing the page to the system browser */
.sg-spin {
  width: 42px; height: 42px; border-radius: 50%;
  border: 3px solid var(--line-2); border-top-color: var(--ink);
  margin: 0 auto 0.4rem;
  animation: sg-spin .85s linear infinite;
}
@keyframes sg-spin { to { transform: rotate(360deg); } }
#sg-manual-card[hidden], #sg-spinner[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .sg-spin { animation: none; } }


/* ── banner call-to-action ──────────────────────────────────────────────
   CLICK HERE is the loudest thing on the page: heavy, white, larger than the
   line under it, flanked by arrows that blink alternately so the eye is
   pulled inward to the middle. */
.bar-inner {
  display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
  min-width: 0;
}
.bar-cta {
  font-family: var(--f-body);
  font-weight: 800;
  font-size: 1.35rem;
  line-height: 1.05;
  letter-spacing: 0.02em;
  color: #fff;
  text-transform: uppercase;
  white-space: nowrap;
}
.bar .bar-text {
  font-size: 0.66rem;
  letter-spacing: 0.09em;
  color: rgba(255, 255, 255, .68);
  text-align: center;
  white-space: normal;
}
.bar-arrow {
  flex: none;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--heart);
  animation: bar-blink 1s steps(1, end) infinite;
}
.bar-arrow--r { animation-delay: .5s; }
@keyframes bar-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: .18; } }

@media (max-width: 26rem) {
  .bar { gap: 0.5rem; padding: 0.55rem 0.7rem; }
  .bar-cta { font-size: 1.15rem; }
  .bar .bar-text { font-size: 0.6rem; letter-spacing: 0.05em; }
  .bar-arrow { font-size: 1.05rem; }
}
@media (prefers-reduced-motion: reduce) {
  .bar-arrow { animation: none; opacity: 1; }
}


/* arrows hug the call to action so the pair reads as one centred unit */
.bar-cta-row { display: flex; align-items: center; justify-content: center; gap: 0.6rem; }
.bar-sub { display: flex; align-items: center; justify-content: center; gap: 0.45rem; min-width: 0; }
.bar-sub .bar-heart { width: 0.95rem; height: 0.95rem; }
@media (max-width: 26rem) {
  .bar-cta-row { gap: 0.45rem; }
  .bar-sub .bar-heart { width: 0.8rem; height: 0.8rem; }
}
