/* components.css: reusable components (spec §9) */

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

.site-header {
  border-bottom: 1px solid var(--color-hairline);
  padding-block: var(--space-2);
  /* Opaque band so the fixed star-dust canvas does not show through. */
  background: var(--color-surface);
}

.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--space-4);
  row-gap: var(--space-1);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-family: var(--font-display);
  font-size: var(--text-md);
  letter-spacing: 0.03em;
  color: var(--color-text);
  text-decoration: none;
  margin-right: auto;
  padding-block: var(--space-1);
}

.wordmark:hover {
  color: var(--color-moon);
}

/* Small logo mark beside the wordmark: the same provisional two-circle
   motif as the favicon; its #0B0A10 tile blends into the page background. */
.wordmark__mark {
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 5px;
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
}

@media (max-width: 40rem) {
  .site-nav ul {
    gap: var(--space-2);
  }
}

.site-nav a:not(.button) {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem; /* 44px touch target */
  color: var(--color-text-secondary);
  text-decoration: none;
  font-size: var(--text-sm);
}

.site-nav a:not(.button):hover {
  color: var(--color-text);
}

/* ---- Buttons ---- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem; /* 44px touch target */
  padding: 0.625rem 1.375rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--transition),
    border-color var(--transition),
    color var(--transition),
    transform var(--transition);
}

.button:hover {
  transform: translateY(-1px);
}

.button--primary {
  background-color: var(--color-moon);
  border-color: var(--color-moon);
  color: var(--color-bg);
}

.button--primary:hover {
  background-color: var(--color-text);
  border-color: var(--color-text);
  color: var(--color-bg);
}

.button--secondary {
  background-color: transparent;
  border-color: var(--color-hairline-strong);
  color: var(--color-text);
}

.button--secondary:hover {
  border-color: var(--color-earth);
  color: var(--color-earth);
}

.button--small {
  min-height: 2.75rem;
  padding-block: 0.5rem;
}

/* Header call to action: kept prominent by colour, but set to the same
   quiet rhythm as the neighbouring nav links. */
.site-nav .button {
  padding: 0.25rem 0.9rem;
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.button[disabled] {
  opacity: 0.6;
  cursor: wait;
  transform: none;
}

/* ---- Eyebrow / metadata labels (Instrument register, used sparingly) ---- */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  /* Keep the body face even on headings: the gold label look is sans. */
  font-family: var(--font-body);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-earth);
}

.eyebrow::before {
  content: "";
  width: 2rem;
  height: 1px;
  background-color: var(--color-earth);
}

/* ---- Hero motif: two-circle construction (Earth ring + Moon sphere).
 * Owner-selected logo direction 2026-08-09, pending final brand-spec
 * sign-off (brand spec §8.2, §12). ---- */

.motif {
  display: block;
}

.motif__pair {
  transform-box: view-box;
  transform-origin: 50% 50%;
  /* The single allowed decorative transformation (spec §8.6):
   * one very slow revolution, disabled by the global reduced-motion rule. */
  animation: motif-drift 220s linear infinite;
}

/* Hero only: the CSS drift yields to scripts/motif.js, which orbits the
 * moon around the earth and adds the grab-and-launch interaction
 * (owner-approved §5.2 exception, 2026-08-09). Without JS the hero motif
 * is static; the 404/thanks motifs keep the CSS drift. */
.hero__motif .motif__pair {
  animation: none;
}

/* The orbiter is the small filled sphere (the Moon): open its disc for
 * pointer events so it can be grabbed anywhere, not just on the stroke. */
.hero__motif .motif__moon {
  cursor: grab;
  pointer-events: all;
  touch-action: none;
}

.hero__motif .motif__moon.is-grabbed {
  cursor: grabbing;
}

/* Class names follow the bodies, not the colours: the larger ring is
   Earth (quartered by the cross, ♁), the smaller filled sphere is the
   Moon. The palette mapping stays as designed. */
.motif__earth {
  fill: none;
  stroke: var(--color-moon);
  stroke-width: 1.5;
}

.motif__moon {
  fill: var(--color-warm-dark);
  stroke: var(--color-earth);
  stroke-width: 1.5;
}

.motif__cross {
  /* Same gold as the star-dust specks, at ~15% less than the old
     hairline opacity (0.14 → 0.12) so it sits further back. */
  stroke: rgba(194, 164, 109, 0.12);
  stroke-width: 1;
}

@keyframes motif-drift {
  to {
    transform: rotate(1turn);
  }
}

/* ---- Principle block ---- */

.principle {
  padding-block: var(--space-4);
}

/* Under the 56rem grid breakpoint, title and body stack; keep a small gap
   so they do not sit flush. Harmless inside the desktop grid columns. */
.principle h3 {
  margin-bottom: var(--space-1);
}

.principle-list > li + li {
  border-top: 1px solid var(--color-hairline);
}

.principle p {
  color: var(--color-text-secondary);
}

/* ---- Project card ---- */

.card {
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius);
  background-color: var(--color-surface);
  padding: var(--space-4);
}

.card__label {
  display: inline-block;
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-earth);
  margin-bottom: var(--space-2);
}

.card h3 {
  margin-bottom: var(--space-1);
}

.card p {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
}

/* ---- Forms ---- */

.field {
  margin-bottom: var(--space-3);
}

.field label {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  margin-bottom: 0.375rem;
}

.field .optional {
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}

.field input,
.field textarea {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.75rem 0.875rem;
  background-color: var(--color-surface);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius);
  color: var(--color-text);
  transition: border-color var(--transition);
}

.field input:focus,
.field textarea:focus {
  border-color: var(--color-moon);
}

.field textarea {
  min-height: 9rem;
  resize: vertical;
}

.form-status {
  margin-top: var(--space-2);
  padding: 0.875rem 1rem;
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius);
  font-size: var(--text-sm);
}

.form-status[hidden] {
  display: none;
}

/* Colour is never the only cue: messages carry explicit wording and differ in prefix */
.form-status--success {
  border-color: var(--color-earth);
  background-color: var(--color-warm-dark);
  color: var(--color-text);
}

.form-status--error {
  border-color: var(--color-moon);
  color: var(--color-text);
}

/* Fallback / notice states used until form endpoints are configured (spec §10.1 mode 3, §11) */

.notice {
  margin-top: var(--space-3);
  padding: 0.875rem 1rem;
  border: 1px dashed var(--color-hairline-strong);
  border-radius: var(--radius);
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  max-width: var(--measure);
}

.privacy-note {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* ---- Owner-input slots: visibly marked, never mistaken for published copy ---- */

.owner-slot {
  margin-block: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--color-earth);
  border-radius: var(--radius);
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  max-width: var(--measure);
}

.owner-slot::before {
  content: "To be supplied before launch";
  display: block;
  margin-bottom: 0.25rem;
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-earth);
}

.draft-banner {
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--color-earth);
  border-radius: var(--radius);
  color: var(--color-text);
  font-size: var(--text-sm);
  max-width: var(--measure);
}

.draft-banner strong {
  color: var(--color-earth);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: var(--text-xs);
  display: block;
  margin-bottom: 0.25rem;
}

/* Honeypot field (contact form): invisible to humans and assistive
   technology, tempting to bots. The Pages Function pretends success when
   it is filled. */
.field--honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

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

/* The [hidden] attribute must win over component display rules (e.g. .button
   sets display:inline-flex, which would otherwise reveal hidden elements).
   Equal specificity, placed last in the cascade. */
[hidden] {
  display: none;
}

.site-footer {
  border-top: 1px solid var(--color-hairline);
  padding-block: var(--space-5);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  /* Opaque band matching the header, so the fixed star-dust canvas
     does not show through. */
  background: var(--color-surface);
}

.footer-grid {
  display: grid;
  gap: var(--space-3);
}

.footer-statement {
  max-width: var(--measure);
}

.footer-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
}

.footer-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--color-text-secondary);
}

.footer-nav a:hover {
  color: var(--color-text);
}

.footer-meta {
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
}
