/* ============================================================
   Antonella Autuori — portfolio
   Fixed gray header + generative typewriter bio · two-column CV
   Arial Narrow Bold everywhere
   ============================================================ */

/* ---------- FONT ---------- */
@font-face {
  font-family: "Arial Narrow";
  src: url("font/Arial Narrow Bold.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- TOKENS ---------- */
:root {
  --bg:   #ffffff;
  --gray: #A2A2A2;   /* fixed headers + bio */
  --ink:  #ff0000;   /* CV columns + bio */

  --fs: 30px;        /* bio, footer */
  --fs-topbar: 30px; /* top bar: name + email — separate from the bio, tweak freely */
  --fs-cv: 24px;      /* CV columns — a bit smaller than the bio/header */

  --edge: 10px;      /* outer margin all around */
  --gap:  32px;      /* space between the columns */

  --fade: 0.32rem;   /* height of the white opacity mask (small, crisp edge) */

  --topH: 0px;       /* measured by JS: height of fixed top zone */
  --botH: 0px;       /* measured by JS: height of fixed bottom zone */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Arial Narrow", Arial, "Helvetica Neue", sans-serif;
  font-weight: 700;
  font-size: var(--fs);
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;   /* the page itself doesn't scroll; each column does */
}

a { color: inherit; text-decoration: none; }

/* mail + footer social links ARE the whole clickable line, so they blur
   themselves on hover (desktop) / tap (mobile, via :active) */
.top .mail, .bottom .bar a { transition: filter 0.15s ease; }
.top .mail:hover, .top .mail:active,
.bottom .bar a:hover, .bottom .bar a:active { filter: blur(2px); }

/* ============================================================
   FIXED TOP: header bar + generative bio
   ============================================================ */
.top {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  background: var(--bg);
  /* extra bottom padding so descenders (g, y, p) in the bio aren't clipped */
  padding: var(--edge) var(--edge) 0.18em;
  color: var(--gray);
  line-height: 1;
}

.top .bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-size: var(--fs-topbar);
}

.top .name { white-space: nowrap; }

.top .mail { white-space: nowrap; }
.top .mail:hover {
  text-decoration-line: underline;
  text-decoration-skip-ink: auto;
  text-decoration-thickness: 0.07em;
  text-underline-offset: 0.12em;
}

.bio {
  margin-top: 0.35em;
  text-align: justify;
  text-justify: inter-word;
  color: var(--ink);   /* bio in black, like the CV text */
  font-size: var(--fs);
  line-height: 1;
}

/* typewriter word slots */
.tw {
  white-space: pre;      /* preserve spacing while animating */
}
/* smooth gray/black glitch while a word is being (re)written */
.tw.caret {
  animation: tw-glitch 0.9s ease-in-out infinite;
}
@keyframes tw-glitch {
  0%, 100% { color: #ff0000; }  /* black */
  50%      { color: #A2A2A2; }  /* gray — smoothly interpolated */
}

/* blinking caret shown only on the word currently being (re)written */
.tw.caret::after {
  content: "";
  display: inline-block;
  width: 0.5ch;
  margin-left: 0.04em;
  background: currentColor;
  color: transparent;
  animation: tw-blink 0.9s steps(1) infinite;
  vertical-align: baseline;
}
@keyframes tw-blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }

/* white opacity mask under the fixed top zone */
.fade--top {
  position: absolute;
  left: 0; right: 0;
  top: 100%;
  height: var(--fade);
  background: linear-gradient(to bottom, #fff 0%, rgba(255,255,255,0) 100%);
  pointer-events: none;
  z-index: 20;
}

/* ============================================================
   SCROLLABLE: two-column CV
   ============================================================ */
.columns {
  display: flex;
  gap: var(--gap);
  /* pinned between the fixed top & bottom zones so each column scrolls alone */
  position: fixed;
  inset: 0;
  z-index: 1;   /* behind the fixed top/bottom masks (z 20) */
  /* clear the fixed zones + breathing room between the bio and the columns */
  padding: calc(var(--topH) + 0.55em) var(--edge) calc(var(--botH) + 0.2em);
  font-size: var(--fs-cv);   /* CV text stays smaller than header/bio/footer */
}

.col {
  flex: 1 1 0;
  min-width: 0;
  hyphens: none;
  /* independent vertical scroll for each column */
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;          /* Firefox: hide scrollbar */
  -ms-overflow-style: none;       /* old Edge */
}
.col::-webkit-scrollbar { width: 0; height: 0; display: none; }  /* WebKit */

.sec {
  color: var(--ink);
  margin: 1.4em 0 0.35em;
  padding-left: 20px;   /* small indent for section titles */
}
.col > .sec:first-child { margin-top: 0.25em; }

.e {
  color: var(--ink);
  margin: 0 0 0.85em;
  line-height: 1;
  transition: filter 0.15s ease;
}

/* hovering/tapping ANYWHERE in a CV entry that contains a link (DOI, name
   link like Edwin Jakobs / Rebecca Bertero, ↗ icon) blurs the whole
   reference text — not just the exact link/first line */
.e:has(a):hover, .e:has(a):active {
  filter: blur(2px);
}

/* date line: its own line, plain black text (no bar) */
.date {
  display: block;
  color: var(--ink);
}

/* links: thin dark underline (no colors) */
.e a {
  color: inherit;
  word-break: break-word;
  text-decoration-line: underline;
  text-decoration-color: var(--ink);
  text-decoration-thickness: 0.07em;
  text-decoration-skip-ink: auto;
  text-underline-offset: 0.12em;
}

/* website link collapsed into a thin arrow icon next to the project title */
.e a.ext {
  text-decoration-line: underline;
  white-space: nowrap;
  color: var(--ink);
  margin-left: 0.12em;
}
.e a.ext:hover { color: var(--gray); }
.ext-ico {
  width: 0.66em;
  height: 0.66em;
  display: inline-block;
  vertical-align: baseline;
}

/* IED entry hover: fill the whole viewport with the gif in TRUE difference.
   The overlay lives at the root of <body> (not inside .columns) so its
   blend backdrop is the white page + all content -> real inversion. */
.ied-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;                 /* above headers/footer/columns */
  pointer-events: none;        /* never block hover / clicks */
  background: url("images/IED/Frame%20106.gif") center center / cover no-repeat;
  mix-blend-mode: difference;  /* inverts the whole background underneath */
  opacity: 0;
  transition: opacity 0.12s ease;
}
.ied-overlay.on { opacity: 1; }

/* RMIT entries hover: same full-viewport true-difference gif treatment */
.rmit-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  background: url("images/Frame%2052.gif") center center / cover no-repeat;
  mix-blend-mode: difference;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.rmit-overlay.on { opacity: 1; }

/* single pre-rendered loop (images/scroll-loop.mp4) with every selected
   photo + video cut together at encode time with hard cuts only (no
   crossfade/dissolve between clips). Shown only while the page is being
   scrolled (JS toggles .on), hidden at rest -- no opacity transition here
   on purpose, so the appear/disappear is a hard cut, not a dissolve. */
.scroll-video {
  position: fixed;
  inset: 0;
  z-index: 40;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
  pointer-events: none;
  mix-blend-mode: difference;
  opacity: 0;
  /* own compositing layer: without this, Safari/Chrome only recomposite the
     blended video against the page when something else forces a repaint
     (e.g. scrolling), so the frame appears frozen/blank while idle */
  transform: translateZ(0);
  will-change: transform;
  backface-visibility: hidden;
}
.scroll-video.on { opacity: 1; }

/* the hovered entry text blurs slightly while the gif is showing */
.ied-trigger, .rmit-trigger { transition: filter 0.2s ease; }
.ied-trigger.blur, .rmit-trigger.blur { filter: blur(2px); }

/* DOI links: on their own "→ ..." line, plain */
.linkline {
  display: block;
  color: var(--ink);
  margin: 0.08em 0;
  word-break: break-word;
}

/* ============================================================
   FIXED BOTTOM: social header
   ============================================================ */
.bottom {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 20;
  background: var(--bg);
  padding: 0 var(--edge) var(--edge);
  color: var(--gray);
  font-size: var(--fs);
  line-height: 1;
}

/* white opacity mask above the fixed bottom zone */
.fade--bottom {
  position: absolute;
  left: 0; right: 0;
  bottom: 100%;
  height: var(--fade);
  background: linear-gradient(to top, #fff 0%, rgba(255,255,255,0) 100%);
  pointer-events: none;
}

.bottom .bar {
  display: flex;
  justify-content: space-between;   /* spread across the full page width */
  align-items: baseline;
  width: 100%;
}
.bottom .bar a { white-space: nowrap; }
.bottom .bar a:hover {
  text-decoration-line: underline;
  text-decoration-skip-ink: auto;
  text-decoration-thickness: 0.07em;
  text-underline-offset: 0.12em;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */

/* tablet: scale the type down a little (still uniform everywhere) */
@media (max-width: 1100px) {
  :root { --fs: 28px; --fs-topbar: 28px; --fs-cv: 22px; }
}

/* phone: single column, stacked, smaller uniform type */
@media (max-width: 680px) {
  :root {
    --fs: 20px;
    --fs-topbar: 20px;
    --fs-cv: 16px;
    --fade: 0.28rem;
  }
  .top .bar {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.2em 1rem;
  }
  /* on phones fall back to a single scrolling page (stacked columns) */
  body { overflow: auto; }
  .columns {
    position: static;
    inset: auto;
    flex-direction: column;
    gap: 0;
  }
  .col {
    height: auto;
    overflow: visible;
  }
  .col + .col { margin-top: 1.2em; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
