/* ============================ THE DRAWN FIGURES ============================
   The landing's two drawn figures — the learning loop and the connected
   system (the moments and the Atlas are field.js's living scene) — in the site's own line: ink hairlines, paper
   points, honey where something returns or helps. The lines are SVG; every
   word is HTML laid over the drawing, so the words wrap and translate like
   the rest of the page. Inter explains (labels, notes, captions); Fraunces
   names (the loop's stages, the system's product names). A figure draws itself once, when it enters the viewport (visuals.js
   adds .is-in); without JavaScript, or under reduced motion, it simply
   stands complete. */
.vis { position: relative; margin: 0; width: 100%; --fs-figure: 13.5px; }
.vis__box { position: relative; width: 100%; aspect-ratio: var(--ar); }
.vis__box > svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.vis__wide { display: block; }
.vis__narrow { display: none; }
.vis figcaption { max-width: 34rem; }
/* a label sits at its point: to the right, to the left, above or below */
.vis__l { position: absolute; font: 400 var(--fs-figure)/1.3 var(--sans); color: var(--ink-2); white-space: nowrap; pointer-events: none; }
.vis__l--r { translate: 11px -50%; }
.vis__l--l { translate: calc(-100% - 11px) -50%; text-align: right; }
.vis__l--t { translate: -50% calc(-100% - 10px); text-align: center; }
.vis__l--b { translate: -50% 10px; text-align: center; }

/* --- 3. the loop: a spiral, each turn wider than the last --- */
.loop__seed { fill: var(--ink); opacity: .55; }
.loop__turn, .loop__step { stroke: var(--ink); stroke-linecap: round; fill: none; stroke-dasharray: 1; stroke-dashoffset: 0; }
.loop__turn--1 { stroke-opacity: .2; stroke-width: 1; }
.loop__turn--2 { stroke-opacity: .42; stroke-width: 1.3; }
.loop__turn--3 { stroke-opacity: .9; stroke-width: 1.7; }
.loop__step--1 { stroke-opacity: .35; stroke-width: 1; } .loop__step--2 { stroke-opacity: .48; stroke-width: 1.15; } .loop__step--3 { stroke-opacity: .6; stroke-width: 1.3; }
.loop__step--4 { stroke-opacity: .72; stroke-width: 1.45; } .loop__step--5 { stroke-opacity: .9; stroke-width: 1.7; }
.loop__return { stroke: var(--honey-deep); stroke-opacity: .6; stroke-width: 1; fill: none; }
.loop__stage { fill: var(--far); stroke: var(--ink); stroke-width: 1.6; }
.loop__l b { display: block; font: 400 clamp(20px, 1.6vw, 24px)/1.1 var(--display); letter-spacing: -.006em; color: var(--ink); }
.loop__l small { display: block; margin-top: 4px; font: 400 12.5px/1.35 var(--sans); color: var(--ink-3); white-space: normal; max-width: 150px; }
.loop__l.vis__l--l small { margin-left: auto; }
.loop__l.vis__l--t small, .loop__l.vis__l--b small { margin-inline: auto; }
.loop__again { font: italic 400 15px/1.3 var(--display); color: var(--honey-deep); }
.loop__again--n { translate: calc(-100% - 8px) -50%; white-space: normal; width: 110px; text-align: right; }

/* --- 4. the connected system: three sources, one braid, two uses, and the way back to tomorrow --- */
.sys__t { stroke: var(--ink); stroke-opacity: .4; stroke-width: 1.1; fill: none; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; }
.sys__r { stroke: var(--honey-deep); stroke-width: 1.6; fill: none; stroke-linecap: round; stroke-dasharray: .035 .965; stroke-dashoffset: 0; opacity: 0; }
.sys__return, .sys__between { stroke: var(--honey-deep); stroke-opacity: .55; stroke-width: 1; fill: none; color: var(--honey-deep); stroke-dasharray: 1; stroke-dashoffset: 0; }
.sys__g { position: absolute; width: 190px; translate: 0 -50%; }
.sys__g--atlas { width: 250px; translate: -50% -100%; text-align: center; }
.sys__g--life { width: auto; }
.sys__k { display: block; font: 500 var(--fs-label)/1 var(--sans); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-3); margin-bottom: 10px; }
.sys__g b { display: block; font: 400 clamp(19px, 1.5vw, 23px)/1.15 var(--display); letter-spacing: -.006em; color: var(--ink); }
.sys__g small { display: block; margin: 3px 0 9px; font: 400 12.5px/1.35 var(--sans); color: var(--ink-3); }
.sys__g small:last-child { margin-bottom: 0; }
.sys__g--atlas b { font-size: clamp(30px, 2.6vw, 40px); line-height: 1; }
.sys__g--atlas small { margin-top: 8px; }
.sys__life { font: italic 400 15px/1.3 var(--display); color: var(--ink-3); }
.sys__note { font: italic 400 13.5px/1.3 var(--display); color: var(--honey-deep); }

/* --- 5. the trace (the app page's continuity): one hairline that runs on, three equal moments along it --- */
.trace__line { stroke: url(#trace-fade); stroke-width: 1.1; fill: none; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; }
.trace__line--n { stroke: url(#trace-fade-n); }
.trace__pt { fill: var(--far); stroke: var(--ink); stroke-width: 1.5; }
.trace__l { white-space: normal; width: 240px; }
.trace__l b { display: block; font: 400 clamp(20px, 1.6vw, 24px)/1.1 var(--display); letter-spacing: -.006em; color: var(--ink); }
.trace__l small { display: block; margin: 8px auto 0; font: 400 13px/1.4 var(--sans); color: var(--ink-3); max-width: 220px; }
.trace__l--n { width: 250px; text-align: left; }
.trace__l--n small { margin-left: 0; max-width: 240px; }
.vis--trace { max-width: 1100px; }

/* --- the entrance (once, with motion, with JavaScript): what stands still is the finished figure --- */
.js.motion .vis[data-enter]:not(.is-in) :is(.vis__l, .loop__stage, .loop__seed, .loop__return, .sys__g, .trace__pt) { opacity: 0; }
.js.motion .vis[data-enter]:not(.is-in) :is(.loop__turn, .loop__step, .sys__t, .sys__return, .sys__between, .trace__line) { stroke-dashoffset: 1; }
.js.motion .vis.is-in :is(.vis__l, .loop__stage, .loop__seed, .loop__return, .sys__g, .trace__pt) { animation: visIn .6s ease-out both; animation-delay: var(--d, 0s); }
.js.motion .vis.is-in :is(.sys__t, .sys__return, .sys__between, .loop__step) { animation: visDraw 1.1s cubic-bezier(.3, 0, .4, 1) both; animation-delay: var(--d, 0s); }
.js.motion .vis.is-in .trace__line { animation: visDraw 2.2s cubic-bezier(.3, 0, .3, 1) both; }
.js.motion .vis.is-in .loop__turn--1 { animation: visDraw .9s linear both; }
.js.motion .vis.is-in .loop__turn--2 { animation: visDraw .9s linear both; animation-delay: .9s; }
.js.motion .vis.is-in .loop__turn--3 { animation: visDraw 1.5s cubic-bezier(.3, 0, .5, 1) both; animation-delay: 1.8s; }
.js.motion .vis.is-in .loop__return { animation-delay: 3.2s; }
/* the system's runners: one bright bead travels each thread — only while the figure is on screen */
.js.motion .vis.is-in .sys__r { opacity: .8; animation: sysRun 9s linear infinite; animation-delay: calc(var(--o, 0) * -9s); animation-play-state: paused; }
.js.motion .vis.is-in.is-visible .sys__r { animation-play-state: running; }
@keyframes visIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes visDraw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes sysRun { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* --- narrow screens: each figure has its own composition, time runs downward --- */
@media (max-width: 880px) {
  .vis { --fs-figure: 13.5px; }
  .vis__wide { display: none; }
  .vis__narrow { display: block; }
  .vis__l--r { translate: 10px -50%; }
  .vis__l--l { translate: calc(-100% - 10px) -50%; }
  .vis__l { max-width: 150px; white-space: normal; }
  .loop__l small { max-width: 120px; font-size: 12px; }
  .sys__g { width: 150px; }
  .sys__g--atlas { width: 220px; }
  .sys__g--n { width: 176px; translate: 0 0; }
  .sys__g--atlasn { width: 176px; translate: 0 -50%; text-align: left; }
  .sys__g--atlasn b { font-size: 34px; }
  .sys__g small { font-size: 12px; }
  .vis--loop, .vis--system { max-width: 30rem; margin-top: 36px; }
  .vis--trace { max-width: 24rem; margin-top: 28px; }
  .vis .trace__l--n { width: 230px; max-width: none; } /* outranks the 400px cap on .vis__l below */
  .trace__l--n b { font-size: 20px; }
}
@media (max-width: 400px) {
  .vis__l { max-width: 128px; }
  .sys__g { width: 138px; }
  .sys__g--n, .sys__g--atlasn { width: 160px; }
}
