/* Blackstaff Automation — the maximalist cut.
   A section drawing of Belfast that you fall through. The canvas is the world;
   everything here is the copy that rides over it.

   The page is readable with JavaScript off: the canvas stays blank, --vis
   defaults to 1, and every chapter is plain text on paper. */

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/space-grotesk-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/space-grotesk-700.woff2') format('woff2');
}

@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/source-serif-4-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/source-serif-4-600.woff2') format('woff2');
}

:root {
  --ink: #1A1D21;
  --paper: #F7F5F0;
  --copper: #B3652A;
  --copper-deep: #8F4E1E;
  --copper-lit: #E08A45;
  --stone: #5A5651;

  --font-display: 'Space Grotesk', system-ui, sans-serif;
  --font-body: 'Source Serif 4', Georgia, serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  overflow-x: hidden;
}

::selection {
  background: var(--copper);
  color: var(--paper);
}

:focus-visible {
  outline: 3px solid var(--copper-lit);
  outline-offset: 3px;
}

/* The world. Fixed behind everything; JS paints it, scroll drives the camera. */

#world {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* Header and the depth rail float over the world. */

header {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 3;
  padding: 1.5rem 1.75rem;
  mix-blend-mode: difference;
}

.wordmark {
  margin: 0;
  color: #fff;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.0625rem;
  letter-spacing: 0.02em;
}

.wordmark strong {
  font-weight: 700;
}

/* On the thank-you page the wordmark is the way home, and it must not pick up
   the copper underline every other link on the site carries. */
.wordmark a {
  color: inherit;
  text-decoration: none;
}

/* Depth rail: a drafting datum down the right edge. Doubles as the section nav. */

.rail {
  position: fixed;
  top: 50%;
  right: 1.5rem;
  z-index: 3;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  mix-blend-mode: difference;
  color: #fff;
}

.rail ol {
  margin: 0;
  padding: 0;
  list-style: none;
  border-right: 1px solid rgba(255, 255, 255, 0.4);
}

.rail li {
  position: relative;
}

.rail a {
  display: block;
  padding: 0.55rem 1.25rem 0.55rem 0;
  color: inherit;
  text-decoration: none;
  text-align: right;
}

.rail a::after {
  content: '';
  position: absolute;
  top: 50%;
  right: -1px;
  width: 8px;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
}

.rail a span {
  opacity: 0.45;
  transition: opacity 200ms;
}

.rail a:hover span,
.rail a[aria-current='true'] span {
  opacity: 1;
}

.rail a[aria-current='true']::after {
  width: 20px;
  height: 2px;
  opacity: 1;
}

.rail-depth {
  display: block;
  margin-bottom: 1rem;
  padding-right: 1.25rem;
  text-align: right;
  font-weight: 700;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

/* Chapters. Each is a tall scroll runway; the copy pins in the middle of it
   and JS ramps --vis so it breathes in and out as the camera passes. */

main {
  position: relative;
  z-index: 1;
}

.chapter {
  min-height: 185vh;
}

.chapter--service {
  min-height: 155vh;
}

.chapter--contact {
  position: relative;
  min-height: 0;
  padding: 12vh 0 14vh;
}

/* The thank-you page. No world behind it and no script: the flight is over, so
   this is one sentence on paper. Deliberately NOT a .chapter — a chapter is a
   scroll runway with a tall min-height, and this page has nothing to scroll. */
.thanks {
  display: flex;
  align-items: center;
  min-height: 100vh;
  padding: 8rem 1.75rem 6rem;
}

.thanks .copy {
  max-width: 44rem;
  margin: 0 auto;
}

/* Contact has no pin, so it carries its own scrim — full-bleed and feathered
   top and bottom. A radial one faded out exactly under the email address. */
.chapter--contact::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, transparent 0%, var(--scrim) 7%, var(--scrim) 93%, transparent 100%);
}

/* The top padding is headroom: it seats the copy below the wordmark, so that as
   the panel leaves upward the copy runs out of opacity before it runs into the
   header. */
.pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  padding: 4.5rem 1.75rem 1.5rem;
}

/* The scrim is what keeps text legible over a moving drawing. It darkens the
   edge the copy sits against, like a cinema grade — not a box behind the words. */
/* The scrim must hold FULL strength across the whole width the copy occupies,
   and only then fade. The copy column ends at about half the viewport, so the
   fade starts there — the bright half of the drawing is the half with no text
   on it. Fading earlier put paper text straight onto a lit brick wall. */
.pin::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: var(--vis, 1);
  background: linear-gradient(90deg, var(--scrim) 0%, var(--scrim) 50%, var(--scrim-mid) 64%, transparent 82%);
}

.copy {
  position: relative;
  width: 100%;
  max-width: 38rem;
  margin-left: clamp(1rem, 7vw, 7rem);
  opacity: var(--vis, 1);
  transform: translateY(calc((1 - var(--vis, 1)) * 2rem));
  will-change: opacity, transform;
}

[data-tone='light'] {
  --scrim: rgba(247, 245, 240, 0.95);
  --scrim-mid: rgba(247, 245, 240, 0.66);
  color: var(--ink);
}

[data-tone='dark'] {
  --scrim: rgba(13, 15, 17, 0.93);
  --scrim-mid: rgba(13, 15, 17, 0.60);
  color: var(--paper);
}

/* Type. This is the maximalist cut: the hero is allowed to be enormous. */

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 700;
  margin: 0 0 1.25rem;
}

h1 {
  font-size: clamp(2.5rem, 6vw, 5.25rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
}

h2 {
  font-size: clamp(2rem, 4.6vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
}

h3 {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

p {
  margin: 0 0 1.25rem;
}

.lede {
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  line-height: 1.5;
  margin-bottom: 2rem;
}

.pull {
  font-size: clamp(1.25rem, 2vw, 1.625rem);
  line-height: 1.4;
  border-left: 3px solid var(--copper);
  padding-left: 1.25rem;
  margin-bottom: 2rem;
}

/* Service blocks: an eyebrow, the promise, then the symptoms in the reader's
   own voice. The symptom line is quieter but still clears AA on the scrim. */

.tag {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--copper-lit);
  margin-bottom: 0.75rem;
}

.claim {
  font-size: clamp(1.125rem, 1.5vw, 1.3125rem);
  line-height: 1.5;
}

/* Quieter than the claim, but it still has to clear 4.5:1 against whatever the
   drawing is doing behind it — so it is lighter than a "muted grey" would be. */
.symptom {
  color: #D5CFC3;
  margin-bottom: 0;
}

[data-tone='light'] .symptom {
  color: var(--stone);
}

/* Links and the button. */

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--copper);
  text-underline-offset: 3px;
}

.button {
  display: inline-block;
  margin-top: 0.5rem;
  padding: 0.9rem 2.25rem;
  background: var(--copper-deep);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: background 160ms, transform 160ms;
}

.button:hover {
  background: var(--ink);
  transform: translateY(-2px);
}

/* Contact. The flight is over; this is a plain, quiet form on paper. */

.copy--contact {
  max-width: 38rem;
  margin: 0 auto;
  padding: 0 1.75rem;
}


form {
  margin: 2.5rem 0 1.5rem;
}

.field {
  margin-bottom: 1.75rem;
}

label {
  display: block;
  margin-bottom: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

input[type='text'],
input[type='email'],
textarea {
  width: 100%;
  padding: 0.6rem 0;
  border: none;
  border-bottom: 2px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 1.0625rem;
  line-height: 1.5;
}

input[type='text']:focus,
input[type='email']:focus,
textarea:focus {
  border-bottom-color: var(--copper-deep);
}

textarea {
  resize: vertical;
}

button[type='submit'] {
  padding: 0.9rem 2.5rem;
  border: none;
  background: var(--copper-deep);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 160ms;
}

button[type='submit']:hover {
  background: var(--ink);
}

button[type='submit']:disabled {
  opacity: 0.6;
  cursor: default;
}

.gotcha {
  display: none;
}

.cf-turnstile {
  margin-bottom: 1.75rem;
}

.form-message {
  padding: 0.875rem 1rem;
  border-left: 3px solid var(--copper-deep);
}

.email-fallback {
  margin-bottom: 0;
  font-size: 1.125rem;
}

/* The brief. A working document, not a greeting — so it is set like a note, not a card. */

.brief {
  margin: 2rem 0 2.5rem;
}

.brief-reading {
  color: var(--stone);
  font-style: italic;
}

.brief-panel {
  padding-left: 1.25rem;
  border-left: 3px solid var(--copper-deep);
}

.brief-intro {
  margin-top: 0;
  color: var(--stone);
}

.brief-fields {
  margin: 1.5rem 0;
}

.brief-field + .brief-field {
  margin-top: 1.125rem;
}

.brief-fields dt {
  margin-bottom: 0.25rem;
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.brief-fields dd {
  margin: 0;
}

.brief-check {
  margin-bottom: 0.875rem;
  font-family: var(--font-display);
  font-weight: 700;
}

.brief-answers {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.brief-answers button {
  padding: 0.75rem 1.75rem;
  border: 2px solid var(--copper-deep);
  background: var(--copper-deep);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 160ms;
}

.brief-answers button:hover {
  background: var(--ink);
  border-color: var(--ink);
}

.brief-answers button:disabled {
  opacity: 0.6;
  cursor: default;
}

/* "No, let me fix it" is not a lesser action, but it is the quieter one. */
.brief-answers .button--quiet {
  background: transparent;
  color: var(--ink);
}

.brief-answers .button--quiet:hover {
  background: var(--ink);
  color: var(--paper);
}

/* Footer: the river goes back underground. */

footer {
  position: relative;
  z-index: 1;
  background: var(--ink);
  color: var(--paper);
  border-top: 3px solid var(--copper);
}

footer .wrap {
  max-width: 64ch;
  margin: 0 auto;
  padding: 3rem 1.75rem 3.5rem;
}

.footer-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.25rem;
}

.footer-name strong {
  font-weight: 700;
}

.footer-small {
  font-size: 0.9375rem;
  margin-bottom: 0.5rem;
}

.footer-small:last-child {
  margin-bottom: 0;
}

/* Narrow viewports. The flight still runs, but the rail and the huge margins go. */

@media (max-width: 46rem) {
  /* The rail loses its rungs — but not the last one. Contact is last because it
     is the last chapter, and a phone visitor who has just flown the river and
     decided to get in touch would otherwise have fifteen viewports between them
     and the form. The flight stays; the door stays open. */
  .rail li:not(:last-child) {
    display: none;
  }

  /* No hover on a phone, so the resting state is the only state — and a door
     nobody can see is not a door. */
  .rail a {
    padding: 0.7rem 1.25rem 0.7rem 0;
  }

  .rail a span {
    opacity: 1;
  }

  /* The door disappears the moment the form starts coming into view — see
     paintRail() in world.js. It is fixed to the bottom right, and the contact
     section is the one chapter that is not pinned, so its heading scrolls up
     through exactly that corner. Left visible, the shortcut to the form prints
     itself over the form. */
  .rail--arrived ol {
    display: none;
  }

  .rail {
    top: auto;
    bottom: 1.25rem;
    right: 1.25rem;
    transform: none;
  }

  .copy {
    margin-left: 0;
  }

  /* On a phone the copy runs the full width, so a side scrim cannot protect it:
     the veil has to cover the frame. There is no arrangement that keeps text
     legible AND the drawing at full brightness right behind it — this trades
     brightness for reading, and reading wins. */
  .pin::before {
    background: linear-gradient(180deg, transparent 0%, var(--scrim) 3%, var(--scrim) 97%, transparent 100%);
  }

  /* The copy must fit inside the pinned viewport. At 360px the long chapters
     overflowed it, which pushed their headings out past the veil and onto the
     bare drawing. Tighter type is what keeps them inside it. */
  body {
    font-size: 1rem;
  }

  h2 {
    font-size: clamp(1.75rem, 7.5vw, 2.25rem);
  }

  .lede {
    font-size: 1.0625rem;
    margin-bottom: 1.25rem;
  }

  .pull {
    font-size: 1.0625rem;
    line-height: 1.45;
    padding-left: 1rem;
    margin-bottom: 1.25rem;
  }

  p {
    margin-bottom: 1rem;
  }

  .chapter,
  .chapter--service {
    min-height: 148vh;
  }
}

/* Reduced motion: no flight. The canvas paints one still frame per chapter and
   the copy simply sits there. Nothing animates, nothing fades. */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .copy {
    opacity: 1;
    transform: none;
  }

  .button:hover {
    transform: none;
  }

  .chapter,
  .chapter--service {
    min-height: 100vh;
  }
}
