/* ==========================================================================
   Handover, homehandover.app

   The product's own identity, not a studio skin: the doorway light from the
   app icon. Deep teal ground, warm amber light, cream paper. The tokens are
   the same --ho-* set the product ships (cjb_manual/web/static/index.html),
   so the site and the app are visibly the same thing.

   Contrast rule that shaped this file: raw amber (#eda94e) measures about
   2:1 on white and is NEVER used as text on a light ground. On light grounds
   the warm accent is --amber-ink (#7d5310). Amber as text appears only on
   the deep teal grounds, where it clears AA comfortably. tools/contrast.py
   measures every pair this file actually renders.
   ========================================================================== */

:root {
  /* the doorway */
  --teal:        #123a40;
  --teal-deep:   #0c2b30;
  --teal-line:   #1d5058;
  --amber:       #eda94e;
  --amber-lift:  #ffe9c2;
  --amber-ink:   #7d5310;   /* the amber that is legible on paper */
  --cream:       #f6f1e7;
  --paper:       #ffffff;
  --ink:         #1d2a2c;
  --ink-soft:    #3d4f52;
  --ink-quiet:   #5b6f72;   /* captions and form hints, still AA on paper */
  --on-dark:     #f6f1e7;
  --on-dark-soft:#c3d4d5;

  --line:        #ddd6c6;
  --line-soft:   #e9e3d6;
  --line-dark:   rgba(246, 241, 231, 0.18);

  --ok:          #1f5c3d;
  --ok-bg:       #e6f0e8;
  --warn-bg:     #fbeed3;

  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --radius: 10px;
  --radius-lg: 16px;
  --shadow: 0 1px 2px rgba(12, 43, 48, 0.05), 0 8px 28px -14px rgba(12, 43, 48, 0.28);
  --shadow-lift: 0 18px 48px -18px rgba(12, 43, 48, 0.38);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-sans);
  /* Marketing, not an app chrome. 18px base, and nothing a visitor is meant
     to READ falls below 16px anywhere on the page. The mono eyebrows are the
     one exception, and they are tracked wide enough to stay legible. */
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; }
img { height: auto; display: block; }

a { color: var(--teal); }
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  /* Teal ring inside an amber halo: the contrast and the identity are
     carried by different parts, because an amber-only ring measures 2:1. */
  outline: 2px solid var(--teal);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(237, 169, 78, 0.45);
  border-radius: 4px;
}
.on-dark a:focus-visible,
.on-dark button:focus-visible {
  outline-color: var(--amber-lift);
  box-shadow: 0 0 0 5px rgba(18, 58, 64, 0.9);
}

.container {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--teal);
  color: var(--on-dark);
  padding: 12px 18px;
  z-index: 100;
}
.skip-link:focus { left: 12px; top: 12px; }

/* ---- type ---- */

h1, h2, h3 { font-family: var(--font-display); font-weight: 400; letter-spacing: -0.01em; }

.label {
  font-family: var(--font-mono);
  font-size: 0.78rem;   /* 14px, tracked wide: an eyebrow, still legible */
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber-ink);
  margin: 0 0 15px;
}
.on-dark .label { color: var(--amber); }

.section-headline {
  font-size: clamp(2rem, 3.8vw, 2.9rem);
  line-height: 1.12;
  margin: 0;
  color: var(--ink);
  max-width: 30ch;
  /* Balanced lines, so a headline never drops one short word onto a line of
     its own. Browsers without it fall back to ordinary wrapping, which is
     why the headlines are also written short enough not to need rescuing. */
  text-wrap: balance;
}
/* Keep a short sentence whole so a multi-sentence headline breaks between
   sentences instead of through one. Only above 900px: at phone widths a
   locked-up clause would push the page sideways, which is worse. */
@media (min-width: 900px) {
  .nb { white-space: nowrap; }
}
/* No last line left carrying one word. Same fallback story as balance. */
.section-sub,
.prose p,
.benefit p,
.card p,
.screen-cap span,
.shot figcaption,
.screens-note,
.status li,
.faq details p { text-wrap: pretty; }
.section-headline em { font-style: italic; color: var(--teal); }
.section-sub {
  font-size: 1.15rem;
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 62ch;
  margin: 20px 0 0;
}

.section { padding: 92px 0; }
.section-tight { padding: 0 0 92px; }
.section-head { margin-bottom: 44px; }

/* The header is sticky, so a nav anchor would otherwise land the top of a
   section underneath it. The bar is 66px tall; this clears it with room to
   spare, on every anchor target on the page. */
section[id],
[id="top"] { scroll-margin-top: 84px; }
.section-head.center { text-align: center; }
.section-head.center .section-headline,
.section-head.center .section-sub { margin-left: auto; margin-right: auto; }

.band-paper { background: var(--paper); border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.band-dark { background: var(--teal-deep); color: var(--on-dark); }
.band-dark .section-headline { color: var(--on-dark); }
.band-dark .section-headline em { color: var(--amber-lift); }
.band-dark .section-sub { color: var(--on-dark-soft); }

/* ---- buttons ---- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  padding: 15px 24px;
  border-radius: var(--radius);
  border: 1.5px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background 160ms var(--ease), transform 160ms var(--ease), border-color 160ms var(--ease);
}
.btn svg { width: 18px; height: 18px; flex: none; }
.btn-primary { background: var(--amber); color: var(--teal-deep); }
.btn-primary:hover { background: var(--amber-lift); }
.btn-primary:active { transform: translateY(1px); }
.btn-solid { background: var(--teal); color: var(--on-dark); }
.btn-solid:hover { background: var(--teal-deep); }
.btn-ghost-dark { background: transparent; color: var(--on-dark); border-color: var(--line-dark); }
.btn-ghost-dark:hover { border-color: var(--amber-lift); }
.btn-quiet { background: transparent; color: var(--teal); border-color: var(--line); }
.btn-quiet:hover { border-color: var(--teal); }
.btn[disabled] { opacity: 0.6; cursor: progress; }

.actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }

/* ---- header ---- */

/* Sticky, but it gets out of the way. Reading down the page, the bar used to
   sit across the middle of whatever you were looking at, which is worst
   exactly where the screenshots are. It now tucks away on the way down and
   comes straight back on the way up, so the call to action is one flick of
   the thumb away without ever covering a line of text. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--teal-deep);
  color: var(--on-dark);
  transition: transform 240ms var(--ease);
}
.site-header.tucked { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) {
  .site-header { transition: none; }
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 66px;
}
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; color: var(--on-dark); }
.brand svg { width: 22px; height: 32px; flex: none; }
.brand span { font-family: var(--font-display); font-size: 1.32rem; letter-spacing: 0.01em; }
.header-nav { display: none; gap: 22px; align-items: center; }
.header-nav a {
  color: var(--on-dark-soft);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
}
.header-nav a:hover { color: var(--amber-lift); }
.header-cta {
  font-size: 0.95rem;
  padding: 11px 17px;
}
/* The nav costs more width at the larger type, so it appears later rather
   than shrinking back under 16px. */
@media (min-width: 1060px) { .header-nav { display: flex; } }
@media (max-width: 620px) {
  /* The nav is gone at this width, so the one action stays: shrink it,
     never hide it, or the header becomes decoration. */
  .header-cta { font-size: 0.82rem; padding: 9px 13px; }
}

/* ---- hero ---- */

.hero {
  background:
    radial-gradient(1200px 620px at 50% -12%, rgba(255, 233, 194, 0.20), transparent 68%),
    var(--teal);
  color: var(--on-dark);
  padding: 76px 0 84px;
  overflow: hidden;
}
.hero-grid { display: grid; gap: 48px; align-items: center; }
@media (min-width: 920px) { .hero-grid { grid-template-columns: 1.15fr 0.85fr; gap: 64px; } }

.stamp {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--amber-lift);
  border: 1.5px solid rgba(255, 233, 194, 0.42);
  border-radius: 3px;
  padding: 7px 13px;
  margin-bottom: 24px;
}
.hero h1 {
  font-size: clamp(2.5rem, 6vw, 4rem);
  line-height: 1.06;
  margin: 0;
  max-width: 15ch;
  color: var(--on-dark);
  /* Same orphan rule as the section headlines: no line left holding one
     word. The words are Josh's, only the line breaks changed. */
  text-wrap: balance;
}
.hero h1 em { font-style: italic; color: var(--amber-lift); }
.hero p.lede {
  font-size: 1.18rem;
  line-height: 1.65;
  color: var(--on-dark-soft);
  max-width: 54ch;
  margin: 26px 0 0;
}

.plate { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.tile {
  width: 100%;
  max-width: 208px;
  aspect-ratio: 1 / 1;
  border-radius: 44px;
  overflow: hidden;
  box-shadow: 0 34px 76px -22px rgba(0, 0, 0, 0.62);
}
.tile svg { display: block; width: 100%; height: 100%; }
@media (prefers-reduced-motion: no-preference) {
  .tile { animation: float 7s ease-in-out infinite; }
  @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
}
.tile-name { font-family: var(--font-display); font-size: 1.36rem; color: var(--on-dark); }
.tile-note {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-soft);
  text-align: center;
  margin: 0;
}

.hero-rail {
  border-top: 1px solid var(--line-dark);
  margin-top: 56px;
  padding-top: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-soft);
}

/* ---- prose ----
   The old layout pinned a headline to the left of a wall of prose, which
   left half of every row empty and crowded the other half. Prose now sits
   in one column under its own headline, at a measure you can actually
   read: about 64 characters. */

.prose { max-width: 64ch; }
.prose p {
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--ink-soft);
  margin: 0 0 22px;
}
.prose p:last-child { margin-bottom: 0; }
.on-dark .prose p { color: var(--on-dark-soft); }

.ticks { list-style: none; padding: 0; margin: 22px 0 0; }
.ticks li {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 11px 0;
  font-size: 1.05rem;
  line-height: 1.62;
  color: var(--ink-soft);
}
.ticks li svg { width: 20px; height: 20px; color: var(--teal); flex: none; margin-top: 5px; }
/* Five short items read better as two balanced columns than as one long
   ladder down the left edge of an empty row. */
@media (min-width: 880px) {
  .ticks-two { columns: 2; column-gap: 56px; }
  .ticks-two li { break-inside: avoid; }
}

/* ---- the benefits band ----
   The concrete list used to sit at the bottom of a text wall as small
   bullets. It is the pitch, so it now runs immediately under the hero at
   full size. Five items: three across, then two centred, never a ragged
   hole in the grid. */

.benefits { display: flex; flex-wrap: wrap; gap: 22px; justify-content: center; }
.benefit {
  flex: 1 1 100%;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  /* Centred, with the same air on every side: the contents sit IN the box
     rather than pinned to its left edge. The three-then-two row reads as a
     decision because the pair is centred under the middle of the row above. */
  padding: 34px 30px 36px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
@media (min-width: 720px) { .benefit { flex: 0 1 calc((100% - 22px) / 2); } }
@media (min-width: 1000px) { .benefit { flex: 0 1 calc((100% - 44px) / 3); } }
/* The marks. Drawn for this product rather than pulled from an icon set:
   a white sheet of paper, teal linework, and one amber element carrying the
   doorway light in every one of them, so the five read as a family. Amber
   is decoration here and never the only edge a shape has: every amber fill
   is outlined in teal, the same reason the focus ring pairs the two. */
.mark {
  width: 80px;
  height: 80px;
  display: block;
  margin: 0 auto 20px;
}
.benefit h3 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 1.34rem;
  line-height: 1.32;
  margin: 0 0 12px;
  color: var(--ink);
  max-width: 22ch;
  text-wrap: balance;
}
.benefit p {
  font-size: 1.05rem;
  line-height: 1.62;
  color: var(--ink-soft);
  margin: 0;
  /* Centred text needs a short measure or the ragged edges fight each
     other. The copy is written to fit this, not trimmed to survive it. */
  max-width: 34ch;
}

/* ---- steps ---- */

.steps { display: grid; gap: 20px; }
@media (min-width: 780px) { .steps { grid-template-columns: repeat(3, 1fr); gap: 26px; } }
.step {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 28px 26px;
}
.step .num {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  color: var(--amber-ink);
}
.step .icon { width: 34px; height: 34px; color: var(--teal); margin: 14px 0 10px; }
.step h3 { font-size: 1.44rem; margin: 0 0 10px; color: var(--ink); }
.step p { font-size: 1.05rem; line-height: 1.62; color: var(--ink-soft); margin: 0; }

/* ---- cards ---- */

.cards { display: grid; gap: 18px; }
@media (min-width: 760px) { .cards { grid-template-columns: 1fr 1fr; gap: 22px; } }
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-left: 3px solid var(--teal);
  border-radius: var(--radius);
  padding: 25px 27px;
}
.card h3 { font-family: var(--font-sans); font-weight: 600; font-size: 1.2rem; margin: 0 0 9px; color: var(--ink); text-wrap: balance; }
.card p { font-size: 1.05rem; line-height: 1.62; color: var(--ink-soft); margin: 0; }
/* The pair under the phone screens sits centred like the benefit cards, so
   that whole stretch of the page reads as one treatment. The accent rule
   moves to the top edge: a left bar and centred text disagree. */
.card-centered {
  text-align: center;
  border-left: 1px solid var(--line);
  border-top: 3px solid var(--teal);
  padding: 28px 30px 30px;
}
.card-centered h3 { font-size: 1.28rem; margin-bottom: 11px; }
.card-centered p { max-width: 46ch; margin: 0 auto; }
.band-dark .card {
  background: rgba(246, 241, 231, 0.05);
  border-color: var(--line-dark);
  border-left-color: var(--amber);
}
.band-dark .card h3 { color: var(--on-dark); }
.band-dark .card p { color: var(--on-dark-soft); }

/* ---- screenshot frames ----
   A frame, not a fake. Every shot inside one is the real interface,
   captured from a demo home, and the caption says so. */

.shot { margin: 48px 0 0; }
.shot figcaption {
  font-size: 0.98rem;
  line-height: 1.62;
  color: var(--ink-quiet);
  margin-top: 18px;
  max-width: 68ch;
}
.band-dark .shot figcaption { color: var(--on-dark-soft); }
.shot figcaption b { color: var(--ink-soft); font-weight: 600; }
.band-dark .shot figcaption b { color: var(--on-dark); }

.window {
  border-radius: 12px;
  overflow: hidden;
  background: var(--teal-deep);
  box-shadow: var(--shadow-lift);
  border: 1px solid rgba(12, 43, 48, 0.22);
}
.window-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 14px;
  background: var(--teal-deep);
}
/* On the deep band the frame would otherwise vanish into the ground, and
   the screenshot would read as floating rather than framed. */
.band-dark .window { border-color: rgba(246, 241, 231, 0.16); }
.band-dark .window-bar { background: rgba(246, 241, 231, 0.08); }
.window-bar i { width: 9px; height: 9px; border-radius: 50%; background: rgba(246, 241, 231, 0.26); }
.window-bar span {
  margin-left: 12px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  color: var(--on-dark-soft);
}
/* A desktop interface shrunk to 327px is a texture, not a screenshot. On a
   narrow screen the shot keeps a legible width and scrolls inside its own
   frame; the page body never scrolls sideways. */
.window-body { overflow-x: auto; background: var(--paper); }
.window-body img { display: block; width: 100%; }
@media (max-width: 760px) {
  .window-body img { width: 720px; max-width: none; }
}

/* ---- the homeowner's app, three real screens ----
   Not a description of the app: the app. Each screen is the shipped
   interface photographed on a demo home, uncropped, so the space under a
   short answer is the space that is actually there. */

.screens {
  display: grid;
  gap: 40px 26px;
  justify-content: center;
  grid-template-columns: minmax(0, 260px);
}
@media (min-width: 700px) { .screens { grid-template-columns: repeat(2, minmax(0, 300px)); } }
@media (min-width: 1000px) { .screens { grid-template-columns: repeat(3, minmax(0, 340px)); } }
.screen { margin: 0; }
.phone {
  padding: 11px;
  background: var(--teal-deep);
  border-radius: 34px;
  box-shadow: var(--shadow-lift);
}
.phone img { border-radius: 24px; width: 100%; }
.screen-cap { margin: 18px 0 0; }
.screen-cap b {
  display: block;
  font-weight: 600;
  font-size: 1.08rem;
  line-height: 1.4;
  color: var(--ink);
  margin-bottom: 6px;
}
.screen-cap span {
  display: block;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.screens-note {
  font-size: 0.98rem;
  line-height: 1.62;
  color: var(--ink-quiet);
  margin: 34px 0 0;
  max-width: 68ch;
}

/* ---- status list ---- */

.status { max-width: 760px; margin: 0 auto; }
.status ul { list-style: none; padding: 0; margin: 0; }
.status li {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  padding: 20px 0;
  border-bottom: 1px solid var(--line);
  font-size: 1.1rem;
  line-height: 1.62;
  color: var(--ink-soft);
}
.status li:last-child { border-bottom: none; }
.status li b {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--amber-ink);
  flex: none;
  width: 122px;
  padding-top: 6px;
}
@media (max-width: 560px) {
  .status li { flex-direction: column; gap: 6px; }
  .status li b { width: auto; padding-top: 0; }
}

/* ---- faq ---- */

.faq { max-width: 820px; margin: 0 auto; }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none;
  cursor: pointer;
  padding: 22px 0;
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--ink);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 18px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--font-mono); color: var(--teal); font-size: 1.5rem; line-height: 1; flex: none; }
.faq details[open] summary::after { content: "\2212"; }
.faq details p { margin: 0 0 22px; color: var(--ink-soft); line-height: 1.7; font-size: 1.08rem; max-width: 68ch; }

/* ---- early access ---- */

.ea {
  background:
    radial-gradient(900px 460px at 50% -20%, rgba(255, 233, 194, 0.18), transparent 70%),
    var(--teal);
  color: var(--on-dark);
  padding: 92px 0;
}
.ea-grid { display: grid; gap: 44px; }
@media (min-width: 900px) { .ea-grid { grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; } }
.ea h2 { font-size: clamp(2rem, 4vw, 3rem); line-height: 1.1; margin: 0; color: var(--on-dark); max-width: 17ch; text-wrap: balance; }
.ea h2 em { font-style: italic; color: var(--amber-lift); }
.ea .lede { font-size: 1.15rem; line-height: 1.68; color: var(--on-dark-soft); margin: 22px 0 0; max-width: 52ch; }
.ea-mail { margin-top: 26px; font-size: 1.05rem; color: var(--on-dark-soft); }
.ea-mail a { color: var(--amber-lift); font-weight: 600; }

.ea-card {
  background: var(--paper);
  border-radius: var(--radius-lg);
  padding: 30px 28px 26px;
  box-shadow: 0 22px 54px rgba(6, 24, 26, 0.34);
  color: var(--ink);
}
/* Without JavaScript there is nowhere safe for this form to go. A plain
   submit on a static host is a GET back to this page, which would put the
   visitor's name and email address in the address bar, in their history and
   in the host's access logs. So the form exists only when the script that
   posts it does, and the address takes over when it does not. */
.ea-form-wrap { display: none; }
.js .ea-form-wrap { display: block; }
.ea-nojs { display: block; margin-top: 15px; }
.js .ea-nojs { display: none; }
.ea-nojs p { font-size: 1.05rem; line-height: 1.62; color: var(--ink-soft); margin: 0 0 14px; }
.ea-nojs p:last-child { margin-bottom: 0; }
.ea-nojs a { color: var(--teal); font-weight: 600; }

.ea-card h3 { font-family: var(--font-sans); font-weight: 600; font-size: 1.18rem; margin: 0 0 7px; }
.ea-card .hint { font-size: 0.98rem; line-height: 1.55; color: var(--ink-quiet); margin: 0 0 22px; }

.field { margin-bottom: 17px; }
.field label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 7px;
}
.field label .opt { color: var(--ink-quiet); letter-spacing: 0.06em; }
.field input, .field textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid var(--line);
  border-radius: 8px;
  padding: 12px 13px;
}
.field textarea { resize: vertical; min-height: 74px; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-quiet); }
.field input:hover, .field textarea:hover { border-color: var(--teal-line); }

/* The honeypot. Off-screen rather than display:none, because some bots skip
   what is hidden outright. No human sees it, and a filled value is refused
   by the endpoint with the same friendly response a person gets. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.ea-card .btn { width: 100%; justify-content: center; margin-top: 6px; }
.ea-note { font-size: 0.95rem; line-height: 1.6; color: var(--ink-quiet); margin: 17px 0 0; }
.ea-note a { color: var(--teal); }

.ea-msg { margin: 16px 0 0; font-size: 1.02rem; line-height: 1.6; padding: 0; }
.ea-msg:empty { display: none; }
.ea-msg.err { color: #8a2a1f; background: #fbeae7; border-radius: 8px; padding: 12px 14px; }
.ea-done {
  background: var(--ok-bg);
  border-radius: var(--radius);
  padding: 24px 24px;
  color: var(--ink);
}
.ea-done h3 { font-family: var(--font-display); font-weight: 400; font-size: 1.6rem; color: var(--ok); margin: 0 0 9px; }
.ea-done p { margin: 0; font-size: 1.05rem; line-height: 1.62; color: var(--ink-soft); }

/* ---- footer ---- */

.site-footer {
  background: var(--teal-deep);
  color: var(--on-dark-soft);
  padding: 54px 0 44px;
  font-size: 1rem;
}
.footer-top { display: flex; flex-wrap: wrap; gap: 22px 40px; align-items: center; justify-content: space-between; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 20px; }
.footer-nav a { color: var(--on-dark-soft); text-decoration: none; }
.footer-nav a:hover { color: var(--amber-lift); }
.maker {
  margin: 32px 0 0;
  padding-top: 24px;
  border-top: 1px solid var(--line-dark);
  max-width: 66ch;
  line-height: 1.66;
}
.maker a { color: var(--on-dark); }
.legal {
  margin: 20px 0 0;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--on-dark-soft);
}

/* ---- reveal ---- */

.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity 620ms var(--ease), transform 620ms var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}
