@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrument-serif.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrument-serif-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

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

:root {
  color-scheme: dark;
  --bg: #050b24;
  --card: rgba(11, 22, 62, .62);
  --ink: #eef1fb;
  --muted: #9aa6c9;
  --line: rgba(255, 255, 255, .1);
  --gold: #e8c987;
  --gold-deep: #b98a3e;
  --blue: #5b82ff;
  --portrait-bg: #0e2263;
  --serif: "Instrument Serif", "Iowan Old Style", Palatino, Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ease: cubic-bezier(.2, .8, .2, 1);
  /* set by main.js for the tilt and glare */
  --rx: 0deg;
  --ry: 0deg;
  --gx: 50%;
  --gy: 50%;
}

* { box-sizing: border-box; }

html, body { margin: 0; }

body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 32px 16px;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; }

/* Background: slow drifting light */
.aurora {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.blob {
  position: absolute;
  width: 70vmax;
  height: 70vmax;
  border-radius: 50%;
  opacity: .55;
}
.b1 {
  top: -30vmax;
  left: -20vmax;
  background: radial-gradient(closest-side, rgba(53, 92, 255, .55), transparent);
  animation: drift1 26s ease-in-out infinite alternate;
}
.b2 {
  bottom: -35vmax;
  right: -25vmax;
  background: radial-gradient(closest-side, rgba(28, 54, 160, .7), transparent);
  animation: drift2 32s ease-in-out infinite alternate;
}
.b3 {
  top: 30%;
  left: 45%;
  width: 45vmax;
  height: 45vmax;
  background: radial-gradient(closest-side, rgba(232, 201, 135, .16), transparent);
  animation: drift3 22s ease-in-out infinite alternate;
}
@keyframes drift1 { to { transform: translate(18vmax, 12vmax) scale(1.1); } }
@keyframes drift2 { to { transform: translate(-16vmax, -10vmax) scale(1.15); } }
@keyframes drift3 { to { transform: translate(-30vmax, -20vmax) scale(.85); } }

/* Fine dot grid, fading out toward the edges and drifting slowly. */
.grid {
  position: absolute;
  inset: -40px;
  background-image: radial-gradient(rgba(190, 205, 255, .16) 1px, transparent 1.4px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse 70% 65% at 50% 45%, #000 20%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 65% at 50% 45%, #000 20%, transparent 100%);
  animation: pan 40s linear infinite, fadein 2s .3s ease both;
}
/* Same grid in gold, visible only around the pointer (position set by main.js). */
.grid-hot {
  background-image: radial-gradient(rgba(232, 201, 135, .9) 1.2px, transparent 1.6px);
  -webkit-mask-image: radial-gradient(circle 190px at var(--mx, -999px) var(--my, -999px), #000, transparent);
  mask-image: radial-gradient(circle 190px at var(--mx, -999px) var(--my, -999px), #000, transparent);
  opacity: 0;
  transition: opacity .6s;
  animation: pan 40s linear infinite;
}
.grid-hot.on { opacity: 1; }
@keyframes pan { to { background-position: 26px 26px; } }
@keyframes fadein { from { opacity: 0; } }

/* Card with a slowly rotating gradient edge */
.stage {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 860px;
  perspective: 1400px;
}
.frame {
  position: relative;
  border-radius: 22px;
  transform: rotateX(var(--rx)) rotateY(var(--ry));
  transform-style: preserve-3d;
  transition: transform .5s var(--ease);
  animation: enter 1.6s cubic-bezier(.16, .9, .25, 1) backwards;
  will-change: transform;
}
/* Rotating edge on each face, so it turns over with the card. Only the 1px ring
   shows; a filled background would tint the card. */
.face::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  padding: 1px;
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(from var(--angle),
    rgba(255, 255, 255, .08) 0deg,
    var(--gold) 60deg,
    rgba(255, 255, 255, .08) 140deg,
    var(--blue) 230deg,
    rgba(255, 255, 255, .08) 320deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: spin 10s linear infinite;
}
.frame.tilting { transition: transform .12s linear; }
@keyframes spin { to { --angle: 360deg; } }
/* The card swings in from the side, like being laid on the table. */
@keyframes enter {
  0% { opacity: 0; transform: translateY(60px) rotateX(24deg) rotateY(-34deg) rotateZ(4deg) scale(.86); }
  35% { opacity: 1; }
  100% { opacity: 1; transform: none; }
}

/* Two faces on a flipper; .flipped turns the card over. */
.flipper {
  position: relative;
  transform-style: preserve-3d;
  transition: transform .9s cubic-bezier(.65, 0, .35, 1);
}
.frame.flipped .flipper { transform: rotateY(180deg); }

/* Which face is shown is decided by main.js from the measured angle (.show-back):
   WebKit sometimes draws the turning card flat and paints both faces on top of
   each other, so the browser's own backface hiding is not used at all.
   At rest the face turned away is switched off completely, or WebKit lets
   parts of it show through. While the card turns (.turning) both faces are on
   and the one turned away is only 99 % transparent: Safari then paints the
   arriving face in advance instead of tile by tile once it shows, which left
   part of the text column blank for a moment. */
.back,
.frame.show-back .front { visibility: hidden; opacity: .01; pointer-events: none; }
.frame.show-back .back { visibility: visible; opacity: 1; pointer-events: auto; }
.frame.turning .front,
.frame.turning .back { visibility: visible; }

.face {
  position: relative;
  border-radius: 21px;
  overflow: hidden;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .6);
  background:
    radial-gradient(120% 90% at 100% 0%, rgba(60, 90, 200, .22), transparent 60%),
    linear-gradient(160deg, #0d1c52 0%, #091440 55%, #070f33 100%);
}
/* Each face sits 1px off the card's middle plane. In one shared plane Safari
   sorted them wrongly and hid the half of the arriving face that lay behind
   the turning axis. */
.front {
  display: grid;
  grid-template-columns: 340px 1fr;
  transform: translateZ(1px);
}
.back {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 340px 1fr;
  transform: rotateY(180deg) translateZ(1px);
}


.glare {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(500px circle at var(--gx) var(--gy), rgba(255, 255, 255, .09), transparent 60%);
  opacity: 0;
  transition: opacity .4s;
}
.frame.tilting .glare { opacity: 1; }

/* Portrait */
.portrait {
  position: relative;
  background: var(--portrait-bg);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, #000 70%, transparent);
  mask-image: linear-gradient(to right, #000 70%, transparent);
  animation: unveil 1.3s .15s var(--ease) both;
}
.portrait img,
.portrait video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  animation: settle 1.8s .15s var(--ease) both;
}
@keyframes unveil {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}
@keyframes settle {
  from { transform: scale(1.12); }
  to { transform: scale(1); }
}
.monogram {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: 72px;
  color: var(--gold);
}
.portrait.no-photo img, .portrait.no-photo video { display: none; }
.portrait.no-photo .monogram { display: flex; }

/* Text side */
.content {
  position: relative;
  z-index: 2;
  padding: 48px 48px 40px 28px;
  display: flex;
  flex-direction: column;
}

.rise { animation: rise .9s var(--ease) both; }
.d1 { animation-delay: .35s; }
.d2 { animation-delay: .45s; }
.d3 { animation-delay: .6s; }
.d4 { animation-delay: .7s; }
.d5 { animation-delay: .82s; }
.d6 { animation-delay: .94s; }
.d7 { animation-delay: 1.04s; }
.d8 { animation-delay: 1.3s; }
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); filter: blur(4px); }
  to { opacity: 1; transform: none; filter: none; }
}

.eyebrow {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.eyebrow svg { width: 13px; height: 13px; fill: var(--gold); }

h1 {
  margin: 10px 0 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(48px, 7vw, 76px);
  line-height: .95;
  letter-spacing: -.01em;
}
h1 em {
  font-style: italic;
  padding-right: .06em;
  background: linear-gradient(100deg, var(--gold-deep) 0%, var(--gold) 35%, #fff4d6 50%, var(--gold) 65%, var(--gold-deep) 100%);
  background-size: 250% 100%;
  background-position: 0% 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shine 2.4s 1.1s var(--ease) backwards;
}
@keyframes shine {
  from { background-position: 100% 0; }
  to { background-position: 0% 0; }
}

.roles {
  list-style: none;
  margin: 32px 0 0;
  padding: 0;
  display: grid;
  gap: 16px;
}
.roles li { display: flex; flex-direction: column; gap: 2px; }
.role {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.roles a {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -.01em;
  text-decoration: none;
  background: linear-gradient(var(--gold), var(--gold)) left bottom / 0 1px no-repeat;
  padding-bottom: 2px;
  transition: background-size .45s var(--ease), color .3s;
}
.roles a svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: var(--gold);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .35s var(--ease);
}
.roles a:hover { background-size: 100% 1px; color: #fff; }
.roles a:hover svg { transform: translate(3px, -3px); }

.personal {
  margin: 26px 0 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  line-height: 1.3;
  color: #c9d1ea;
}

.interests { margin-top: 24px; }
.interests ul {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.interests li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px 6px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .04);
  font-size: 14px;
  font-weight: 500;
  transition: border-color .3s, background .3s;
}
.interests li:hover { border-color: rgba(232, 201, 135, .5); background: rgba(232, 201, 135, .06); }
.interests svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: var(--gold);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Contact and profiles */
.actions {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

button {
  font: inherit;
  cursor: pointer;
}
.reveal {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 20px 12px 22px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--gold), var(--gold-deep));
  color: #1a1407;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .01em;
  box-shadow: 0 8px 24px -8px rgba(232, 201, 135, .55);
  transition: transform .3s var(--ease), box-shadow .3s;
}
.reveal::after {
  content: "";
  position: absolute;
  inset: 0;
  /* moves the background rather than the element: no extra layer in Safari */
  background: linear-gradient(110deg, transparent 40%, rgba(255, 255, 255, .55) 50%, transparent 60%) no-repeat;
  background-size: 300% 100%;
  background-position: 100% 0;
  animation: sweep 5s 2.2s ease-in-out infinite;
}
@keyframes sweep {
  0%, 70% { background-position: 100% 0; }
  100% { background-position: 0% 0; }
}
.reveal:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -10px rgba(232, 201, 135, .7); }
.reveal svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .6s var(--ease);
}
.reveal:hover svg { transform: rotate(180deg); }

/* Back of the card */
.crest {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  border-right: 1px solid var(--line);
  background:
    repeating-linear-gradient(45deg, rgba(232, 201, 135, .035) 0 1px, transparent 1px 12px),
    radial-gradient(closest-side, rgba(232, 201, 135, .12), transparent);
}
.crest-mono {
  font-family: var(--serif);
  font-size: 150px;
  line-height: .8;
  letter-spacing: -.04em;
  background: linear-gradient(160deg, #fff4d6 0%, var(--gold) 35%, var(--gold-deep) 70%, #7d5a22 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* no drop-shadow filter: WebKit draws filtered elements on their own layer
     and lets them show through the transparent face */
}
.crest-line { width: 48px; height: 1px; background: var(--gold); opacity: .6; }
.crest-sub {
  font-size: 11px;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gold);
  opacity: .8;
}

.back-body {
  position: relative;
  padding: 48px 48px 40px 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.details {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: 14px 20px;
  margin: 18px 0 0;
}
.details dt {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.details dd {
  margin: 0;
  font-family: var(--serif);
  font-size: 28px;
  line-height: 1.1;
}
.details a { text-decoration: none; transition: color .3s; }
.details a:hover { color: var(--gold); }

.back-actions {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.save,
.flip-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  transition: transform .3s var(--ease), border-color .3s, color .3s;
}
.save {
  border: 0;
  background: linear-gradient(135deg, var(--gold), var(--gold-deep));
  color: #1a1407;
}
.flip-back {
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .04);
  color: var(--ink);
}
.flip-back:hover { border-color: var(--gold); color: var(--gold); }
.save svg, .flip-back svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.qr {
  position: absolute;
  right: 40px;
  bottom: 36px;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.qr img {
  display: block;
  width: 84px;
  height: 84px;
  padding: 8px;
  border-radius: 10px;
  background: #f3e7c9;
}
.qr figcaption { font-size: 10px; letter-spacing: .08em; color: var(--muted); }

.hint { margin: 0; font-size: 14px; color: var(--muted); }

.social { display: flex; gap: 10px; }
.social a {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .04);
  color: var(--muted);
  transition: transform .3s var(--ease), color .3s, border-color .3s, background .3s;
}
.social a:hover {
  transform: translateY(-3px);
  color: var(--bg);
  background: var(--ink);
  border-color: var(--ink);
}
.social svg { width: 16px; height: 16px; fill: currentColor; }

button:focus-visible, a:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.foot {
  position: relative;
  z-index: 1;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}

/* Phone: portrait on top, fading into the text */
@media (max-width: 720px) {
  .front { grid-template-columns: 1fr; }
  .back { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
  .crest { padding: 48px 0 32px; border-right: 0; border-bottom: 1px solid var(--line); }
  .crest-mono { font-size: 110px; }
  .back-body { padding: 28px 24px 32px; }
  .details { grid-template-columns: 1fr; gap: 2px; }
  .details dd { font-size: 24px; margin-bottom: 12px; }
  .qr { position: static; margin-top: 28px; align-self: flex-start; }
  .stage { max-width: 460px; }
  .portrait {
    height: 300px;
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent);
    mask-image: linear-gradient(to bottom, #000 62%, transparent);
  }
  .portrait img, .portrait video { object-position: center 28%; }
  @keyframes unveil {
    from { clip-path: inset(0 0 100% 0); }
    to { clip-path: inset(0 0 0 0); }
  }
  .content { padding: 4px 24px 28px; margin-top: -36px; }
  .personal { font-size: 20px; }
  .b3 { opacity: .2; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  .frame { transform: none; }
  /* no 3D turn: just swap the faces */
  .flipper { transform: none !important; }
  .front, .back { transform: none; }
}

.sep {
  margin: 0 .35em;
  color: var(--gold);
  font-style: normal;
  opacity: .7;
}

/* Once the card has turned over, drop the 3D rotation and show the back flat:
   Safari misses clicks on elements of a rotated backface. */
.frame.flipped.settled .flipper { transform: none; transition: none; }
.frame.flipped.settled .back { transform: none; }
.flipper.no-anim { transition: none; }

/* Easter egg: double-click spins the card once around. */
.frame.spinning .flipper { animation: spin-front 1.3s cubic-bezier(.65, 0, .35, 1); }
.frame.spinning.flipped .flipper { animation-name: spin-back; }
@keyframes spin-front { from { transform: rotateY(0); } to { transform: rotateY(360deg); } }
@keyframes spin-back { from { transform: rotateY(180deg); } to { transform: rotateY(540deg); } }

/* Easter egg: local time in Bozen next to the place. */
.place { cursor: default; }
.clock {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  vertical-align: bottom;
  color: var(--gold);
  opacity: 0;
  transition: max-width .5s var(--ease), opacity .4s;
}
.place:hover .clock { max-width: 16em; opacity: 1; }

/* Easter egg: "Vater" × 3. */
.vater { cursor: default; white-space: nowrap; }
.times {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  vertical-align: bottom;
  margin-left: 0;
  color: var(--gold);
  opacity: 0;
  transition: max-width .45s var(--ease), margin-left .45s var(--ease), opacity .35s;
}
.vater:hover .times { max-width: 3em; margin-left: .3em; opacity: 1; }

/* Easter egg: hovering the portrait (tap on touch) plays a short smile. The
   clip starts on exactly the still image, so it can fade in quickly. */
.portrait .smile {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  transition: opacity .5s ease;
}
.portrait.smiling .smile { opacity: 1; transition: opacity .12s ease; }

/* Intro animations are dropped once finished (.anim-done, set by main.js); their
   end state equals the plain styles. Safari otherwise keeps them as separate
   layers and repaints them late after the card turns back to the front. */
.rise.anim-done,
.portrait.anim-done,
.portrait img.anim-done,
.portrait video.anim-done { animation: none; }
