:root {
  --logo-bg: #000000;
  --logo-color: #ff4040;
  --mission-bg: #ff4040;
  --mission-text: #000000;
  --font-base: 'Ubuntu', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'Ubuntu Mono', 'Courier New', Courier, monospace;
  --ease-panel: cubic-bezier(0.66, 0, 0.16, 1);
  --dur-panel: 900ms;
}

* {
  box-sizing: border-box;
}

html {
  scroll-snap-type: y mandatory;
}

html,
body {
  margin: 0;
}

body {
  font-family: var(--font-base);
  background-color: var(--logo-bg);
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ---------------------------------------------------------------- stage */

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  z-index: 1;
}

/* Layer 0 — split screen */

.split {
  position: absolute;
  inset: 0;
  display: flex;
  z-index: 1;
}

/* Stage 2: everything from stage 1 travels up at exactly the rate the short
   film rises, so the two tile the viewport with no gap between them. */
.split,
.reveal {
  transition: transform var(--dur-panel) var(--ease-panel);
  will-change: transform;
}

body[data-stage="2"] .split,
body[data-stage="2"] .reveal {
  transform: translateY(-100%);
}

.panel {
  position: relative;
  flex: 1 1 50%;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 3rem;
}

.panel--brand {
  background-color: var(--logo-bg);
  color: var(--logo-color);
  padding: 0;
}

.panel--mission {
  background-color: var(--mission-bg);
  color: var(--mission-text);
}

/* The mission column is pushed up out of frame by the founder panel. */
.panel__shift {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  transition: transform var(--dur-panel) var(--ease-panel);
  will-change: transform;
}

body[data-stage="1"] .panel__shift,
body[data-stage="2"] .panel__shift {
  transform: translateY(-110%);
}

.brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  /* Governs the fade back in. Delayed, because the showreel panel takes the
     full 900ms to slide clear of the logo — without the wait the panel just
     uncovers a logo that has already finished fading up. */
  transition: opacity 350ms ease 550ms;
}

/* Governs the fade out, which runs immediately as the panel sweeps across. */
body:not([data-stage="0"]) .brand {
  opacity: 0;
  transition: opacity 650ms ease;
}

.brand__logo {
  width: 88%;
  height: auto;
  display: block;
}

.mission {
  width: 100%;
  max-width: 56ch;
}

.mission__text {
  margin: 0 0 1.25rem;
  font-family: var(--font-mono);
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  font-weight: 400;
  line-height: 1.65;
  text-align: left;
  min-height: 1.65em;
}

.mission__text:last-child {
  margin-bottom: 0;
}

/* Layer 1 — showreel + founder */

.reveal {
  position: absolute;
  inset: 0;
  display: flex;
  z-index: 2;
  pointer-events: none;
}

.reveal__slot {
  position: relative;
  flex: 1 1 50%;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

.reveal__panel {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  transition: transform var(--dur-panel) var(--ease-panel);
  will-change: transform;
}

.reveal__panel--film {
  background-color: var(--logo-bg);
  color: var(--logo-color);
  padding: 1.5rem;
  transform: translateX(-100%);
}

/* Sits over the right column rather than travelling with its content. It
   starts transparent so the mission text below stays readable at stage 0,
   then goes opaque in the mission colour. */
.reveal__panel--founder {
  background-color: transparent;
  color: var(--mission-text);
  padding: 2rem;
  transition: background-color var(--dur-panel) var(--ease-panel);
}

body[data-stage="1"] .reveal__panel--film,
body[data-stage="2"] .reveal__panel--film {
  transform: translateX(0);
}

body[data-stage="1"] .reveal__panel--founder,
body[data-stage="2"] .reveal__panel--founder {
  background-color: var(--mission-bg);
}

body[data-stage="1"] .reveal,
body[data-stage="2"] .reveal {
  pointer-events: auto;
}

/* The showreel is 2.4:1 scope letterboxed inside a 16:9 file — the frame
   below matches the picture area so the baked-in black bars are cropped.
   Full panel width, so the picture is as large as the aspect allows. */
.film {
  width: 100%;
  aspect-ratio: 1920 / 792;
  max-height: 100%;
  background-color: #000;
  overflow: hidden;
}

.film__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Fullscreen is a real 16:9 surface — show the whole frame, bars and all. */
.film__video:fullscreen,
.film__video:-webkit-full-screen {
  object-fit: contain;
}

.founder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  margin: 0;
  transform: translateY(110%);
  transition: transform var(--dur-panel) var(--ease-panel);
  will-change: transform;
}

body[data-stage="1"] .founder,
body[data-stage="2"] .founder {
  transform: translateY(0);
}

/* Top-aligned so the name starts level with the top of the portrait. */
.founder__row {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 2rem;
  width: 100%;
  max-width: 60rem;
}

/* The container grows with the panel; the portrait stays capped so the extra
   width goes to the text rather than blowing the image back up. */
.founder__image {
  flex: 0 0 auto;
  width: 27%;
  max-width: 14.8rem;
  height: auto;
  max-height: 48vh;
  object-fit: contain;
  object-position: center;
}

.founder__body {
  flex: 1 1 auto;
  min-width: 0;
}

.founder__name,
.founder__text {
  position: relative;
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(0.95rem, 1.25vw, 1.2rem);
  line-height: 1.65;
  text-align: left;
}

.founder__name {
  font-weight: 700;
  margin-bottom: 0.35em;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Zero layout shift while typing: a hidden copy reserves the exact space. */
.type-ghost {
  visibility: hidden;
}

.type-live {
  position: absolute;
  inset: 0;
}

/* Layer 2 — full screen short film */

.short {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #000;
  transform: translateY(100%);
  transition: transform var(--dur-panel) var(--ease-panel);
  will-change: transform;
}

body[data-stage="2"] .short {
  transform: translateY(0);
}

/* Fills the frame. The file is true 16:9 with no baked-in bars, so on a
   widescreen display this is an exact fit rather than a crop. */
.short__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background-color: #000;
}

/* A portrait phone would crop away most of the frame — show it whole there. */
@media (orientation: portrait) and (max-width: 1024px) {
  .short__video {
    object-fit: contain;
  }
}

.sound {
  position: absolute;
  top: 1.5rem;
  right: 1.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1.1rem;
  border: 0;
  background-color: var(--mission-bg);
  color: var(--mission-text);
  font-family: var(--font-mono);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}

.sound[hidden] {
  display: none;
}

.sound.is-muted .sound__icon {
  opacity: 0.5;
}

.sound__icon {
  width: 0.85rem;
  height: 0.85rem;
  background-color: currentColor;
  clip-path: polygon(0 30%, 35% 30%, 70% 0, 70% 100%, 35% 70%, 0 70%);
}

/* Credit bug over the short film */

/* Everything is sized in em off this one font-size and the lines never wrap,
   so the bug scales as a unit and stays exactly three lines. The square is
   5.75em to match 3 × 1.45em of text plus 2 × 0.7em of padding. */
.filminfo {
  position: absolute;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 4;
  display: flex;
  align-items: flex-start;
  font-family: var(--font-mono);
  font-size: clamp(0.55rem, 2.35vw, 0.86rem);
  pointer-events: none;
}

/* favicon.svg already carries the accent square + black mark. */
.filminfo__mark {
  flex: 0 0 auto;
  display: block;
  width: 5.75em;
  height: 5.75em;
}

.filminfo__text {
  margin: 0;
  padding: 0.7em 0.9em;
  background-color: #000;
  color: var(--mission-bg);
  line-height: 1.45;
}

.filminfo__text span {
  display: block;
  white-space: nowrap;
}

/* Scroll hint */

.hint {
  position: absolute;
  right: 2rem;
  bottom: 1.75rem;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--mission-text);
  font-family: var(--font-mono);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: opacity 400ms ease;
}

.hint__arrow {
  width: 0.7rem;
  height: 0.7rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  animation: nudge 1.6s ease-in-out infinite;
}

body:not([data-stage="0"]) .hint {
  opacity: 0;
}

@keyframes nudge {
  0%, 100% {
    transform: translateY(-2px) rotate(45deg);
  }
  50% {
    transform: translateY(3px) rotate(45deg);
  }
}

/* Typing cursor */

.cursor {
  display: inline-block;
  width: 0.65em;
  height: 1.05em;
  background-color: currentColor;
  margin-left: 0.08em;
  vertical-align: text-bottom;
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

/* --------------------------------------------------------- scroll track */

.scroll-track {
  position: relative;
  z-index: 0;
}

.scroll-step {
  height: 100vh;
  height: 100svh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* -------------------------------------------------------------- mobile */

@media (max-width: 1024px) {
  /* Columns become rows: the showreel still slides in from the left over
     the logo, the founder panel still rises over the mission text. */
  .split,
  .reveal {
    flex-direction: column;
  }

  .panel {
    flex: 1 1 50%;
    padding: 2rem 1.5rem;
  }

  .panel--brand {
    padding: 0 1.25rem;
  }

  .brand {
    align-items: center;
    text-align: center;
  }

  .mission {
    max-width: 60ch;
  }

  .mission__text {
    font-size: clamp(0.85rem, 3.2vw, 1.05rem);
    margin-bottom: 0.9rem;
  }

  .reveal__panel {
    padding: 1.25rem;
  }

  .reveal__panel--film {
    padding: 1rem;
  }

  .film {
    max-width: 100%;
  }

  .founder__row {
    gap: 1.25rem;
    max-width: 44rem;
  }

  .founder__image {
    width: 29%;
    max-height: 27vh;
  }

  .founder__name,
  .founder__text {
    font-size: clamp(0.8rem, 3.1vw, 1rem);
    line-height: 1.55;
  }

  .hint {
    right: 1.25rem;
    bottom: 1.25rem;
    font-size: 0.8rem;
  }

  .sound {
    top: 1rem;
    right: 1rem;
    padding: 0.6rem 0.9rem;
    font-size: 0.85rem;
  }

  /* Lifted clear of the video's native control bar, which sits at the very
     bottom of the player on a phone. */
  .filminfo {
    right: 1rem;
    bottom: 4.5rem;
  }
}

/* A phone held in landscape is watching the film full-frame — no credit bug. */
@media (orientation: landscape) and (max-height: 600px) {
  .filminfo {
    display: none;
  }
}

/* Belt and braces: hide it whenever anything is in fullscreen. */
:root:has(:fullscreen) .filminfo {
  display: none;
}

@media (max-width: 480px) {
  .panel {
    padding: 1.5rem 1.25rem;
  }

  .panel--brand {
    padding: 0 1rem;
  }

  .reveal__panel {
    padding: 1rem;
  }

  .reveal__panel--film {
    padding: 0.75rem;
  }

  .founder__row {
    gap: 0.9rem;
  }

  .founder__image {
    width: 27%;
    max-height: 24vh;
  }
}

/* Short viewports (landscape phones) — reclaim vertical space. */
@media (max-width: 1024px) and (max-height: 520px) {
  .founder__row {
    gap: 1rem;
    max-width: none;
  }

  /* Height-capped here, so the square portrait can't outgrow a short row. */
  .founder__image {
    width: auto;
    max-width: 26%;
    max-height: 24vh;
  }

  .founder__name,
  .founder__text {
    font-size: 0.8rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-snap-type: y proximity;
  }

  .split,
  .reveal,
  .panel__shift,
  .reveal__panel,
  .founder,
  .short,
  .brand {
    transition-duration: 1ms;
    transition-delay: 0s;
  }

  .hint__arrow,
  .cursor {
    animation: none;
  }
}
