/* ==========================================================================
   Wriggled: wriggled.app
   Design system. Derived from SPEC-v1.md "Quick reference", web-scoped.

   Two deliberate deviations from the app spec, both already logged:
   1. Type is Nunito, not SF Pro Rounded. Apple's licence forbids SF Pro for
      website content. (DECISIONS.md, 2026-08-23)
   2. The type SCALE is enlarged for desktop web. The spec's scale is
      app-scoped; ratios and weights are preserved, absolute sizes are not.

   Accessibility constraint carried through the whole file:
   wriggle (#FF4A1C) on paper (#F2EEE4) is 2.9:1, fails AA. Therefore in
   light mode wriggle is used ONLY as: the squiggle line, and as a BUTTON
   FILL with ink (#171512) labels. Never as text on paper. Never as a link.
   ========================================================================== */

/* --- Nunito, self-hosted -------------------------------------------------
   SIL Open Font License 1.1, see /fonts/LICENSE.txt.
   Self-hosted rather than pulled from Google Fonts: no third-party request,
   nothing to block, and the CSP stays tight. */
@font-face {
  font-family: Nunito;
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url("/fonts/nunito-400.woff2") format("woff2");
}
@font-face {
  font-family: Nunito;
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url("/fonts/nunito-600.woff2") format("woff2");
}
@font-face {
  font-family: Nunito;
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url("/fonts/nunito-800.woff2") format("woff2");
}





/* --- Tokens: light is the base, defined on bare :root ---------------------- */
:root {
  --paper:      #F2EEE4;
  --paper-deep: #E6E0D2;
  --ink:        #171512;
  --ink-soft:   #6B655A;
  --wriggle:    #FF4A1C;
  --streak:     #D9A521;

  /* Secondary text sitting on --paper-deep. #6B655A on #E6E0D2 is only
     4.39:1, it fails AA. This darker step is 4.96:1 and keeps the hue. */
  --ink-soft-deep: #635D52;

  /* Derived. Hairlines are ink at low alpha so they sit in the same family. */
  --hairline:   rgba(23, 21, 18, 0.16);
  --hairline-strong: rgba(23, 21, 18, 0.28);
  --ink-on-accent: #171512;   /* 5.4:1 on wriggle, the only label colour */
  --focus:      #171512;

  /* Type */
  --font: "Nunito", ui-rounded, "SF Pro Rounded", -apple-system,
          BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  /* 4pt grid */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 20px;
  --s6: 24px; --s8: 32px; --s10: 40px; --s12: 48px; --s16: 64px;
  --s20: 80px; --s28: 112px;

  --gutter: var(--s4);
  --rhythm: var(--s6);

  /* Radii, spec values. CSS has no continuous-corner primitive; standard
     border-radius is the closest available. */
  --r-card:  14px;
  --r-sheet: 22px;
  --r-pill:  999px;
  --r-cell:  8px;

  --hair: 0.5px;

  /* Motion, cubic-bezier approximating spring(response 0.35, damping 0.8) */
  --spring: cubic-bezier(0.33, 0.9, 0.35, 1);
  --dur:    350ms;
  --dur-slow: 620ms;

  --measure: 62ch;
  --page-max: 1120px;

  color-scheme: light;
}

/* --- Dark: system preference, unless an explicit light choice overrides ---- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:      #16140F;
    --paper-deep: #201D16;
    --ink:        #EDE7DA;
    --ink-soft:   #9A9285;
    --wriggle:    #FF6338;
    --streak:     #E8B93F;
    --ink-soft-deep: #9A9285;   /* 5.46:1 on #201D16, already passes */
    --hairline:   rgba(237, 231, 218, 0.16);
    --hairline-strong: rgba(237, 231, 218, 0.30);
    --ink-on-accent: #16140F;
    --focus:      #EDE7DA;
    color-scheme: dark;
  }
}

/* --- Dark: explicit choice wins in the other direction too ---------------- */
:root[data-theme="dark"] {
  --paper:      #16140F;
  --paper-deep: #201D16;
  --ink:        #EDE7DA;
  --ink-soft:   #9A9285;
  --wriggle:    #FF6338;
  --streak:     #E8B93F;
  --ink-soft-deep: #9A9285;   /* 5.46:1 on #201D16, already passes */
  --hairline:   rgba(237, 231, 218, 0.16);
  --hairline-strong: rgba(237, 231, 218, 0.30);
  --ink-on-accent: #16140F;
  --focus:      #EDE7DA;
  color-scheme: dark;
}

/* --- Base ----------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);           /* explicit, never inherit host ground */
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

/* --- Type ----------------------------------------------------------------- */
h1, h2, h3 {
  margin: 0;
  font-weight: 800;
  letter-spacing: -0.02em;
  text-wrap: balance;
  line-height: 1.08;
}

.display {
  font-size: clamp(2.5rem, 7vw, 4.25rem);
}

h2, .title {
  font-size: clamp(1.625rem, 3.4vw, 2.25rem);
  line-height: 1.15;
}

h3, .subtitle {
  font-size: clamp(1.125rem, 2vw, 1.3125rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
}

p { margin: 0; }

.lead {
  font-size: clamp(1.125rem, 2.2vw, 1.3125rem);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: var(--measure);
}

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

.caption {
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

.micro {
  font-size: 0.875rem;
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

strong, b { font-weight: 800; }

a {
  color: var(--ink);
  text-decoration-color: var(--hairline-strong);
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1.5px;
  transition: text-decoration-color var(--dur) var(--spring);
}
a:hover { text-decoration-color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--r-cell);
}

/* --- Layout --------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--s5);
}

.section {
  padding-block: clamp(var(--s16), 9vw, var(--s28));
  border-top: var(--hair) solid var(--hairline);
}
.section:first-of-type { border-top: 0; }

.section--deep {
  background: var(--paper-deep);
  --ink-soft: var(--ink-soft-deep);   /* keeps secondary text at AA on this surface */
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--rhythm);
  align-items: flex-start;
}
.stack--tight { gap: var(--s3); }
.stack--loose { gap: var(--s10); }

/* --- Skip link ------------------------------------------------------------ */
.skip {
  position: absolute;
  left: var(--s4);
  top: var(--s4);
  transform: translateY(-200%);
  background: var(--ink);
  color: var(--paper);
  padding: var(--s2) var(--s4);
  border-radius: var(--r-pill);
  font-weight: 800;
  font-size: 0.875rem;
  text-decoration: none;
  z-index: 100;
  transition: transform var(--dur) var(--spring);
}
.skip:focus { transform: translateY(0); }

/* --- Header --------------------------------------------------------------- */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding-block: var(--s5);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-weight: 800;
  font-size: 1.125rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--ink);
}
.wordmark svg { display: block; overflow: visible; }

/* Canonical lockup. Geometry comes from brand-logo.md; never redraw these. */
.wordmark .wm-lockup { display: block; height: 17px; width: auto; overflow: visible; }
.wordmark .wm-mark { fill: var(--wriggle); transform-box: fill-box; transform-origin: center; }
.wordmark .wm-word { fill: var(--ink); }
.wordmark:hover .wm-mark { animation: wm-nudge 620ms cubic-bezier(.22,.9,.28,1); }
@keyframes wm-nudge { 40% { transform: translateY(-2px) rotate(-3deg); } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .wordmark:hover .wm-mark { animation: none; } }

.theme-toggle {
  appearance: none;
  border: var(--hair) solid var(--hairline-strong);
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0;
  padding: var(--s2) var(--s3);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background var(--dur) var(--spring), color var(--dur) var(--spring);
}
.theme-toggle:hover { background: var(--ink); color: var(--paper); }

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: var(--s3) var(--s6);
  border-radius: var(--r-pill);
  font-weight: 800;
  font-size: 1rem;
  letter-spacing: -0.01em;
  text-decoration: none;
  border: var(--hair) solid transparent;
  cursor: pointer;
  font-family: inherit;
  transition: transform var(--dur) var(--spring), background var(--dur) var(--spring);
}
.btn:active { transform: scale(0.97); }

/* Primary action is INK, not wriggle.
   Two reasons, both deliberate:
   1. SPEC-v1.md reserves wriggle for the squiggle line, the ghost overlay and
      the "your drawing" hairline, "nothing else". A button fill breaks that.
   2. wriggle on paper is 2.9:1, so an orange surface can never carry a light
      label anyway. Ink gives 15.7:1 and keeps colour where drawing happens. */
.btn--accent {
  background: var(--ink);
  color: var(--paper);
}
.btn--accent:hover { background: var(--ink-soft); color: var(--paper); }

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

/* --- The squiggle: the one place wriggle runs free ------------------------ */
.squiggle path,
.squiggle-rule path {
  fill: none;
  stroke: var(--wriggle);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.squiggle-rule {
  display: block;
  width: 100%;
  height: 40px;
  overflow: visible;
}

/* Draw-on animation, triggered by .is-drawn from IntersectionObserver */
.draw path {
  stroke-dasharray: var(--len, 1200);
  stroke-dashoffset: var(--len, 1200);
}
.draw.is-drawn path {
  transition: stroke-dashoffset var(--draw-dur, 1400ms) var(--spring);
  stroke-dashoffset: 0;
}
@media (prefers-reduced-motion: reduce) {
  .draw path { stroke-dashoffset: 0 !important; }
}

/* --- Hero ----------------------------------------------------------------- */
.hero {
  padding-block: clamp(var(--s12), 7vw, var(--s20)) clamp(var(--s16), 9vw, var(--s28));
}
.hero__inner {
  display: grid;
  gap: clamp(var(--s10), 5vw, var(--s16));
  align-items: center;
}
@media (min-width: 900px) {
  .hero__inner { grid-template-columns: 1.05fr 0.95fr; }
}

.hero__copy { display: flex; flex-direction: column; gap: var(--s6); align-items: flex-start; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }

.hero__art {
  width: 100%;
  aspect-ratio: 4 / 5;
  max-height: 62vh;
  background: var(--paper-deep);
  border: var(--hair) solid var(--hairline);
  border-radius: var(--r-sheet);
  display: grid;
  place-items: center;
  padding: var(--s6);
  overflow: hidden;
}
.hero__art svg { width: 100%; height: 100%; overflow: visible; }

/* --- The demonstration grid ---------------------------------------------- */
.demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: var(--s4);
  width: 100%;
}

.frame {
  background: var(--paper);
  border: var(--hair) solid var(--hairline);
  border-radius: var(--r-card);
  padding: var(--s4);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}
.section--deep .frame { background: var(--paper-deep); }

/* The canvas inside a frame does NOT follow the theme.
   Each drawing uses one of the app's 200 curated palettes, and every palette
   has a dark anchor (L* < 30) chosen against a paper-coloured canvas. Invert
   the canvas and those anchors vanish. So this is a picture of a drawing, and
   pictures don't invert, the canvas stays paper in both themes. */
.frame__art {
  aspect-ratio: 4 / 5;
  border-radius: var(--r-cell);
  display: grid;
  place-items: center;
  overflow: hidden;
  background: #F2EEE4;
  border: var(--hair) solid rgba(23, 21, 18, 0.12);
}
.frame__art svg { width: 100%; height: 100%; overflow: visible; }

/* --- Steps ---------------------------------------------------------------- */
.steps {
  display: grid;
  gap: var(--s8);
  width: 100%;
  counter-reset: step;
}
@media (min-width: 760px) { .steps { grid-template-columns: repeat(3, 1fr); gap: var(--s6); } }

.step {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding-top: var(--s5);
  border-top: var(--hair) solid var(--hairline-strong);
}
.step__n {
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* --- Feature list --------------------------------------------------------- */
.features {
  display: grid;
  gap: var(--s6);
  width: 100%;
}
@media (min-width: 700px) { .features { grid-template-columns: repeat(2, 1fr); gap: var(--s8) var(--s10); } }

.feature { display: flex; flex-direction: column; gap: var(--s2); }

/* --- Pricing -------------------------------------------------------------- */
.tiers {
  display: grid;
  gap: var(--s4);
  width: 100%;
}
@media (min-width: 820px) { .tiers { grid-template-columns: repeat(3, 1fr); } }

.tier {
  border: var(--hair) solid var(--hairline);
  border-radius: var(--r-card);
  padding: var(--s6);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  background: var(--paper);
}
.section--deep .tier { background: var(--paper-deep); }
/* Ink, not wriggle: wriggle on paperDeep is 2.55:1 and fails the 3:1 floor
   for a meaningful UI boundary. Ink is 13.9:1. The tier is also labelled in
   text, so the border is never the only signal. */
.tier--marked { border-color: var(--ink); border-width: 1.5px; }

.tier__price {
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.tier__price span { font-size: 0.9375rem; font-weight: 400; color: var(--ink-soft); letter-spacing: 0; }

.tier__list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--s2); }
.tier__list li { display: flex; gap: var(--s2); font-size: 0.9375rem; line-height: 1.45; }
.tier__list li::before { content: "\00B7"; color: var(--ink-soft); flex: none; }

/* --- Pledge / promise band ------------------------------------------------ */
.pledge {
  border: var(--hair) solid var(--hairline-strong);
  border-radius: var(--r-sheet);
  padding: clamp(var(--s6), 4vw, var(--s12));
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  width: 100%;
}

/* --- Prose (legal + support pages) --------------------------------------- */
.prose { max-width: var(--measure); display: flex; flex-direction: column; gap: var(--s5); }
.prose h2 { margin-top: var(--s8); }
.prose h3 { margin-top: var(--s5); }
.prose ul, .prose ol { margin: 0; padding-left: var(--s6); display: flex; flex-direction: column; gap: var(--s2); }
.prose :first-child { margin-top: 0; }

.slot {
  border: 1.5px dashed var(--hairline-strong);
  border-radius: var(--r-card);
  padding: var(--s5);
  background: var(--paper-deep);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.toc { display: flex; flex-wrap: wrap; gap: var(--s2); }
.toc a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: var(--s2) var(--s4);
  border: var(--hair) solid var(--hairline-strong);
  border-radius: var(--r-pill);
  text-decoration: none;
  font-weight: 800;
  font-size: 0.875rem;
}
.toc a:hover { background: var(--ink); color: var(--paper); }

/* --- Footer --------------------------------------------------------------- */
.footer {
  border-top: var(--hair) solid var(--hairline);
  padding-block: var(--s12) var(--s16);
}
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s8);
  justify-content: space-between;
  align-items: flex-start;
}
.footer nav { display: flex; flex-direction: column; gap: var(--s2); }
.footer nav a { font-size: 0.9375rem; text-decoration: none; color: var(--ink-soft); }
.footer nav a:hover { color: var(--ink); text-decoration: underline; }

/* --- Utility -------------------------------------------------------------- */
.vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.tabular { font-variant-numeric: tabular-nums; }


/* Utility classes replacing inline style attributes, so the Content-Security-Policy
   can keep style-src 'self' without needing 'unsafe-inline'. */
.frame--flush { margin: 0; }
.measure-34 { max-width: 34ch; }
.measure-56 { max-width: 56ch; }
.measure-64 { max-width: 64ch; }
