@import url("fonts.css");

/* ==========================================================================
   DSFX — dsfx.org
   Tokens taken directly from the brand identity document. Section references
   in comments point at it.
   ========================================================================== */

:root {
  /* Palette, §05 --------------------------------------------------------- */
  --peach:        #FFD3B0;   /* Warm Peach   · gradient origin, tints        */
  --orange:       #FF7A45;   /* Sunset       · the single 5% accent          */
  --blush:        #F9BBD9;   /* Blush        · the warm/cool join            */
  --lavender:     #CBBEF5;   /* Lavender     · surfaces (never text on white)*/
  --violet:       #8A6BE8;   /* Soft Violet  · labels, mid-gradient          */
  --indigo:       #3A28C9;   /* Electric Indigo · links, the only AAA vivid  */
  --cloud:        #FBFAFC;   /* Cloud White  · default page                  */
  --mist:         #E9E7EC;   /* Mist Grey    · rules, dividers               */
  --mist-ground:  #E5E2E7;   /* the ground the light field sits on           */
  --ink:          #16141C;   /* warm-blooded black                           */

  /* Text tiers (derived from usage frequency in the brand doc) ------------ */
  --text-1: var(--ink);
  --text-2: #3D3949;
  --text-3: #5A5666;
  --text-4: #8F8B9B;
  --on-ink-1: #FFFFFF;
  --on-ink-2: rgba(255, 255, 255, 0.72);
  --on-ink-3: #8F8B9B;

  /* Rules ----------------------------------------------------------------- */
  --rule:        #E9E7EC;
  --rule-light:  #DCD8E4;
  --rule-field:  rgba(22, 20, 28, 0.22);
  --rule-on-ink: rgba(255, 255, 255, 0.18);

  /* Semantic (brand uses these consistently but never names them) ---------- */
  --ok:        #2F7D4F;
  --ok-on-ink: #8FE0B0;
  --err:       #C24545;
  --err-soft:  #E0A0A0;
  --focus:     #8A6BE8;

  /* Type ------------------------------------------------------------------ */
  --sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Motion, §12 — "Light moves. Type doesn't." ----------------------------- */
  --ease-enter: cubic-bezier(0.22, 1, 0.36, 1);
  --enter-ms:   400ms;
  --ui-ms:      200ms;
  --drift-ms:   36s;

  /* Spacing — every value a multiple of 8, §07 ----------------------------- */
  --gutter: clamp(24px, 4.4vw, 64px);
  --shell-top: clamp(24px, 3vw, 40px);

  /* The wordmark gradient, §03. Three-stop working version: the pink stop is
     dropped below ~130px, per the brand doc's own usage. */
  --x-gradient: linear-gradient(122deg, #FF8A4C, #9A7BEE 58%, #5B47E0);
  --x-gradient-reversed: linear-gradient(122deg, #FFB58C, #FF8A4C 30%, #C58BE0 68%, #8E7BF5);

  /* Phase progression, §02 — Imagine → Test → Scale ------------------------ */
  --phase-imagine: linear-gradient(90deg, #FFD3B0, #FF7A45);
  --phase-test:    linear-gradient(90deg, #FF7A45, #8A6BE8);
  --phase-scale:   linear-gradient(90deg, #8A6BE8, #3A28C9);
}

/* ==========================================================================
   Reset
   ========================================================================== */

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

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

body {
  margin: 0;
  min-height: 100%;
  background: var(--mist-ground);
  color: var(--text-1);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

a { color: var(--indigo); text-decoration: none; transition: color var(--ui-ms) var(--ease-enter); }
a:hover { color: var(--orange); }

::selection { background: var(--lavender); color: var(--ink); }
input::placeholder { color: #9A96A6; }

/* The brand book specifies no focus treatment at all. This one uses Soft
   Violet, which is a palette colour and clears 3:1 against every surface the
   site actually uses. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}
:focus:not(:focus-visible) { outline: none; }

.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;
}

.skip-link {
  position: absolute;
  top: -100px; left: 16px;
  z-index: 100;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--on-ink-1);
  font-size: 15px;
  transition: top var(--ui-ms) var(--ease-enter);
}
.skip-link:focus { top: 16px; color: var(--on-ink-1); }

/* ==========================================================================
   Page shell and the signature light field, §05
   ========================================================================== */

.shell {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  padding: var(--shell-top) var(--gutter) clamp(28px, 3vw, 48px);
  overflow: hidden;
  isolation: isolate;
}

/* Six overlapping blooms on mist. Never a linear ramp, never a hard edge —
   each bloom fades to nothing by 60% of its radius so no two colours meet at
   a boundary. Warm and cool are both present by design: the warmth is the
   humanity, the violet is the intelligence. */
.field {
  position: absolute;
  inset: -12%;
  z-index: -2;
  background:
    radial-gradient(40% 46% at 20% 26%, #CBB7F7 0%, rgba(203,183,247,0) 60%),
    radial-gradient(34% 40% at 44% 66%, #FFA974 0%, rgba(255,169,116,0) 58%),
    radial-gradient(30% 36% at 70% 26%, #F9BBD9 0%, rgba(249,187,217,0) 60%),
    radial-gradient(36% 44% at 88% 70%, #A79BF0 0%, rgba(167,155,240,0) 62%),
    radial-gradient(30% 34% at  8% 82%, #FFDFC8 0%, rgba(255,223,200,0) 60%),
    radial-gradient(50% 46% at 58%  6%, #F1EFF3 0%, rgba(241,239,243,0) 72%),
    var(--mist-ground);
  animation: drift var(--drift-ms) ease-in-out infinite;
  will-change: transform;
}

.field-lift {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(58% 44% at 8% 96%, rgba(255,255,255,0.62) 0%, rgba(255,255,255,0) 74%);
  pointer-events: none;
}

/* "Drift, don't slide" — 20–40s loops, no visible start or end, nothing
   bounces. Transform only, so it stays on the compositor. */
@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-2%, 1.5%, 0) scale(1.06); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

/* ==========================================================================
   Wordmark, §03
   ========================================================================== */

.wordmark {
  font-weight: 200;
  letter-spacing: -0.03em;
  line-height: 0.85;
  color: var(--ink);
  white-space: nowrap;
}
.wordmark .x {
  background: var(--x-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.wordmark--reversed { color: var(--on-ink-1); }
.wordmark--reversed .x { background: var(--x-gradient-reversed); -webkit-background-clip: text; background-clip: text; }

/* "As the mark gets smaller, weight goes up and tracking opens. Thin type at
   small sizes is the most common failure." §03 size ladder. */
.wordmark--sm { font-weight: 300; letter-spacing: -0.02em; }

/* ==========================================================================
   Header
   ========================================================================== */

.masthead {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.masthead__brand { display: flex; align-items: center; gap: 16px; }
.masthead__mark  { font-size: 28px; }
.masthead__divider { width: 1px; height: 22px; background: rgba(22,20,28,0.2); }
.masthead__descriptor { font-size: 14px; font-weight: 300; color: var(--text-3); letter-spacing: 0.02em; }

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}
.eyebrow--sm { font-size: 11px; letter-spacing: 0.12em; }
.eyebrow--muted { color: var(--text-4); }

/* ==========================================================================
   Main grid
   ========================================================================== */

.masthead + .main { margin-top: clamp(32px, 4vw, 56px); }

.main {
  position: relative;
  flex: 1;
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: clamp(40px, 5vw, 80px);
  align-items: center;
  padding-bottom: clamp(32px, 4vw, 56px);
}

.pitch { display: flex; flex-direction: column; gap: clamp(24px, 2.6vw, 36px); }
.pitch__intro,
.pitch__detail { display: flex; flex-direction: column; gap: clamp(24px, 2.6vw, 36px); }

/* Display, §06: 88–200 · weight 200 · tracking −35 */
.pitch__title {
  margin: 0;
  font-size: clamp(38px, 6.4vw, 88px);
  font-weight: 200;
  letter-spacing: -0.035em;
  line-height: 0.98;
  text-wrap: pretty;
}

.pitch__lede {
  font-size: clamp(18px, 1.6vw, 24px);
  line-height: 1.5;
  color: var(--text-2);
  max-width: 640px;
}

.inside { display: flex; flex-direction: column; gap: 14px; max-width: 660px; }
.inside__body { font-size: 17px; line-height: 1.6; color: var(--text-2); }
.inside__note { font-size: 15px; line-height: 1.6; color: var(--text-3); padding-top: 6px; }

/* Tags, §5e — radius full */
.tags {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  padding-top: 4px;
  margin: 0;
  padding-left: 0;
  list-style: none;
}
.tag {
  padding: 8px 16px;
  border: 1px solid var(--rule-field);
  border-radius: 999px;
  font-size: 14px;
  color: var(--text-2);
  transition: border-color var(--ui-ms) var(--ease-enter), color var(--ui-ms) var(--ease-enter);
}
.tag:hover { border-color: var(--ink); color: var(--ink); }

.stats {
  display: flex;
  gap: clamp(28px, 4vw, 56px);
  flex-wrap: wrap;
  margin: 0;
  padding-top: 28px;
  border-top: 1px solid var(--rule-field);
}
.stat { display: flex; flex-direction: column; gap: 6px; }
.stat__figure { font-size: clamp(30px, 3vw, 40px); font-weight: 200; letter-spacing: -0.03em; line-height: 1; }
.stat__label  { font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); }

/* ==========================================================================
   The ink panel
   ========================================================================== */

.panel {
  position: relative;
  background: var(--ink);
  padding: clamp(28px, 3.4vw, 48px);
  display: flex;
  flex-direction: column;
  gap: 28px;
  overflow: hidden;
}

.panel__title {
  margin: 0;
  font-size: clamp(26px, 2.4vw, 34px);
  font-weight: 200;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--on-ink-1);
}

.panel__head { display: flex; flex-direction: column; gap: 12px; }
.panel__lede { font-size: 16px; line-height: 1.55; color: var(--on-ink-2); }

.panel__foot {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.7;
  color: var(--on-ink-3);
  padding-top: 20px;
  border-top: 1px solid var(--rule-on-ink);
}

.panel__foot a { color: var(--on-ink-2); text-decoration: underline; text-underline-offset: 2px; }
.panel__foot a:hover { color: var(--peach); }

/* Panel state machine. Only one view is mounted at a time. */
.panel__view { display: flex; flex-direction: column; gap: 28px; }
.panel__view[hidden] { display: none; }

/* ==========================================================================
   Form
   ========================================================================== */

.form { display: flex; flex-direction: column; gap: 14px; }

.field-input {
  width: 100%;
  padding: 18px 20px;
  font-family: var(--sans);
  font-size: 18px;
  color: var(--on-ink-1);
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.28);
  border-radius: 0;
  outline: none;
  transition: border-color var(--ui-ms) var(--ease-enter), background-color var(--ui-ms) var(--ease-enter);
  -webkit-appearance: none;
  appearance: none;
}
.field-input:hover { border-color: rgba(255,255,255,0.42); }
.field-input:focus { border-color: var(--peach); background: rgba(255,255,255,0.12); }
.field-input:focus-visible { outline: 2px solid var(--peach); outline-offset: 2px; }
.field-input[aria-invalid="true"] { border-color: var(--err-soft); }

/* Honeypot. Off-screen rather than display:none — some form-fillers skip
   hidden fields but happily fill positioned ones. */
.trap {
  position: absolute !important;
  left: -9999px;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.consent {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 14px;
  line-height: 1.55;
  color: var(--on-ink-2);
  cursor: pointer;
  /* 44px minimum touch target, counting the label. */
  min-height: 44px;
  padding: 4px 0;
}
.consent input {
  flex: none;
  width: 20px; height: 20px;
  margin: 2px 0 0;
  accent-color: var(--orange);
  cursor: pointer;
}
.consent a { color: var(--on-ink-1); text-decoration: underline; text-underline-offset: 2px; }
.consent a:hover { color: var(--peach); }

/* --- Button ------------------------------------------------------------- */

.button {
  position: relative;
  width: 100%;
  padding: 18px 20px;
  font-family: var(--sans);
  font-size: 18px;
  font-weight: 400;
  color: var(--ink);
  background: #FFFFFF;
  border: none;
  border-radius: 0;
  cursor: pointer;
  text-align: center;
  overflow: hidden;
  transition: background-color var(--ui-ms) var(--ease-enter), color var(--ui-ms) var(--ease-enter);
}
/* The one hover state the brand actually specifies: white → Warm Peach.
   Colour only — "nothing bounces". */
.button:hover:not(:disabled) { background: var(--peach); }
.button:disabled { cursor: not-allowed; opacity: 0.55; }

.button__label { display: block; transition: opacity var(--ui-ms) var(--ease-enter); }

.button__working {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity var(--ui-ms) var(--ease-enter);
}

/* Loading: the label crosses over to a mono "sending", and the phase
   progression sweeps the lower edge. A spinner would be off-brand; the
   Imagine → Test → Scale ramp is the house language for work in progress. */
.button[data-working="true"] .button__label   { opacity: 0; }
.button[data-working="true"] .button__working { opacity: 1; }
.button[data-working="true"]::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: 40%;
  background: linear-gradient(90deg, var(--peach), var(--orange) 34%, var(--violet) 70%, var(--indigo));
  animation: sweep 1.15s var(--ease-enter) infinite;
}

@keyframes sweep {
  0%   { transform: translateX(-105%); }
  100% { transform: translateX(355%); }
}

/* --- Messages ----------------------------------------------------------- */

.notice {
  font-size: 15px;
  line-height: 1.55;
  padding-left: 14px;
  border-left: 2px solid transparent;
}
.notice:empty { display: none; }
.notice--error   { color: #FFC9C9; border-left-color: var(--err); }
.notice--warn    { color: var(--peach); border-left-color: var(--orange); }
.notice--success { color: var(--ok-on-ink); border-left-color: var(--ok); }

/* ==========================================================================
   Success view
   ========================================================================== */

.done { display: flex; flex-direction: column; gap: 24px; justify-content: center; min-height: 300px; }

.done__headline {
  margin: 0;
  font-size: clamp(42px, 4.6vw, 64px);
  font-weight: 200;
  letter-spacing: -0.04em;
  line-height: 0.92;
  background: linear-gradient(122deg, #FFB58C, #FF8A4C 30%, #C58BE0 68%, #8E7BF5);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* The only motion applied to type anywhere on the site, and §12 sanctions
     precisely this: the gradient moves, the letterforms do not. */
  animation: gradient-drift 9s ease-in-out infinite;
}

@keyframes gradient-drift {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

.done__body { font-size: 19px; line-height: 1.6; color: var(--on-ink-2); }
.done__body strong { color: var(--on-ink-1); font-weight: 400; word-break: break-word; }

/* ==========================================================================
   Footer
   ========================================================================== */

.colophon {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 32px;
  flex-wrap: wrap;
}
.colophon__line { font-size: 17px; line-height: 1.5; color: var(--text-2); max-width: 560px; }
.colophon__meta {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-3);
  text-align: right;
}
.colophon__meta a { color: var(--text-3); text-decoration: underline; text-underline-offset: 2px; }
.colophon__meta a:hover { color: var(--orange); }

/* ==========================================================================
   Standalone pages — download, privacy, errors
   ========================================================================== */

.shell--centred .centred {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(32px, 5vw, 72px) 0;
}

.panel--standalone {
  width: 100%;
  max-width: 620px;
  gap: 24px;
}

.panel__title--lg {
  font-size: clamp(32px, 3.6vw, 46px);
  letter-spacing: -0.03em;
  line-height: 1.08;
}

.panel__actions { display: flex; gap: 14px; flex-wrap: wrap; padding-top: 4px; }

/* Buttons on standalone pages follow the brand ladder — radius full, §5e.
   The landing page keeps its sharp form panel because that is the approved
   design for that page specifically. */
.pill-button {
  display: inline-block;
  padding: 15px 30px;
  border-radius: 999px;
  background: #FFFFFF;
  color: var(--ink);
  font-size: 16px;
  line-height: 1;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color var(--ui-ms) var(--ease-enter), color var(--ui-ms) var(--ease-enter);
}
.pill-button:hover { background: var(--peach); color: var(--ink); }

.pill-button--ghost {
  background: transparent;
  color: var(--on-ink-1);
  border-color: rgba(255, 255, 255, 0.3);
}
.pill-button--ghost:hover { background: rgba(255, 255, 255, 0.08); color: var(--on-ink-1); }

/* --- Progress ----------------------------------------------------------- */

.progress { display: flex; flex-direction: column; gap: 10px; }
.progress[hidden] { display: none; }

.progress__track {
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}

/* Imagine → Test → Scale, §02. The house language for work in progress. */
.progress__bar {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--peach), var(--orange) 34%, var(--violet) 70%, var(--indigo));
  transition: width 240ms var(--ease-enter);
}

.progress__meta {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--on-ink-3);
}
.progress__pct { color: var(--on-ink-1); }

/* --- Prose (privacy) ---------------------------------------------------- */

.prose { display: flex; flex-direction: column; gap: 20px; }
.prose h2 {
  margin: 20px 0 0;
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 300;
  letter-spacing: -0.015em;
  line-height: 1.25;
  color: var(--on-ink-1);
}
.prose p, .prose li { font-size: 16px; line-height: 1.65; color: var(--on-ink-2); }
.prose ul { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 8px; }
.prose a { color: var(--on-ink-1); text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--peach); }
.prose strong { color: var(--on-ink-1); font-weight: 400; }

.panel--prose { max-width: 720px; }

/* ==========================================================================
   Entrance reveals — "Fade, don't fly", §12
   opacity + 8px of travel, 400ms, cubic-bezier(0.22, 1, 0.36, 1)
   ========================================================================== */

/* Content is visible by default and only hidden once the page has positively
   confirmed it can animate it back in. Hiding by default would mean any
   scenario where the script does not run — a syntax error, a blocked asset, a
   corporate proxy stripping JavaScript — leaves a blank page. An animation is
   never worth risking the content. */
.reveal { transition: opacity var(--enter-ms) var(--ease-enter), transform var(--enter-ms) var(--ease-enter); }

.reveals .reveal { opacity: 0; transform: translateY(8px); }
.reveals .reveal.is-visible { opacity: 1; transform: none; }

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1100px) {
  .main { grid-template-columns: 1fr 0.9fr; }
}

@media (max-width: 900px) {
  .main {
    grid-template-columns: 1fr;
    align-items: start;
    gap: 40px;
  }

  /* One column, in reading order: what this is, then the form, then the
     detail. `display: contents` promotes the two pitch blocks to grid items so
     the panel can slide between them.

     The panel must not come first. On a phone that would ask for an address
     above the headline explaining what the address buys — and the long
     "what's inside" copy must not push the form off the bottom either. */
  .pitch { display: contents; }
  .pitch__intro  { order: 1; }
  .panel         { order: 2; }
  .pitch__detail { order: 3; }

  .pitch__lede { max-width: none; }
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  .masthead { gap: 12px; }
  .masthead__mark { font-size: 24px; }
  .colophon { flex-direction: column; align-items: flex-start; }
  .colophon__meta { text-align: left; }
  .stats { gap: 24px; }
}

@media (max-width: 380px) {
  .masthead__divider, .masthead__descriptor { display: none; }
}

/* ==========================================================================
   Reduced motion
   The brand book is silent on this. Everything decorative stops; nothing that
   carries information is removed.
   ========================================================================== */

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

  .field { animation: none; transform: none; }
  .done__headline { animation: none; background-position: 0 50%; }
  .reveals .reveal { opacity: 1; transform: none; }

  /* The loading bar still has a job to do, so it keeps moving — just calmly,
     and without the easing that reads as "bouncing". */
  .button[data-working="true"]::after {
    animation: sweep 2.4s linear infinite !important;
    animation-duration: 2.4s !important;
  }
}

@media print {
  .field, .field-lift, .panel { display: none; }
  body { background: #FFFFFF; }
}
