/* The landing page's own sections: the hero, its proof band, and the exploded PDF stack. Its
   own sheet because only index.html renders any of it, and the three shared sheets are on the
   review page's transfer budget (tests/test_api.py). Tokens and the type scale apply here
   exactly as they do in base.css (web/DESIGN.md). */

/* Hero. One headline, one promise, one control. The upload reads as a single bar rather than a
   card of fields, so the whole proposition fits above the fold and the next action is
   unmistakable; everything that qualifies the offer sits below it in .hero-scope. */
.hero {
  padding: 60px 0 40px;
  background: var(--surface-page);
  text-align: center;
}

.hero-inner {
  max-width: 880px;
}

.hero h1 {
  margin: 0 auto 14px;
  max-width: 24ch;
}

.hero-lede {
  margin: 0 auto;
  max-width: 62ch;
  color: var(--text-muted);
  font-size: var(--text-lg);
  line-height: 1.5;
}

.upload-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 32px;
  padding: 12px 12px 12px 20px;
  border: 2px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  text-align: left;
}

.upload-bar.dragover, .upload-bar:focus-within {
  border-style: solid;
  border-color: var(--primary);
  background: var(--primary-soft);
}

.upload-bar-label {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  cursor: pointer;
}

.upload-bar .dropzone-icon {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  margin: 0;
  border-radius: var(--radius-md);
  background: var(--primary-soft);
  color: var(--primary-hover);
}

.upload-bar .dropzone-icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.upload-bar .dropzone-title {
  min-width: 0;
  color: var(--text-heading);
  font-size: var(--text-md);
  font-weight: 600;
}

.upload-bar input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.upload-bar .btn {
  flex: 0 0 auto;
}

.upload-bar.has-file {
  border-style: solid;
}

.upload-bar-file:not([hidden]) {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.upload-bar-file strong {
  overflow: hidden;
  color: var(--text-heading);
  font-size: var(--text-md);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.upload-bar-file span {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.upload-bar-remove {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}

.upload-bar-remove[hidden] {
  display: none;
}

.upload-bar-remove:hover {
  color: var(--text-heading);
  background: var(--surface-soft);
}

.upload-bar-remove:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.upload-bar-remove svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* The shared 12px margin lifts the widget off the email field's baseline in this row. */
.hero-form-row .cf-turnstile {
  margin: 0;
}

.hero-form-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: 16px;
  margin-top: 18px;
}

.hero-form-row .email-row {
  flex: 0 1 320px;
  margin: 0;
  text-align: left;
}

.hero-micro {
  margin: 16px 0 0;
  /* --text-muted-soft is only 4.32:1 on --surface-page at 14 px; this line is real copy. */
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.hero-link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  margin-top: 10px;
  color: var(--info);
  font-weight: 700;
}

.hero-link:hover {
  color: var(--primary-hover);
  text-decoration: underline;
}

.hero .file-selection {
  margin-top: 14px;
  text-align: left;
}

/* Proof band: the three facts a visitor wants before they will drop a file in. */
.hero-proof {
  padding: 26px 0 30px;
  border-block: 1px solid var(--line-soft);
  background: var(--surface-card);
}

.hero-proof-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
  margin-block: 0;
  padding: 0;
  list-style: none;
}

.hero-proof-list li {
  padding-left: 14px;
  border-left: 3px solid var(--primary);
}

.hero-proof-list b {
  display: block;
  color: var(--text-heading);
  font-size: var(--text-md);
}

.hero-proof-list span {
  display: block;
  margin-top: 2px;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* What qualifies the offer: out of the first screen, never off the page. */
.hero-scope {
  padding: 28px 0 36px;
  background: var(--surface-page);
}

.hero-scope .fine-print {
  max-width: 820px;
  margin: 0 0 10px;
}

.hero-scope .upload-privacy {
  max-width: 820px;
  margin-top: 16px;
}

@media (max-width: 860px) {
  .hero {
    padding: 40px 0 32px;
  }

  .upload-bar {
    flex-wrap: wrap;
  }

  .upload-bar-label, .upload-bar #submit-btn {
    width: 100%;
  }

  /* The remove icon shares the first line with the chosen file; the button wraps below. */
  .upload-bar.has-file .upload-bar-label {
    width: auto;
    flex: 1 1 0;
  }

  .hero-proof-list {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
  }
}

/* Exploded PDF stack. Every plane carries the same tilt and is offset from the one below it in
   plain screen pixels, so there is no perspective and no 3D sorting: planes paint in document
   order, which is why the visual page is written first and sits at the bottom of the stack.
   --p is scroll progress 0..1, set by pdf-layers.js; it defaults to 1 so the stack stands fully
   open without JavaScript, at reduced motion, and in the stacked phone layout. */
.pdf-layers {
  padding: 72px 0 0;
  border-block-start: 1px solid var(--line);
  background: var(--surface-card);
}

.pdf-layers-intro h2, .pdf-layers-intro p {
  max-width: 760px;
}

.pdf-layers-intro p {
  color: var(--text-muted);
}

.pdf-layers-grid {
  --p: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: 48px;
  margin-top: 8px;
}

.pdf-layers-stage {
  position: sticky;
  top: 96px;
  height: 600px;
  overflow: clip;
}

.pdf-layers-defs {
  position: absolute;
}

.pdf-layers-deck {
  --plane-w: 290px;
  --plane-h: 376px;
  --fan-x: 11px;
  --fan-y: 31px;
  --deck-scale: 0.95;
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--plane-w);
  height: var(--plane-h);
  /* The fan runs up and to the right, so the deck drifts the other way by half of it and
     the open stack stays centred on the same point the closed page sat on. */
  transform: translate(-50%, -50%) scale(var(--deck-scale))
    translate(calc(var(--fan-x) * -4 * var(--p)), calc(var(--fan-y) * 4 * var(--p)));
}

.pdf-layer {
  --tint: var(--surface-soft);
  --edge: var(--line-strong);
  --r: clamp(0, calc(var(--p) * 9 - var(--i) + 1), 1);
  position: absolute;
  inset: 0;
  border: 1px solid var(--edge);
  border-radius: 2px;
  background: var(--tint);
  box-shadow: 0 12px 26px -14px var(--shadow-color);
  opacity: var(--r);
  transform:
    translate(calc(var(--fan-x) * var(--i) * var(--r)),
              calc(var(--fan-y) * var(--i) * var(--r) * -1))
    rotateX(48deg) rotateZ(-32deg);
  transition: background-color 160ms ease, box-shadow 160ms ease;
}

/* The layer whose label is being read comes to the front of the stack, where its artwork is
   not under eight other sheets, and turns opaque so the artwork reads. */
.pdf-layer.is-active {
  z-index: 3;
  background-color: var(--surface-glass);
  background-image: linear-gradient(var(--tint), var(--tint));
  box-shadow: 0 0 0 2px var(--edge), 0 18px 34px -16px var(--shadow-color-strong);
}

.pdf-layer-page {
  background: var(--surface-card);
  opacity: 1;
}

/* Nine sets of artwork at full strength is a pile, not a stack. Only the page under
   everything and the layer being described are drawn to be read. */
.pdf-layer-art {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0.3;
}

.pdf-layer-page .pdf-layer-art, .pdf-layer.is-active .pdf-layer-art {
  opacity: 1;
}

/* List item N and deck plane N are the same layer. --i is how high it rides above the page
   and picks its tint; the order is the one strings/en.json lists, which the deck mirrors. */
.pdf-layer:nth-child(1), .pdf-layer-item:nth-child(1) { --i: 0; --tint: var(--surface-soft); --edge: var(--text-muted); }
.pdf-layer:nth-child(2), .pdf-layer-item:nth-child(2) { --i: 1; --tint: var(--layer-text); --edge: var(--layer-text-line); }
.pdf-layer:nth-child(3), .pdf-layer-item:nth-child(3) { --i: 2; --tint: var(--layer-tags); --edge: var(--layer-tags-line); }
.pdf-layer:nth-child(4), .pdf-layer-item:nth-child(4) { --i: 3; --tint: var(--layer-order); --edge: var(--layer-order-line); }
.pdf-layer:nth-child(5), .pdf-layer-item:nth-child(5) { --i: 4; --tint: var(--layer-headings); --edge: var(--layer-headings-line); }
.pdf-layer:nth-child(6), .pdf-layer-item:nth-child(6) { --i: 5; --tint: var(--layer-tables); --edge: var(--layer-tables-line); }
.pdf-layer:nth-child(7), .pdf-layer-item:nth-child(7) { --i: 6; --tint: var(--layer-figures); --edge: var(--layer-figures-line); }
.pdf-layer:nth-child(8), .pdf-layer-item:nth-child(8) { --i: 7; --tint: var(--layer-links); --edge: var(--layer-links-line); }
.pdf-layer:nth-child(9), .pdf-layer-item:nth-child(9) { --i: 8; --tint: var(--layer-settings); --edge: var(--layer-settings-line); }

/* Plane artwork. Every plane carries the same ghosted document so the stack reads as one
   file seen nine ways; the motif on top is what that layer contributes. */
.pdfl-ghost {
  fill: var(--text-muted-soft);
  opacity: 0.16;
}

.pdfl-solid {
  fill: var(--line);
}

.pdfl-fill {
  fill: var(--edge);
}

.pdfl-soft {
  fill: var(--edge);
  fill-opacity: 0.14;
}

.pdfl-chip {
  fill: var(--edge);
}

.pdfl-stroke {
  fill: none;
  stroke: var(--edge);
  stroke-width: 2;
}

.pdfl-thick {
  stroke-width: 3;
}

.pdfl-round {
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pdfl-dash {
  stroke-dasharray: 7 6;
}

.pdfl-knob {
  fill: var(--surface-card);
}

.pdfl-marks {
  stroke-width: 3;
}

.pdfl-text {
  fill: var(--edge);
  font-family: var(--font-mono);
  font-weight: 700;
}

.pdfl-text-chip {
  fill: var(--surface-card);
}

.pdfl-photo rect {
  fill: var(--surface-strong);
}

.pdfl-sun {
  fill: var(--warning-line);
}

.pdfl-hill {
  fill: var(--line-strong);
}

.pdfl-rule {
  fill: none;
  stroke: var(--surface-card);
  stroke-width: 2;
}

/* The trailing space is what keeps the deck pinned while the last labels are read, and it
   gives the open stack a moment to stand still before the section ends. */
.pdf-layer-list {
  margin: 0;
  padding: 0 0 42vh;
  list-style: none;
  counter-reset: pdf-layer;
}

.pdf-layer-item {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  align-content: start;
  align-items: baseline;
  column-gap: 14px;
  min-height: 19vh;
  padding-block: 10px;
  counter-increment: pdf-layer;
}

.pdf-layer-mark {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border: 1px solid var(--edge);
  border-radius: var(--radius-sm);
  background: var(--tint);
  color: var(--edge);
  font-size: var(--text-xs);
  font-weight: 700;
  transform: translateY(2px);
}

.pdf-layer-mark::before {
  content: counter(pdf-layer);
}

.pdf-layer-item b {
  color: var(--text-heading);
  font-size: var(--text-lg);
}

.pdf-layer-detail {
  grid-column: 2;
  margin-top: 6px;
  max-width: 46ch;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* Only the edge and the mark change on the item a scroller has reached; the text stays at
   full strength so the list reads the same at any scroll position. */
.pdf-layer-item.is-active .pdf-layer-mark {
  border-width: 2px;
  background: var(--edge);
  color: var(--surface-card);
}

.pdf-layers-foot {
  max-width: 760px;
  margin: 0;
  padding-block: 4px 72px;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

@media (max-height: 780px) {
  .pdf-layers-stage {
    height: 470px;
  }

  .pdf-layers-deck {
    --deck-scale: 0.78;
  }
}

@media (max-width: 960px) {
  .pdf-layers-grid {
    gap: 32px;
  }

  .pdf-layers-deck {
    --deck-scale: 0.8;
  }
}

/* Phone and 200 % zoom: one column, the stack stands open above the list and nothing pins. */
@media (max-width: 860px) {
  .pdf-layers {
    padding-top: 48px;
  }

  /* Block flow, not one grid column: a grid item can only stick inside its own row, and in a
     single column that row is exactly as tall as the deck, so there is nothing to travel
     through. As ordinary siblings the deck pins and the labels scroll past it. */
  .pdf-layers-grid {
    display: block;
  }

  /* The deck pins under the site header and the labels pass beneath it, so a phone gets the
     same reading as a wide screen without the page taking over its scroll.

     It pins at 0 with the header's height as padding rather than at the header's height: the
     header is 65px under 720px wide and 73px above it, so any single offset either leaves a
     seam the labels show through or tucks the deck under the header. Starting the ground at
     the top of the viewport means no gap can open at any width. */
  .pdf-layers-visual {
    position: sticky;
    top: 0;
    z-index: 1;
    padding-top: 80px;
    padding-bottom: 8px;
    background: var(--surface-card);
    box-shadow: 0 14px 12px -12px var(--shadow-color-soft);
  }

  .pdf-layers-stage {
    position: relative;
    top: 0;
    height: 320px;
  }

  .pdf-layers-deck {
    --deck-scale: 0.66;
  }

  /* Enough run below the last label for the ninth layer to finish opening and be looked at
     before the deck unpins; without it the stack is still moving when it leaves. */
  .pdf-layer-list {
    padding-bottom: 130px;
  }

  .pdf-layer-item {
    min-height: 0;
    padding-block: 14px;
    border-top: 1px solid var(--line-soft);
  }
}

@media (max-width: 560px) {
  .pdf-layers-stage {
    height: 300px;
  }

  .pdf-layers-deck {
    --deck-scale: 0.52;
  }
}

/* Stillness means no pinning and no scroll-driven opening: the deck is a static, fully open
   stack and the labels sit under it in ordinary flow. pdf-layers.js reads the computed position
   here, so releasing the pin is all it takes to stand the script down too. */
@media (prefers-reduced-motion: reduce) {
  .pdf-layers-stage,
  .pdf-layers-visual {
    position: relative;
    top: 0;
    z-index: auto;
    padding-top: 0;
    box-shadow: none;
  }
}
