/* ==========================================================================
   Home page only. Kept out of base.css so the rest of the site does not carry
   hero and step-list rules it never uses.
   ========================================================================== */

/* -- Hero ------------------------------------------------------------------ */

.hero {
  background:
    radial-gradient(900px 420px at 78% 8%, rgb(250 139 46 / 0.16), transparent 62%),
    radial-gradient(700px 380px at 12% 92%, rgb(240 115 107 / 0.12), transparent 60%),
    var(--ink-900);
  color: var(--ink-100);
  padding-block: var(--sp-9);
  overflow: hidden;
  position: relative;
}

/* The hero paints an opaque dark background, which would hide the body
   watermark entirely. It gets its own instead — and on black the shield
   disappears while the flame stays, so the mark reads as a glow rather than a
   gray smudge. Slightly higher opacity than the light-page watermark because
   low-contrast marks vanish faster on dark. */
.hero::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(72vw, 680px);
  height: min(72vw, 680px);
  transform: translate(-50%, -50%);
  background: var(--logo-url) no-repeat center / contain;
  /* Kept low. A brightness filter was tried at higher opacity and turned the
     mid-tones olive against the near-black hero — the mark has to stay a hint,
     not a blob competing with the headline. */
  opacity: 0.07;
  pointer-events: none;
  z-index: 0;
}

/* Keep hero content above its own watermark. */
.hero__inner {
  position: relative;
  z-index: 1;
}

/*
 * The hero is the upload, centered.
 *
 * Owner's pick on 2026-09-09 (variant A of the two prototypes; see
 * docs/archive/DESIGN-DECISIONS.md). The hero was a left-aligned column of copy with
 * two buttons; it is now a claim, a line of explanation, and the drop zone
 * itself at full width.
 *
 * The right-hand column that was removed in 2026-08-16 is not coming back, and
 * this is what finally fills the space it left. What kept landing there was a
 * fabricated price card — see the note in worker/views/home.tsx. The only
 * number that appears in this hero now is one computed from the visitor's own
 * file.
 */
.hero--upload {
  text-align: center;
}

.hero--upload .hero__lede,
.hero--upload h1 {
  margin-inline: auto;
}

.hero--upload .hero__trust {
  justify-content: center;
  margin-top: var(--sp-6);
}

.hero__eyebrow {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--flame-400);
  margin-bottom: var(--sp-4);
}

.hero h1 {
  color: var(--paper);
  margin-bottom: var(--sp-5);
}

.hero__lede {
  font-size: var(--text-lg);
  color: var(--ink-200);
  max-width: 52ch;
  margin-bottom: var(--sp-6);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}

/*
 * Scoped to the hero's OWN buttons, not to everything inside the hero.
 *
 * It was `.hero .btn--ghost`, which was correct while the hero held nothing but
 * two buttons. The hero now mounts the quote tool, whose editor sits on a white
 * card and is full of ghost buttons — the rotate and placement controls — and
 * the descendant selector turned every one of them into near-white text on
 * white. They were still there, still clickable, and effectively invisible.
 *
 * `.hero__actions` is currently empty in variant A. The rule stays because the
 * hero may take a button again, and because deleting it is how the bug comes
 * back the moment it does.
 */
.hero__actions .btn--ghost {
  border-color: var(--ink-500);
  color: var(--ink-100);
}

.hero__actions .btn--ghost:hover {
  background: var(--ink-700);
  border-color: var(--ink-400);
  color: var(--paper);
}

.hero__trust {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-5);
  font-size: var(--text-sm);
  color: var(--ink-300);
}

.hero__trust li {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.hero__trust li::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--flame-gradient);
  flex-shrink: 0;
}

/* The hero panel's styles lived here — first `.quote-demo` (the fabricated
   price card), then `.hero-card` (a spec panel that replaced it). Both are
   gone as of 2026-08-16 along with the markup; nothing on the site uses
   `.hero__panel` any more. Deleted rather than commented out, since dead CSS
   for a removed component is how the component quietly comes back. */

/* -- The quote tool, mounted in the hero ----------------------------------- */

/*
 * The same component /print renders, on a dark ground.
 *
 * Only the presentation differs — quote.css owns everything about how the tool
 * WORKS, and this file must never restate one of its rules. What is here is
 * the handful of color flips a dark background needs, plus what happens when
 * a model is actually loaded: the hero stops being a hero.
 */
.quote-tool--hero {
  margin-top: var(--sp-7);
  text-align: left;
}

/* The drop zone carries the hero, so it is bigger here and reads on dark. */
.quote-tool--hero .drop-zone {
  max-width: 46rem;
  margin-inline: auto;
  padding-block: var(--sp-8);
  text-align: center;
  border-color: var(--ink-500);
  background: rgb(20 20 24 / 0.55);
}

.quote-tool--hero .drop-zone:hover,
.quote-tool--hero .drop-zone:focus-visible,
.quote-tool--hero .drop-zone.is-over {
  border-color: var(--flame-400);
  background: rgb(20 20 24 / 0.85);
}

.quote-tool--hero .drop-zone__title {
  color: var(--paper);
}

.quote-tool--hero .drop-zone__meta {
  color: var(--ink-300);
}

/* The compacted title is ink-400 on quote.css's light page, which is legible
   there and too dim on the hero's near-black. */
.quote-tool--hero .drop-zone.is-compact .drop-zone__title {
  color: var(--ink-200);
}

.quote-tool--hero .drop-zone__privacy {
  color: var(--flame-300);
}

/*
 * Once a file is dropped, the workspace appears and the hero has done its job.
 *
 * The controller adds `is-compact` to the drop zone and unhides the workspace;
 * it knows nothing about this page. So the styling hangs off that same class,
 * which means the home page and /print stay in step without the controller
 * growing a branch for either of them.
 *
 * The panel goes onto a light card rather than inheriting the dark hero. The
 * viewer's own backdrop is a deliberate neutral gray — it exists so someone can
 * see the color they are buying — and floating light controls on near-black
 * around it looked like two different pages stitched together.
 */
/* quote.css already hides the zone's icon, meta and privacy line on
   `is-compact`. Its padding rule has to be repeated here, though, and that is
   not duplication for its own sake: `.quote-tool--hero .drop-zone` above and
   `.drop-zone.is-compact` in quote.css have the SAME specificity, and home.css
   loads second, so the hero's roomy padding would otherwise win and the zone
   would stay full height with nothing in it. */
.quote-tool--hero .drop-zone.is-compact {
  max-width: 32rem;
  padding-block: var(--sp-3);
}

/*
 * Once a model is loaded, the hero stops behaving like a hero.
 *
 * `:has()` reads the state the controller already sets on the drop zone, so
 * this needs no new class and no branch in site/src/quote/ — the controller
 * stays ignorant of which page it is on, which is what keeps / and /print from
 * drifting apart.
 *
 * Without it the headline keeps its full 6rem of padding and the editor opens
 * most of a screen below the fold, which on the page whose whole pitch is
 * "see what it costs, right here" is the wrong first impression.
 */
.hero--upload:has(.drop-zone.is-compact) {
  padding-block: var(--sp-5) var(--sp-6);
}

.hero--upload:has(.drop-zone.is-compact) h1 {
  font-size: var(--text-2xl);
  margin-bottom: var(--sp-2);
}

.hero--upload:has(.drop-zone.is-compact) .hero__lede,
.hero--upload:has(.drop-zone.is-compact) .hero__eyebrow,
.hero--upload:has(.drop-zone.is-compact) .hero__trust {
  display: none;
}

.hero--upload:has(.drop-zone.is-compact) .quote-tool--hero {
  margin-top: var(--sp-4);
}

.quote-tool--hero .quote-workspace {
  background: var(--paper);
  color: var(--ink-800);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-lg);
}

/* Headings and labels inside the workspace are dark-on-light again, because the
   workspace is a light card. Without this they inherit the hero's ink-100 and
   vanish. */
.quote-tool--hero .quote-workspace h2,
.quote-tool--hero .quote-workspace h3,
.quote-tool--hero .quote-workspace label,
.quote-tool--hero .quote-workspace dt {
  color: inherit;
}

.quote-tool--hero .quote-status {
  max-width: 46rem;
  margin-inline: auto;
}

/* The no-JavaScript fallback is a light card for the same reason. */
.quote-tool--hero .empty-state {
  background: var(--paper);
  color: var(--ink-800);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
}

/* -- Steps ----------------------------------------------------------------- */

.steps {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-6);
  counter-reset: step;
}

.step {
  position: relative;
  padding-top: var(--sp-5);
  border-top: 2px solid var(--line);
}

.step__num {
  position: absolute;
  top: -18px;
  left: 0;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--flame-gradient);
  color: var(--ink-950);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-sm);
  box-shadow: var(--shadow-flame);
}

.step h3 {
  margin: var(--sp-3) 0 var(--sp-2);
}

.step p {
  color: var(--ink-500);
  font-size: var(--text-sm);
}

/* -- Bands and splits ------------------------------------------------------ */

/* Semi-transparent rather than solid, so the fixed body watermark shows
   through instead of being masked by every alternating section. */
.band {
  background: rgb(244 244 247 / 0.72);
  border-block: 1px solid var(--line);
}

.material-split {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--sp-8);
  align-items: start;
}

@media (max-width: 860px) {
  .material-split {
    grid-template-columns: 1fr;
    gap: var(--sp-6);
  }
}

.spec-list {
  list-style: none;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.spec-list li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line);
  font-size: var(--text-sm);
}

.spec-list li:last-child {
  border-bottom: 0;
}

.spec-list li:nth-child(odd) {
  background: var(--surface);
}

.spec-list strong {
  color: var(--ink-900);
}

.spec-list span {
  color: var(--ink-500);
  text-align: right;
}

/* -- Closing CTA ----------------------------------------------------------- */

.cta {
  background: var(--ink-900);
  color: var(--ink-200);
  padding-block: var(--sp-8);
  position: relative;
  overflow: hidden;
}

.cta::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 4%;
  width: 300px;
  height: 300px;
  transform: translateY(-50%);
  background: var(--logo-url) no-repeat center / contain;
  opacity: 0.08;
  pointer-events: none;
}

.cta__inner {
  position: relative;
  z-index: 1;
}

.cta__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  align-items: center;
  justify-content: space-between;
}

.cta h2 {
  color: var(--paper);
  margin-bottom: var(--sp-2);
}
