/* Stacked is the base: the magazine sits in a band at the top, the section
   list is pinned under it, and the bio flows below. Two columns are an
   enhancement for windows that are both wide enough and landscape enough to
   hold them — a half-screen or portrait window gets the stacked layout, not a
   squeezed version of the wide one.

   The landing is a scrolling page now: a hero the height of the window, with
   the interview below it. The magazine lives in the fixed .stage behind, so
   the hero is deliberately click-through except where there is real content. */
.landing {
  position: relative;
  z-index: 20;
  pointer-events: none;
}
body[data-state="reading"] .landing,
body[data-state="opening"] .landing { pointer-events: none; }
body[data-state="reading"] .landing { visibility: hidden; }

.landing__hero {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr;
  align-content: start;
}

/* The hero ornament runs off the right edge on purpose. It is clipped here
   rather than by the document, which would leave the page a scrollWidth wider
   than its viewport; the wrapper holds nothing fixed, so clipping is safe. */
.landing__bleed {
  position: absolute; inset: 0;
  overflow: clip;
  pointer-events: none;
  z-index: -1;
}

/* ── the ornaments ──────────────────────────────────────────────────── */
/* Her own artwork: the halftone sigils from Fall of Man, keyed off their
   pages and masked so they can be tinted to the room rather than pasted on. */
/* Art direction, not decoration. On the old dark ground these sat at .17–.26
   and effectively disappeared; drawn in ink on a pale room they can carry real
   weight without turning into neon — the tint is her own oxblood and mauve, and
   there is no glow anywhere, because a glow is what would make this cyberpunk. */
.landing__sigil {
  position: absolute;
  pointer-events: none;
  opacity: .5;
  background: linear-gradient(150deg, #f0d2d4 0%, #c07f8d 50%, #7d2440 100%);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain;    mask-size: contain;
  -webkit-mask-position: center; mask-position: center;
}
/* Bleeding off the left edge, counterweight to the magazine on the right.
   It crowns the heading and then falls away before the running text: the sigil
   is intersected with a gradient, so the mark itself stays at full strength up
   top and fades to nothing over the columns rather than being dimmed
   everywhere. Strong graphic, readable paragraph — not a compromise between. */
.landing__sigil--hero {
  left: -9vw; top: -1vh;
  width: min(58vw, 48rem); aspect-ratio: 1100 / 537;
  opacity: .42;
  -webkit-mask-image: url("../assets/sigil/flourish-a.png"),
                      linear-gradient(168deg, #000 0%, #000 30%, rgba(0,0,0,.35) 58%, transparent 80%);
          mask-image: url("../assets/sigil/flourish-a.png"),
                      linear-gradient(168deg, #000 0%, #000 30%, rgba(0,0,0,.35) 58%, transparent 80%);
  -webkit-mask-size: contain, 100% 100%;
          mask-size: contain, 100% 100%;
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}
.landing__sigil--qa {
  left: 50%; translate: -50% 0; top: -5rem;
  width: min(78vw, 33rem); aspect-ratio: 1055 / 464;
  opacity: .40;
  -webkit-mask-image: url("../assets/sigil/flourish-b.png");
  mask-image: url("../assets/sigil/flourish-b.png");
}

/* the tall barbed vine, only where there is margin for it to live in */
.landing__sigil--vine {
  display: none;
  left: max(1.2vw, calc(50% - 36rem));
  top: 10%;
  width: min(18vw, 13.5rem); aspect-ratio: 667 / 1100;
  opacity: .34;
  -webkit-mask-image: url("../assets/sigil/vine.png");
  mask-image: url("../assets/sigil/vine.png");
}
@media (min-width: 1180px) {
  .landing__sigil--vine { display: block; }
}

.landing__about {
  position: relative;
  pointer-events: auto;
  width: auto;
  padding: 3.5rem clamp(1.2rem, 5vw, 3rem) 3rem;
  /* clears the magazine, the list and the button beneath it, all measured */
  margin-top: calc(var(--open-bottom, 62dvh) + 2.4rem);
  /* This panel lifts the text off the sigil behind it, but the gradient only
     faded IN — at the foot of the block --room stopped dead against the body
     gradient, a 29-step edge straight across the page. It fades out too now.
     Both stops are the same colour at different alpha, so nothing shifts hue. */
  background: linear-gradient(to bottom,
    rgba(30,21,25,0) 0,
    var(--room) 10%,
    var(--room) 84%,
    rgba(30,21,25,0) 100%);
  transform-origin: 50% 100%;
  transition:
    opacity 200ms ease,
    transform 260ms cubic-bezier(.4,.5,.2,1),
    filter 200ms ease;
}

.landing__eyebrow {
  /* also used inside the h1, where it must not inherit the display face */
  display: block;
  font-family: var(--font-slab);
  font-weight: 400;
  line-height: 1.62;
  margin: 0 0 .35rem;
  font-size: .74rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
/* her name, so it reads as a byline rather than a caption */
.landing__head .landing__eyebrow {
  color: var(--ink-soft);
  font-weight: 500;
}

.landing__display {
  margin: 0 0 1.15rem;
}
/* One heading, two lines: the name carries the display face, the discipline
   sits under it as a rule of small caps. */
.landing__name {
  display: block;
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(3.1rem, 6.4vw, 5.6rem);
  line-height: 1.02;
  color: #e3bfc0;
  letter-spacing: .01em;
}
.landing__role {
  display: block;
  margin-top: .5rem;
  font-family: var(--font-slab);
  font-weight: 500;
  font-size: clamp(.84rem, 1.15vw, 1.04rem);
  line-height: 1.4;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.polaroid {
  float: right;
  width: clamp(6.5rem, 12vw, 9.5rem);
  margin: .2rem 0 .9rem 1.4rem;
  padding: .45rem .45rem 1.15rem;
  background: #e9e0dc;
  box-shadow: 0 1px 1px rgba(0,0,0,.5), 0 18px 34px -16px rgba(0,0,0,.9);
  rotate: 3.2deg;
  position: relative;
  transition: rotate 500ms cubic-bezier(.2,.8,.3,1);
}
.polaroid:hover { rotate: 1.2deg; }
.polaroid img { width: 100%; height: auto; aspect-ratio: 6/7; object-fit: cover; background: #cdc2bb; }
.polaroid__clip {
  position: absolute; top: -.85rem; right: .9rem;
  width: .5rem; height: 2.1rem;
  border: 2px solid #8e8681;
  border-radius: .4rem;
  border-bottom-color: transparent;
  rotate: 8deg;
  box-shadow: .1rem .1rem .3rem rgba(0,0,0,.5);
}
.polaroid__clip::after {
  content: ""; position: absolute; inset: .28rem .1rem .5rem;
  border: 2px solid #a29a95; border-radius: .3rem; border-bottom-color: transparent;
}

/* Capped in ch, not rem, so the measure stays near 62 characters whatever the
   font size resolves to at a given viewport. */
.landing__body { max-width: 63ch; }
.landing__body p { margin: 0 0 1rem; color: var(--ink-soft); }
/* At 600 in --accent (#d9b7b8) these sat within a hair of the body colour
   (#c8b9b8) — close enough that they read as a rendering accident rather than
   emphasis. Full bold, a clearly brighter rose, and a touch of tracking so the
   difference is unmistakable at a glance. */
.landing__body b {
  color: #f4d2d6;
  font-weight: 700;
  letter-spacing: .006em;
}

/* the Depop shop, set apart from the prose as a tag rather than a sentence */
.landing__tag { margin: 1.25rem 0 0 !important; }
.depop {
  display: inline-flex; align-items: center; gap: .42em;
  padding: .42em .85em;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-style: italic;
  font-size: .95rem;
  letter-spacing: .01em;
  color: var(--accent-ink);
  text-decoration: none;
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease;
}
.depop:hover, .depop:focus-visible {
  color: #f3dcdc;
  border-color: rgba(242,234,233,.42);
  background: rgba(66,46,58,.6);
}
.depop svg { opacity: .75; }


/* Stacked, both of these belong in the flow under the bio. Only the two-column
   layout has a right-hand column to hang them off, and pinning them there on a
   phone dropped them straight onto the heading. */
/* Under the contents list, which is itself under the magazine — the same
   relationship at every width, not just on a wide screen. Both the list and
   the button hang off measurements JS takes from the rendered cover. */
#open-book {
  position: absolute;
  left: var(--cover-cx, var(--cover-cx-calc, 50%));
  top: calc(var(--index-bottom, 58dvh) + 1.5rem);
  translate: -50% 0;
  margin: 0;
  z-index: 21;
  display: inline-flex;
  /* Absolutely positioned with `left` set, a shrink-to-fit box only gets the
     space from that offset to the container's edge — at left:50% that halved
     the button and wrapped the label. max-content ignores the offset; the
     max-width keeps it inside the smallest phones. */
  width: max-content;
  max-width: calc(100vw - 2.4rem);
  white-space: nowrap;
  pointer-events: auto;
}

/* The magazine's cover is centred on 28vw: the frame sits at 50vw, is shifted
   by --land-x minus a quarter of its own scaled width, and the cover is its
   right half. Anchoring the list to the same numbers keeps the two aligned at
   any viewport rather than by eye. */
.landing__index {
  position: absolute;
  left: var(--cover-cx, var(--cover-cx-calc, 28vw));
  translate: -50% 0;
  top: calc(var(--cover-bottom, var(--cover-bottom-calc, 70vh)) + 2.1rem);
  width: min(25rem, calc(100vw - 2.6rem));
  margin: 0; padding: 0;
  list-style: none;
  display: grid;
  gap: .3rem;
  justify-items: center;
  pointer-events: auto;
  z-index: 21;
  transition: opacity 380ms ease, transform 460ms cubic-bezier(.4,.5,.2,1);
}
.landing__index li { display: contents; }

.landing__jump {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
  gap: .75rem;
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--ink-faint);
  white-space: nowrap;
  width: 100%;
  padding: .28rem .4rem;
  border: 0; border-radius: .3rem;
  background: none;
  font-family: inherit;
  cursor: pointer;
  transition: background 200ms ease, color 200ms ease;
}
.landing__jump:hover { background: rgba(217,183,184,.13); }
.landing__jump:hover span { color: var(--ink); }
.landing__jump:hover em { color: var(--accent); }
.landing__jump:hover::before { border-bottom-color: rgba(242,234,233,.5); }
.landing__index span { grid-column: 1; text-align: right; color: var(--ink-soft); }
.landing__jump::before {
  content: "";
  grid-column: 2; grid-row: 1;
  width: 2.6rem;
  border-bottom: 1px dotted rgba(242,234,233,.3); 
  translate: 0 -.24em;
}
.landing__index em { grid-column: 3; font-style: normal; text-align: left; }

/* ── the cue down to the interview ──────────────────────────────────── */
.scrollcue {
  position: static;
  margin: 1.5rem auto 2.6rem;
  width: fit-content;
  z-index: 21;
  pointer-events: auto;
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .4rem .9rem;
  border: 1px solid rgba(242,234,233,.26);
  border-radius: 999px;
  background: rgba(48,33,42,.7);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  color: var(--ink-soft);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  text-decoration: none;
  transition: color 200ms ease, border-color 200ms ease, opacity 320ms ease, translate 320ms ease;
}
.scrollcue:hover { color: var(--ink); border-color: rgba(242,234,233,.46); background: rgba(66,46,58,.88); }
.scrollcue svg { animation: cuebob 2.6s ease-in-out infinite; }
@keyframes cuebob { 0%,100% { translate: 0 -1px } 50% { translate: 0 3px } }

/* ── the interview ──────────────────────────────────────────────────── */
.qa {
  position: relative;
  overflow-x: clip;
  z-index: 22;
  pointer-events: auto;
  /* The fade used to sit on top of an opaque --room-deep layer, so it ran from
     --room-deep to --room-deep and did nothing: the section began at full dark
     on its first pixel, against a lit body gradient, which is where the hard
     line came from. With the solid layer gone the fade has something to reveal.
     The stops are eased rather than linear — a straight alpha ramp over this
     distance bands visibly on a dark ground. */
  background: linear-gradient(to bottom,
    rgba(18,13,16,0)    0,
    rgba(18,13,16,.10)  2.5rem,
    rgba(18,13,16,.30)  6rem,
    rgba(18,13,16,.55)  10rem,
    rgba(18,13,16,.76)  14rem,
    rgba(18,13,16,.92)  18rem,
    var(--room-deep)    23rem);
  padding: 7rem clamp(1.2rem, 5vw, 3rem) clamp(4rem, 10vh, 7rem);
}
.qa__inner { max-width: 46rem; margin: 0 auto; }

.qa__head { position: relative; text-align: center; margin-bottom: clamp(2.4rem, 6vh, 4rem); }
.qa__title {
  font-family: var(--font-didone);
  font-weight: 400;
  font-size: clamp(2.1rem, 5.6vw, 3.4rem);
  line-height: 1.05;
  margin: .2rem 0 0;
  color: var(--ink);
  letter-spacing: .01em;
}

.qa__list { margin: 0; padding: 0; }

.qa__item {
  position: relative;
  padding: clamp(1.4rem, 3.4vh, 2.2rem) 0;
  border-top: 1px solid var(--line-soft);
}
.qa__item:first-child { border-top: 0; }

/* a barbed mark from her own sigil, standing in for a bullet */
.qa__item::before {
  content: "";
  position: absolute; left: -1.9rem; top: calc(clamp(1.4rem, 3.4vh, 2.2rem) + .15em);
  width: 1.25rem; height: 1.25rem;
  background: #d9a7ad;
  opacity: .8;
  -webkit-mask: url("../assets/sigil/star.png") center / contain no-repeat;
  mask: url("../assets/sigil/star.png") center / contain no-repeat;
}

.qa__item dt {
  font-family: var(--font-didone);
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
  line-height: 1.25;
  /* not var(--accent): that is a section tint, and the question line wants a
     fixed one that holds its contrast whatever section the reader came from */
  color: #eec9cb;
  margin: 0 0 .7rem;
}
.qa__item dd {
  margin: 0;
  color: var(--ink-soft);
  font-size: .98rem;
  line-height: 1.72;
  max-width: 40rem;
}

.qa__foot { margin-top: clamp(2.4rem, 6vh, 3.6rem); text-align: center; }

/* the panel recedes as the book comes forward */
body[data-state="opening"] .landing__index,
body[data-state="reading"] .landing__index,
body[data-state="opening"] .scrollcue,
body[data-state="reading"] .scrollcue {
  opacity: 0;
  pointer-events: none;
  transform: translateY(1rem);
}
body[data-state="reading"] .stage { position: fixed; }
body[data-state="opening"] .landing__about,
body[data-state="reading"] .landing__about {
  opacity: 0;
  transform: translateY(2rem) scale(.97);
}

/* ── the interview, set larger once there is a screen to set it on ──── */
@media (min-width: 1024px) {
  .qa__inner { max-width: 52rem; }
  .qa__item dt { font-size: clamp(1.45rem, 2.1vw, 1.9rem); line-height: 1.2; margin-bottom: .85rem; }
  .qa__item dd { font-size: 1.12rem; line-height: 1.76; max-width: 46rem; }
  .qa__item { padding: clamp(1.8rem, 4vh, 2.7rem) 0; }
  .qa__item::before { width: 1.45rem; height: 1.45rem; }
  .qa__title { font-size: clamp(2.6rem, 5vw, 4rem); }
}

/* ── two columns, once there is genuinely room for them ─────────────── */
@media (min-width: 1024px) and (min-aspect-ratio: 5 / 4) {
  .landing__index { width: min(25rem, 46vw); }
  .landing__hero {
    grid-template-columns: 58% 42%;
    align-content: center;
    align-items: center;
  }
  /* Wider measure, hard against the left margin. The column was 33rem centred
     in the right half, which made every paragraph deep and pushed the end of
     the bio past the fold; the same words in a 42rem measure on the left sit
     in one screen without the type having to shrink. */
  .landing__about {
    grid-column: 1;
    justify-self: start;
    width: min(52rem, calc(60vw - 3rem));
    margin-top: 0;
    margin-left: clamp(1.6rem, 3.7vw, 4.1rem);
    padding: .9rem 0;
    background: none;
    transform-origin: 18% 50%;
  }
  body[data-state="opening"] .landing__about,
  body[data-state="reading"] .landing__about {
    transform: translateX(-3.5rem) scale(.96);
    filter: blur(3px);
  }
  .qa__item::before { left: -2.6rem; }

  /* The bio used to run four long paragraphs and needed two columns to stay
     above the fold. It is three short ones now, so a single column reads
     better — and the recovered height goes into the type instead. The measure
     is capped near 62 characters, which is where prose is easiest to read. */
  .landing__display { margin-bottom: 1.5rem; }
  .landing__body { font-size: clamp(1.08rem, 1.3vw, 1.32rem); }
  .landing__body p { margin: 0 0 1.15rem; line-height: 1.66; }
  .landing__body p:last-child { margin-bottom: 0; }
  /* The photo sat absolutely over the right-hand column and covered live text.
     It shares a row with the heading instead, so the columns always begin below
     whichever of the two is taller. */
  .landing__about {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "photo head" "body body" "cta cta";
    align-items: start;
    column-gap: clamp(1.2rem, 2.6vw, 2.4rem);
  }
  .landing__head { grid-area: head; }
  .polaroid {
    grid-area: photo;
    position: static;
    float: none;
    width: clamp(7rem, 10.5vw, 9.5rem);
    margin: .2rem 0 0;
    align-self: start;
    rotate: -3.2deg;
  }
  .polaroid:hover { rotate: -1.4deg; }
  /* the heading sits beside the photo, so it no longer needs to clear it */
  .landing__head { align-self: center; }
  /* Only this layout has a right-hand column to hang the buttons off. In the
     flow they fell into the hero grid's second column, which dropped "Open the
     portfolio" straight onto the cover artwork. Pinned: the open button to the
     cover's own measured centre, just below the contents list, and the Q & A
     cue to the middle of the fold. On a phone both stay in the flow. */
  #open-book { top: calc(var(--index-bottom, 64dvh) + 1.6rem); }
  .scrollcue {
    position: absolute;
    left: 50%;
    top: max(calc(100dvh - 3.6rem), calc(var(--about-bottom, 0px) + .7rem));
    translate: -50% 0;
    margin: 0;
  }
  /* The photo and the heading share the top row and the columns run underneath
     both, so the text was butting straight up against the bottom of the print.
     A print needs air under it. */
  .landing__body { grid-area: body; margin-top: clamp(1.1rem, 1.9vh, 1.9rem); }
  #open-book { margin-top: .9rem; }
}

/* ── a wide but short window: the bio gives up a little height ──────── */
/* Modest, not dramatic: the measure and the column count do the real work, so
   this only has to close the last stretch on a short or small laptop. */
@media (min-width: 1024px) and (min-aspect-ratio: 5 / 4) and (max-height: 900px) {
  .landing__about { padding: .5rem 0; }
  .landing__name { font-size: clamp(2.5rem, 4.6vw, 3.6rem); }
  .landing__display { margin-bottom: .9rem; }
  .landing__body p { margin-bottom: .9rem; line-height: 1.58; }
  .polaroid { width: clamp(6rem, 9vw, 7.6rem); margin-top: .15rem; }
  #open-book { margin-top: .6rem; padding: .62rem 1.25rem; font-size: .9rem; }
}

/* the last stretch, on a genuinely short laptop */
@media (min-width: 1024px) and (min-aspect-ratio: 5 / 4) and (max-height: 830px) {
  .landing__about { padding: .2rem 0; }
  .landing__name { font-size: clamp(2.2rem, 4vw, 3.1rem); }
  .landing__body p { margin-bottom: .75rem; line-height: 1.54; }
  #open-book { margin-top: .35rem; }
  .landing__display { margin-bottom: .7rem; }
  .polaroid { width: clamp(5.4rem, 8vw, 6.8rem); }
}

/* ── phones ─────────────────────────────────────────────────────────── */
@media (max-width: 560px) {
  .landing__jump { gap: .5rem; font-size: .82rem; padding: .5rem .3rem; }
  .landing__jump::before { width: 1.6rem; }
  /* at 12vw the name ran 337px into 351px of measure — almost touching both
     edges. It reads as a statement, not a squeeze, with the margin back. */
  .landing__name { font-size: clamp(2.2rem, 10.6vw, 3.4rem); }
  .landing__role { letter-spacing: .26em; }
  .polaroid { width: clamp(6rem, 26vw, 8rem); }
  .landing__index { gap: .1rem; }
  /* no room for a hanging mark beside the question */
  .qa__item::before { position: static; display: block; margin: 0 0 .55rem; }
  .qa { padding-top: 5rem; }
  .landing__sigil--hero { opacity: .22; width: 104vw; left: -22vw; top: 1vh; }
}

/* ── short windows: the bio starts sooner so it is reachable ────────── */
@media (max-height: 620px) and (max-width: 1023px) {
  .landing__about { padding-top: 2.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .landing__about { transition: opacity 300ms ease; }
  .landing__index { transition: opacity 300ms ease; }
  body[data-state="opening"] .landing__index,
  body[data-state="reading"] .landing__index { transform: none; }
  body[data-state="opening"] .landing__about,
  body[data-state="reading"] .landing__about { transform: none; filter: none; }
  .polaroid { transition: none; }
  .scrollcue svg { animation: none; }
}
