/* =========================================================
   Yarntastic — pre-launch site
   Design tenets (see PRD §5-6):
   - Silence over noise. Massive whitespace.
   - One serif for the poetry. One sans for the machinery.
   - Off-white paper. Deep ink. One accent.
   - Motion sparingly. Reduced-motion respected.
   ========================================================= */

/* Fonts: EB Garamond (serif, stand-in for GT Sectra/Freight Text)
   and Inter (sans, stand-in for Söhne/Neue Haas Grotesk).
   Both loaded from Google Fonts for zero setup. Replace with
   licensed cuts before launch. */
@import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,600;1,400&family=Inter:wght@300;400;500;600&display=swap');

/* ---------- Tokens ---------- */
:root {
  /* Palette — off-white paper, deep ink, one saturated accent.
     Accent is a deep madder-indigo pulled from a hypothetical
     hero yarn. Refresh per season. */
  --paper: #F5F1E8;
  --paper-warm: #EFE9DC;
  --ink: #1A1613;
  --ink-soft: #4A423A;
  --ink-quiet: #8A8175;
  --accent: #2B3A67;
  --accent-deep: #1F2C4F;
  --rule: rgba(26, 22, 19, 0.12);

  /* Typography */
  --serif: "EB Garamond", "Freight Text Pro", Caslon, Georgia, serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;

  /* Scale — generous, editorial */
  --step--1: clamp(0.875rem, 0.85rem + 0.15vw, 1rem);
  --step-0:  clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  --step-1:  clamp(1.125rem, 1.05rem + 0.4vw, 1.375rem);
  --step-2:  clamp(1.375rem, 1.2rem + 0.9vw, 1.875rem);
  --step-3:  clamp(1.75rem, 1.4rem + 1.75vw, 2.75rem);
  --step-4:  clamp(2.25rem, 1.6rem + 3.25vw, 4.25rem);
  --step-5:  clamp(3rem, 2rem + 5vw, 6.5rem);

  /* Space — favor larger than you think */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;
  --space-7: 9rem;
  --space-8: 12rem;

  /* Layout */
  --measure: 34rem;         /* ideal reading measure */
  --measure-wide: 52rem;    /* wider blocks */
  --page-max: 88rem;
  --gutter: clamp(1.25rem, 4vw, 3rem);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body,
h1, h2, h3, h4, h5, h6,
p, ul, ol, dl, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: 0; cursor: pointer; color: inherit; }
input { font: inherit; color: inherit; background: none; border: 0; }
input:focus, button:focus, a:focus { outline: none; }
input:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
/* The UA stylesheet's `[hidden] { display: none }` is an author-origin loss waiting to
   happen: ANY class rule that sets `display` beats it, because author declarations win
   over UA ones regardless of specificity. `.signup__form { display: flex }` did exactly
   that, so `form.hidden = true` in waitlist.js set the attribute and changed nothing —
   the email form stayed on screen through the code step and past a successful signup.
   Keep this rule, and keep the !important: without it the next `display` rule silently
   reintroduces the same bug. */
[hidden] { display: none !important; }

/* ---------- Base ---------- */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  font-family: var(--sans);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  font-feature-settings: "kern", "liga", "calt";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* ---------- Typography primitives ---------- */
.serif { font-family: var(--serif); }
.sans  { font-family: var(--sans); }

h1, h2, h3, .h1, .h2, .h3 {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.eyebrow {
  font-family: var(--sans);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: var(--space-4);
}

.lede {
  font-family: var(--serif);
  font-size: var(--step-2);
  line-height: 1.35;
  color: var(--ink);
  max-width: var(--measure-wide);
}

.body-copy p + p { margin-top: 1.25em; }

.pull {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-2);
  line-height: 1.35;
  color: var(--ink);
  max-width: var(--measure);
  margin: var(--space-5) auto;
}

hr.rule {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: var(--space-5) 0;
}

/* ---------- Layout ---------- */
.page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.wrap {
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

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

section {
  padding-top: var(--space-7);
  padding-bottom: var(--space-7);
}
@media (max-width: 640px) {
  section { padding-top: var(--space-6); padding-bottom: var(--space-6); }
}

/* ---------- Header (wordmark + minimal nav) ---------- */
.site-header {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 10;
  padding: var(--space-4) var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.site-header.static { position: static; }

.wordmark {
  font-family: var(--serif);
  font-size: var(--step-1);
  letter-spacing: -0.01em;
  color: var(--ink);
  display: block;
  line-height: 0; /* no descender gap under the logo */
}
.site-header.on-dark .wordmark,
.site-header.on-dark .site-nav a { color: var(--paper); }

/* One transparent PNG serves both header variants — no background is baked in, so it
   sits correctly on the paper mastheads and over the dark hero alike.
   The source (700x173) is already trimmed to the artwork, so it scales whole: no
   object-fit crop, or the yarn ball and the tail would lose their ends. */
.wordmark__logo {
  width: clamp(140px, 17vw, 200px);
  height: auto;
}

.site-nav {
  display: flex;
  gap: var(--space-4);
}
.site-nav a {
  font-family: var(--sans);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  padding: 0.25rem 0;
  border-bottom: 1px solid transparent;
  transition: border-color 200ms ease;
}
.site-nav a:hover { border-bottom-color: currentColor; }
.site-nav a[aria-current="page"] { border-bottom-color: currentColor; }

@media (max-width: 640px) {
  .site-nav { display: none; }
}

/* ---------- Hero (full-bleed cinematic photograph) ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding-bottom: var(--space-7);
  overflow: hidden;
  color: var(--paper);
  background: var(--ink);
}

.hero__image {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Subtle vignette so text stays legible over any real image */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.55) 0%,
    rgba(0, 0, 0, 0.15) 40%,
    rgba(0, 0, 0, 0.0) 70%
  );
  z-index: 1;
}

.hero__content {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.hero__headline {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: var(--step-5);
  line-height: 1.05;
  letter-spacing: -0.01em;
  max-width: 18ch;
  color: var(--paper);
}

.hero__sub {
  margin-top: var(--space-4);
  font-family: var(--sans);
  font-size: var(--step-1);
  line-height: 1.5;
  max-width: 38ch;
  color: rgba(245, 241, 232, 0.85);
}

.hero__cta {
  margin-top: var(--space-5);
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}

/* Phone: lift the copy off the yarn strand in the photograph.
   Two things are going on. First, the hero copy is bottom-anchored, so tightening
   the headline-to-paragraph gap on its own drops the headline instead of raising
   the paragraph — the reclaimed space has to come back as bottom offset.
   Second, the photograph is landscape and `cover` therefore crops it horizontally
   on a portrait phone: the whole image height is always visible, so the strand
   lands at a fixed FRACTION of the viewport (~59%), not a fixed pixel depth. A
   px offset would only clear it at one screen height, so the offset is expressed
   in svh — 45svh less the height of the button and its margin puts the last line
   of the paragraph a comfortable margin above the strand on any portrait phone.
   Clamped so short viewports keep a sane floor and tall ones don't drift.
   Left alone above 640px, where the strand already falls between headline and copy. */
@media (max-width: 640px) {
  .hero { padding-bottom: clamp(var(--space-6), calc(45svh - 7.5rem), 20rem); }
  .hero__sub { margin-top: var(--space-2); }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--sans);
  font-size: var(--step-0);
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 0.9rem 1.5rem;
  border: 1px solid currentColor;
  color: var(--paper);
  background: transparent;
  transition: background 200ms ease, color 200ms ease;
}
.btn:hover { background: var(--paper); color: var(--ink); }

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

.btn--accent {
  color: var(--paper);
  background: var(--accent);
  border-color: var(--accent);
}
.btn--accent:hover { background: var(--accent-deep); border-color: var(--accent-deep); }

.arrow { display: inline-block; transform: translateY(-1px); }

/* ---------- Manifesto ---------- */
.manifesto {
  background: var(--paper-warm);
  padding: var(--space-8) 0;
}
@media (max-width: 640px) {
  .manifesto { padding: var(--space-7) 0; }
}
.manifesto__body {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 var(--gutter);
  font-family: var(--serif);
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.375rem);
  line-height: 1.35;
  color: var(--ink);
}
.manifesto__body p + p { margin-top: 1.4em; }
.manifesto__body em { font-style: italic; color: var(--accent-deep); }
.manifesto__final {
  font-style: italic;
  margin-top: 1.6em !important;
}

/* ---------- Beta signup ---------- */
.signup {
  background: var(--ink);
  color: var(--paper);
  padding: var(--space-7) 0;
}
.signup__eyebrow {
  color: rgba(245, 241, 232, 0.55);
}
.signup__title {
  font-family: var(--serif);
  font-size: var(--step-3);
  line-height: 1.15;
  max-width: 22ch;
  margin-bottom: var(--space-2);
  color: var(--paper);
}
.signup__note {
  font-family: var(--sans);
  color: rgba(245, 241, 232, 0.7);
  margin-bottom: var(--space-4);
  max-width: 38ch;
}
.signup__form {
  display: flex;
  gap: 0;
  max-width: 32rem;
  border-bottom: 1px solid rgba(245, 241, 232, 0.4);
  padding-bottom: 0.75rem;
}
/* type="text", not a second email field: the six-digit code input is text so mobile
   keyboards honour inputmode="numeric" and autocomplete="one-time-code". It shares this
   rule because it replaces the email field in the same flex row — selected on
   type="email" alone it kept its intrinsic width and lost the padding, so the code step
   sat visibly narrower than the step before it. */
.signup__form input[type="email"],
.signup__form input[type="text"] {
  flex: 1;
  padding: 0.75rem 0;
  font-size: var(--step-0);
  color: var(--paper);
  background: transparent;
  border: 0;
}
.signup__form input::placeholder { color: rgba(245, 241, 232, 0.4); }
.signup__form button {
  font-family: var(--sans);
  font-size: var(--step-0);
  font-weight: 500;
  letter-spacing: 0.04em;
  padding: 0.75rem 1.25rem;
  color: var(--paper);
  border-left: 1px solid rgba(245, 241, 232, 0.25);
  transition: color 200ms ease;
}
.signup__form button:hover { color: var(--paper-warm); }
/* Submit disables during the request but the reset strips buttons of every visual cue,
   so without this "Sending your code…" leaves a button that still looks pressable. */
.signup__form button:disabled { color: rgba(245, 241, 232, 0.35); cursor: default; }
.signup__fineprint {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: rgba(245, 241, 232, 0.55);
  margin-top: var(--space-3);
  max-width: 40rem;
}
/* Joining is the one thing this page exists to do, so its confirmation must not be
   styled as fine print. The status line carries every message including the terminal
   success one; this modifier is added only for that last one, and removed on restart. */
.signup__status--done {
  font-family: var(--serif);
  font-size: var(--step-1);
  font-style: italic;
  color: var(--paper);
  margin-top: var(--space-4);
}
/* The two exits from the code step. Underlined because the global reset strips buttons
   of every visual cue — without it "Send me a new code" is dim text that happens to be
   clickable, which is how the code step became a dead end in the first place. */
.signup__actions button {
  color: rgba(245, 241, 232, 0.8);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  transition: color 200ms ease;
}
.signup__actions button:hover { color: var(--paper-warm); }
.signup__actions button[disabled] {
  opacity: 0.5;
  cursor: default;
  text-decoration: none;
}

/* ---------- Editorial section (interior pages) ---------- */
.interior-hero {
  padding: var(--space-8) 0 var(--space-5);
}
.interior-hero .eyebrow { margin-bottom: var(--space-3); }
.interior-hero h1 {
  font-size: var(--step-4);
  max-width: 20ch;
  letter-spacing: -0.01em;
}
.interior-hero .lede {
  margin-top: var(--space-3);
  color: var(--ink-soft);
}

.article {
  padding-bottom: var(--space-7);
}
.article__body {
  max-width: var(--measure);
  margin: 0 auto;
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--ink);
}
.article__body p + p { margin-top: 1.2em; }
.article__body p.drop::first-letter {
  font-family: var(--serif);
  font-weight: 500;
  float: left;
  font-size: 4.4em;
  line-height: 0.85;
  padding: 0.05em 0.15em 0 0;
  color: var(--accent-deep);
}
.article__body h2 {
  margin-top: 2em;
  font-family: var(--serif);
  font-size: var(--step-2);
  font-style: italic;
  color: var(--accent-deep);
}

/* ---------- Photos ---------- */
figure.photo {
  margin: var(--space-6) 0;
}
/* The frame holds an absolutely-positioned <img>; the background and
   aspect-ratio are what show through if that image ever fails to load. */
.photo__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  background: var(--paper-warm);
  border: 1px dashed var(--rule);
  overflow: hidden;
}
.photo__frame.tall  { aspect-ratio: 4 / 5; }
.photo__frame.wide  { aspect-ratio: 16 / 7; }
.photo__frame.square { aspect-ratio: 1 / 1; }

.photo__frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- Four moments (How It Works) ---------- */
.moments {
  padding: 0;
}
.moment {
  padding: var(--space-7) 0;
  border-top: 1px solid var(--rule);
}
.moment:first-child { border-top: 0; }
.moment__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: center;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
@media (min-width: 900px) {
  .moment__grid { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
  .moment.reverse .moment__grid > :first-child { order: 2; }
}
.moment__num {
  font-family: var(--sans);
  font-size: var(--step--1);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: var(--space-3);
}
.moment__title {
  font-family: var(--serif);
  font-size: var(--step-3);
  line-height: 1.15;
  max-width: 16ch;
  color: var(--ink);
}

/* ---------- Sellers table ---------- */
.sellers-table {
  width: 100%;
  max-width: var(--measure);
  margin: var(--space-5) auto;
  border-collapse: collapse;
  font-family: var(--sans);
}
.sellers-table th, .sellers-table td {
  padding: var(--space-2) var(--space-2);
  text-align: left;
  border-bottom: 1px solid var(--rule);
  font-size: var(--step-0);
}
.sellers-table th {
  font-weight: 500;
  color: var(--ink-quiet);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: var(--step--1);
}
.sellers-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.sellers-table tr.total td {
  font-weight: 600;
  border-top: 2px solid var(--ink);
  border-bottom: 0;
}

/* ---------- Press ---------- */
.press-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  max-width: var(--measure-wide);
  margin: 0 auto;
}
@media (min-width: 700px) {
  .press-grid { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
}
.press-block h3 {
  font-family: var(--sans);
  font-size: var(--step--1);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: var(--space-2);
}
.press-block p {
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.5;
}
.press-block a {
  color: var(--accent-deep);
  border-bottom: 1px solid var(--accent-deep);
}

/* ---------- Journal ---------- */
.journal-list {
  max-width: var(--measure-wide);
  margin: 0 auto;
}
.journal-list li {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--rule);
}
.journal-list li:last-child { border-bottom: 1px solid var(--rule); }
.journal-list .meta {
  font-family: var(--sans);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: 0.4rem;
}
.journal-list h3 {
  font-family: var(--serif);
  font-size: var(--step-2);
  line-height: 1.2;
  max-width: 32ch;
}
.journal-list h3 a { color: var(--ink); }
.journal-list h3 a:hover { color: var(--accent-deep); }

.journal-coming {
  max-width: var(--measure);
  margin: 0 auto;
  text-align: center;
  color: var(--ink-quiet);
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-1);
}

/* ---------- Footer ---------- */
.site-footer {
  margin-top: auto;
  padding: var(--space-6) 0 var(--space-5);
  border-top: 1px solid var(--rule);
  background: var(--paper);
}
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: baseline;
  justify-content: space-between;
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-quiet);
}
.site-footer a { color: var(--ink); }
.site-footer a:hover { color: var(--accent-deep); }
.site-footer .closing {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-0);
  color: var(--ink-soft);
  max-width: 32rem;
}
.site-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ---------- Utility ---------- */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}
