/* Metal testnet faucet — the "Technical Drawing" design system. A schematic on
   a white sheet: 1px hairlines for structure, one serif against a workhorse
   sans for hierarchy, achromatic by rule. See DESIGN.md.

   Self-hosted faces only: the nginx CSP resolves font-src to 'self', so no CDN
   and no data: URIs. The Rust binary serves these from /fonts/. */
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/instrument-serif-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Source Sans 3 Variable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/source-sans-3-latin-wght-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/geist-latin-wght-normal.woff2") format("woff2");
}

/* ── Tokens ─────────────────────────────────────────────────────────────
   One achromatic ramp — every brand token is oklch(L 0 0). The only hue on
   the page is the sanctioned status tones (emerald ok, destructive-red fail)
   on the result line. */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --primary: oklch(0 0 0);
  --primary-foreground: oklch(1 0 0);
  --border: oklch(0.922 0 0);
  --muted: oklch(0.97 0 0);
  --ring: oklch(0.708 0 0);

  /* Sanctioned semantic status tones. */
  --ok: oklch(0.52 0.13 152);
  --destructive: oklch(0.577 0.245 27.325);

  --font-heading: "Instrument Serif", Georgia, serif;
  --font-sans: "Source Sans 3 Variable", system-ui, sans-serif;
  --font-label: "Geist Variable", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
}

* {
  box-sizing: border-box;
  /* Zero radius. There is no circle carve-out on this page. */
  border-radius: 0;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* The white sheet: a centered schematic with generous margins. No card,
     no shadow, no gradient — depth is hairlines and tonal value. */
  display: flex;
  justify-content: center;
  padding: clamp(2rem, 9vh, 6rem) 1.5rem 3rem;
}

main {
  width: 100%;
  max-width: 34rem;
}

/* ── Page header — sentence-case caption, serif H1, drawn hairline. No
   uppercase eyebrow above the heading (the Annotation Rule). ── */
.page-header {
  margin-bottom: 1.75rem;
}

.caption {
  margin: 0 0 0.5rem;
  font-size: 0.9375rem;
  color: var(--muted-foreground);
}

h1 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  font-size: clamp(2.25rem, 6vw, 3rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

/* The Drawn Edge Rule: hairlines animate in by transform from a declared
   origin, never opacity. */
.rule {
  height: 1px;
  border: 0;
  margin: 0.875rem 0 0;
  background: var(--border);
}
.rule-draw {
  transform: scaleX(0);
  transform-origin: left center;
  animation: rule-draw 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 0.05s forwards;
}
@keyframes rule-draw {
  to {
    transform: scaleX(1);
  }
}

.lede {
  margin: 0 0 2rem;
  font-size: 1.05rem;
  color: var(--foreground);
  max-width: 30rem;
}

/* Figures only: monospace + tabular-nums. Token symbols are ids. */
.token,
.figure {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.token {
  font-size: 0.95em;
}

/* ── Form ── */
form {
  margin: 0;
}

/* The Annotation Rule: a Geist uppercase tracked label captioning the field. */
.label {
  display: block;
  margin-bottom: 0.5rem;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--muted-foreground);
}

.request {
  display: flex;
  gap: 0.625rem;
}

input,
select,
button {
  height: 2.75rem;
  font-size: 0.9375rem;
}

/* Square, hairline-framed input. Addresses are ids → mono tabular. */
input {
  flex: 1;
  min-width: 0;
  padding: 0 0.75rem;
  border: 1px solid var(--border);
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
input::placeholder {
  color: var(--muted-foreground);
}
input:focus-visible {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--ring) 30%, transparent);
}

/* Currency select — same hairline frame as the input; token symbols are
   figures → mono tabular. */
select {
  padding: 0 0.5rem;
  border: 1px solid var(--border);
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
select:focus-visible {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--ring) 30%, transparent);
}
/* The chromatic form state: a filled-but-invalid address flips to destructive. */
input:not(:placeholder-shown):invalid {
  border-color: var(--destructive);
}

/* Primary button — near-black fill, square, press nudge. No wipes. */
button {
  padding: 0 1.1rem;
  border: 1px solid var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
  font-family: var(--font-sans);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
button:hover {
  background: color-mix(in oklch, var(--primary) 80%, var(--background));
  border-color: color-mix(in oklch, var(--primary) 80%, var(--background));
}
button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent);
}
button:active {
  transform: translateY(1px);
}
button:disabled {
  cursor: wait;
  opacity: 0.5;
}

/* ── Result status line — muted default, semantic status tones. ── */
#result {
  margin: 1rem 0 0;
  min-height: 1.5rem;
  font-size: 0.9375rem;
  color: var(--muted-foreground);
}
#result:empty {
  margin-top: 0;
}
#result.success {
  color: var(--ok);
}
#result.error {
  color: var(--destructive);
}
#result a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── Footer meta — one hairline, a labeled figure, and nav links. ── */
.meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}
.datum {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.datum .figure {
  font-size: 0.875rem;
  color: var(--foreground);
}
nav {
  display: flex;
  gap: 1.25rem;
  font-size: 0.875rem;
}
nav a {
  color: var(--muted-foreground);
  text-decoration: none;
}
nav a:hover {
  color: var(--foreground);
  text-decoration: underline;
  text-underline-offset: 2px;
}

@media (max-width: 30rem) {
  .request {
    flex-direction: column;
  }
  input,
  select,
  button {
    width: 100%;
  }
}

/* Honor reduced motion: neutralize the drawn-edge animation, leave the rule
   at its resting full width. */
@media (prefers-reduced-motion: reduce) {
  .rule-draw {
    animation: none;
    transform: none;
  }
}
