/* MERCHINT landing page.

   Values are copied from frontend/src/design/tokens.css rather than
   imported, because this page ships as a standalone static site to
   Cloudflare Pages and cannot reach the Next.js build. Night only: there is
   no theme switch on a one page site, and night is the working default.

   Two themes. Night is the design and sits on bare :root, so a page with no
   preference and no stored choice looks the way it was drawn. A system set to
   light gets the day palette, and an explicit toggle beats both. Every colour
   is a token: the sticky header veils and the hairlines used to be literal
   rgba values and would not have swapped.

   Day is not an inversion. The accents are darkened because #00b4d8 on white
   fails contrast at body size, and the wordmark's magenta is deepened for the
   same reason.

   Mobile first. Base rules are the phone; min-width queries add to them.

   An earlier build carried the rule "no boxes, no card grid" and set every
   section as prose in one narrow column. It read as an essay rather than as
   a business offering a service, which is the wrong first impression for the
   page a cold-email reader opens to decide whether the sender is real.
   Structure now comes from panels, a grid, and a priced card that looks like
   a price rather than a sentence. */

:root {
  --m-void: #05070a;
  --m-void-deep: #020406;
  --m-raise: #0b0f15;
  --m-raise-2: #101620;
  --m-ink: #eceae3;
  /* Measured on the report page, where these carry most of the text.
     #98a2ac read 7.4 and #646e78 read 3.88, under the 4.5 minimum, and
     --m-faint is what every field label, note, evidence key and the
     attestation use. Raised to 10.5 and 6.4. */
  --m-muted: #b6bec6;
  --m-faint: #8a939c;
  --m-accent: #00b4d8;
  --m-accent-hot: #00f5d4;
  --m-mark-bars: #00f5d4;
  --m-mark-stem: #ff006e;
  --m-hairline: rgba(154, 163, 172, 0.22);
  --m-hairline-strong: rgba(154, 163, 172, 0.4);
  --m-veil: rgba(5, 7, 10, 0.86);
  --m-on-accent: #020406;
  --m-scheme: dark;

  /* 29rem is about 70 characters at this size, which is a comfortable
     measure and, more to the point here, the width at which the running copy
     stops ending on a two-word last line. At 36rem the hero lede's final line
     filled 15 percent of the column and the who-section's filled 14. */
  --m-measure: 29rem;
  --m-shell: 68rem;
  --m-pad: 1.25rem;
  --m-radius: 3px;
}


/* Day. Applied when the system asks for light and nothing was chosen, and
   again when it was chosen explicitly, so the toggle wins in both
   directions. Not an inversion: the accents are darkened because
   #00b4d8 on white fails contrast at body size. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
  --m-void: #fcfcfb;
    --m-void-deep: #f2f3f4;
    --m-raise: #ffffff;
    --m-raise-2: #f7f8f9;
    --m-ink: #12161b;
    --m-muted: #3f4750;
    --m-faint: #5c656e;
    --m-accent: #00708f;
    --m-accent-hot: #007a6b;
    --m-mark-bars: #00806f;
    --m-mark-stem: #c4005a;
    --m-hairline: rgba(18, 22, 27, 0.14);
    --m-hairline-strong: rgba(18, 22, 27, 0.26);
    --m-veil: rgba(252, 252, 251, 0.88);
    --m-on-accent: #ffffff;
    --m-scheme: light;
  }
}

:root[data-theme="light"] {
  --m-void: #fcfcfb;
  --m-void-deep: #f2f3f4;
  --m-raise: #ffffff;
  --m-raise-2: #f7f8f9;
  --m-ink: #12161b;
  --m-muted: #3f4750;
  --m-faint: #5c656e;
  --m-accent: #00708f;
  --m-accent-hot: #007a6b;
  --m-mark-bars: #00806f;
  --m-mark-stem: #c4005a;
  --m-hairline: rgba(18, 22, 27, 0.14);
  --m-hairline-strong: rgba(18, 22, 27, 0.26);
  --m-veil: rgba(252, 252, 251, 0.88);
  --m-on-accent: #ffffff;
  --m-scheme: light;
}

:root { color-scheme: var(--m-scheme); }

/* Transitions are suppressed for one frame while the theme swaps.
   A property animated with `transition` holds its old computed value when the
   custom property behind it changes, rather than re-resolving: the button's
   background stayed #00b4d8 in day mode even though --m-accent on that same
   element read #00708f. Killing the transition for the swap re-resolves it,
   and hover still animates the rest of the time. */
:root.m-swapping *,
:root.m-swapping *::before,
:root.m-swapping *::after {
  transition: none !important;
}

:where(body, h1, h2, h3, p, ul, ol, li, figure, aside, article) {
  margin: 0;
  padding: 0;
}
:where(ul, ol) { list-style: none; }
* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  text-wrap: pretty;
  hyphens: auto;
  -webkit-hyphens: auto;
  background: var(--m-void);
  color: var(--m-ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter,
    Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--m-accent); }

/* ---------- shell ---------- */

.m-top-in,
.m-band,
.m-hero,
.m-cta-band,
.m-foot-in {
  width: 100%;
  max-width: var(--m-shell);
  margin-inline: auto;
  padding-inline: var(--m-pad);
}

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

.m-top {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--m-veil);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--m-hairline);
}

.m-top-in {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 60px;
}

.m-mark { display: block; flex: 0 0 auto; }

.m-mark-art {
  display: block;
  width: 132px;
  height: auto;
}

.m-mark-type { stroke: var(--m-ink); }
.m-mark-bars { fill: var(--m-mark-bars); }
.m-mark-stem { fill: var(--m-mark-stem); }

/* Whatever sits directly after the wordmark takes the auto margin, so the
   whole right hand group is pushed right. On the landing page that is the
   section nav; on the sample report, which has no section nav, it is the
   theme toggle. One rule, both headers, and it survives adding or removing
   the nav. Page-scoped overrides used to do this and left the sample's
   toggle and button parked against the wordmark. */
.m-top-in > .m-mark + * { margin-left: auto; }

.m-nav {
  display: none;
  gap: 1.6rem;
}

.m-nav a {
  color: var(--m-muted);
  text-decoration: none;
  font-size: 0.875rem;
}

.m-nav a:hover,
.m-nav a:focus-visible { color: var(--m-ink); }


@media (min-width: 800px) {
  .m-nav { display: flex; }
}

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

.m-btn {
  display: inline-block;
  padding: 0.8rem 1.35rem;
  border: 1px solid var(--m-accent);
  border-radius: var(--m-radius);
  background: var(--m-accent);
  color: var(--m-on-accent);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  transition: background 120ms ease, border-color 120ms ease;
}

.m-btn:hover,
.m-btn:focus-visible {
  background: var(--m-accent-hot);
  border-color: var(--m-accent-hot);
}

.m-btn-ghost {
  background: transparent;
  color: var(--m-ink);
  border-color: var(--m-hairline-strong);
}

.m-btn-ghost:hover,
.m-btn-ghost:focus-visible {
  background: transparent;
  border-color: var(--m-accent);
  color: var(--m-accent-hot);
}

.m-btn-sm {
  padding: 0.5rem 0.9rem;
  font-size: 0.85rem;
}

/* Theme toggle. Two glyphs, one shown per theme, so the control says what it
   switches to rather than what is currently on. */
.m-theme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--m-hairline-strong);
  border-radius: var(--m-radius);
  background: transparent;
  color: var(--m-muted);
  cursor: pointer;
  line-height: 1;
}

.m-theme:hover,
.m-theme:focus-visible { color: var(--m-accent-hot); border-color: var(--m-accent); }

.m-theme svg { width: 16px; height: 16px; display: block; }
.m-theme .m-sun { display: none; }
.m-theme .m-moon { display: block; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .m-theme .m-sun { display: block; }
  :root:not([data-theme="dark"]) .m-theme .m-moon { display: none; }
}

:root[data-theme="light"] .m-theme .m-sun { display: block; }
:root[data-theme="light"] .m-theme .m-moon { display: none; }

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

.m-eyebrow {
  color: var(--m-accent);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Line breaking.

   Body copy is justified, so every line but the last meets both margins.
   Justification without hyphenation opens rivers of white space in a narrow
   column, so hyphens: auto rides with it; the html element already carries
   lang="en", which is what the hyphenation dictionary needs.

   pretty stays on for the one ragged line justification leaves, the last
   one, where it prevents a single-word widow. Headings keep balance instead:
   justifying a two or three word heading stretches it across the whole
   measure, which looks broken.

   A hand-placed <br> used to do this for the h1, which hardcoded one
   viewport's line count into the markup. */
h1 {
  text-wrap: balance;
  margin-top: 0.9rem;
  font-size: clamp(2rem, 5.2vw, 3.1rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  font-weight: 650;
}

.m-h2 {
  text-wrap: balance;
  margin-top: 0.7rem;
  font-size: clamp(1.4rem, 2.6vw, 1.85rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  font-weight: 640;
  max-width: 40rem;
}

.m-lede {
  margin-top: 1.1rem;
  max-width: var(--m-measure);
  color: var(--m-muted);
  font-size: 1.05rem;
}

.m-body {
  margin-top: 1rem;
  max-width: var(--m-measure);
  color: var(--m-muted);
}

.m-center { margin-inline: auto; text-align: center; }

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

.m-hero {
  display: grid;
  gap: 2.5rem;
  padding-top: 3.25rem;
  padding-bottom: 3.5rem;
}

@media (min-width: 940px) {
  .m-hero {
    grid-template-columns: 1.15fr 0.85fr;
    gap: 3.5rem;
    align-items: start;
    padding-top: 4.5rem;
    padding-bottom: 5rem;
  }
}

.m-hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.m-center-row { justify-content: center; }

.m-hero-note {
  margin-top: 1rem;
  max-width: var(--m-measure);
  color: var(--m-faint);
  font-size: 0.9rem;
}

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

.m-card {
  padding: 1.5rem;
  border: 1px solid var(--m-hairline);
  border-radius: var(--m-radius);
  background: var(--m-raise);
}

.m-card h3 {
  text-wrap: balance;
  margin-top: 0.55rem;
  font-size: 1.02rem;
  font-weight: 630;
  letter-spacing: -0.005em;
}

.m-card p:not(.m-num):not(.m-card-tag):not(.m-price):not(.m-card-foot):not(.m-quote) {
  margin-top: 0.55rem;
  color: var(--m-muted);
  font-size: 0.94rem;
}

.m-card-tag {
  color: var(--m-faint);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.m-num {
  color: var(--m-accent);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
}

.m-card-quiet { background: transparent; border-style: dashed; }

/* The exclusion is labelled rather than numbered, so it is obviously a
   deliberate contrast and not a card whose number failed to render. */
.m-num-out {
  color: var(--m-mark-stem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* price card */

.m-card-price {
  background: linear-gradient(180deg, var(--m-raise-2), var(--m-raise));
  border-color: var(--m-hairline-strong);
  padding: 1.75rem;
}

.m-card-price h2 {
  margin-top: 0.5rem;
  font-size: 1.2rem;
  font-weight: 640;
}

.m-price {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  margin-top: 0.9rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--m-hairline);
}

.m-price-num {
  text-wrap: nowrap;
  font-size: 2.6rem;
  line-height: 1;
  font-weight: 680;
  letter-spacing: -0.03em;
}

.m-price-unit { color: var(--m-faint); font-size: 0.9rem; }

.m-ticks { margin-top: 1.1rem; display: grid; gap: 0.6rem; }

.m-ticks li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--m-muted);
  font-size: 0.93rem;
  line-height: 1.5;
}

.m-ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1.5px solid var(--m-accent-hot);
}

.m-card-foot {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--m-hairline);
  color: var(--m-faint);
  font-size: 0.86rem;
}

/* ---------- bands and grids ---------- */

.m-band {
  padding-top: 3.5rem;
  padding-bottom: 3.5rem;
  border-top: 1px solid var(--m-hairline);
}

.m-band-alt { background: var(--m-void-deep); max-width: none; }
.m-band-alt > * { max-width: var(--m-shell); margin-inline: auto; }

.m-grid { display: grid; gap: 1rem; margin-top: 2rem; }

@media (min-width: 660px) { .m-grid-2 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 660px) { .m-grid-3 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .m-grid-3 { grid-template-columns: repeat(3, 1fr); } }

.m-deny {
  padding-left: 1.15rem;
  border-left: 2px solid var(--m-mark-stem);
}

.m-deny h3 { text-wrap: balance; font-size: 1rem; font-weight: 630; }

.m-deny p {
  margin-top: 0.45rem;
  color: var(--m-muted);
  font-size: 0.94rem;
}

/* ---------- who ---------- */

.m-who { display: grid; gap: 2rem; }

@media (min-width: 940px) {
  .m-who { grid-template-columns: 1.25fr 0.75fr; gap: 3rem; align-items: start; }
}

.m-card-quote { background: var(--m-raise-2); }

.m-quote {
  margin-top: 0.7rem;
  color: var(--m-ink);
  font-size: 1rem;
  line-height: 1.55;
}

/* ---------- closing cta ---------- */

.m-cta-band {
  padding-top: 3.75rem;
  padding-bottom: 4.25rem;
  border-top: 1px solid var(--m-hairline);
  text-align: center;
}

.m-cta-band .m-h2 { margin-inline: auto; }

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

.m-foot {
  border-top: 1px solid var(--m-hairline);
  background: var(--m-void-deep);
  padding-block: 2.5rem 2rem;
  color: var(--m-faint);
  font-size: 0.88rem;
}

.m-foot-in {
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 660px) {
  .m-foot-in { grid-template-columns: 1fr auto; }
}

.m-foot a { color: var(--m-muted); text-decoration: none; }
.m-foot a:hover, .m-foot a:focus-visible { color: var(--m-accent-hot); }

.m-foot-brand {
  color: var(--m-ink);
  font-weight: 680;
  letter-spacing: 0.22em;
  font-size: 0.82rem;
}

.m-foot-legal {
  max-width: var(--m-shell);
  margin: 1.75rem auto 0;
  padding-top: 1.25rem;
  padding-inline: var(--m-pad);
  border-top: 1px solid var(--m-hairline);
  font-size: 0.8rem;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* Justification, on running copy only, and only where the measure is wide
   enough to carry it. Headings, the price, the ticked list, the nav, and the
   footer meta stay flush left at every width, because justifying a short line
   stretches three words across the whole column.

   The 600px floor is the real constraint. Justified text needs roughly sixty
   characters a line; below that the spaces stretch into rivers, and the last
   line lands wherever the words happen to fall. On a 375px screen the card
   column is about forty-five characters, and tuning the copy cannot fix it:
   wording that ends a line full at 1280px breaks somewhere else entirely at
   375px. Nine of seventeen blocks ran short there while desktop was clean.
   Ragged right is the correct setting at that measure, not a concession, and
   a ragged last line is not a runt. Hyphenation stays on at every width. */
@media (min-width: 600px) {
  .m-lede,
  .m-body,
  .m-hero-note,
  .m-quote,
  .m-deny p,
  .m-card p:not(.m-num):not(.m-card-tag):not(.m-price):not(.m-card-foot) {
    text-align: justify;
    text-justify: inter-word;
  }
}

h1, .m-h2, .m-card h3, .m-deny h3, .m-price, .m-eyebrow, .m-num, .m-card-tag {
  hyphens: manual;
  text-align: left;
}

/* The closing band centres everything. The rule above set every heading flush
   left, which left its h2 hanging off the left edge while the paragraph and
   button under it stayed centred. Justification is off here too: a justified
   paragraph inside a centred column reads as neither. */
.m-cta-band,
.m-cta-band .m-h2,
.m-cta-band .m-body,
.m-cta-band .m-hero-note {
  text-align: center;
}

.m-cta-band .m-body {
  max-width: 34rem;
  margin-inline: auto;
}
