/* One world: the getfeder.com redesign preview (Nov 3, 2026).
   Every page is a place in the same garden at its own time of day. The
   nav and the scene are shared elements, so the browser can
   carry you from one place to the next (cross-document view transitions).
   Only the preview build copies this folder into the site (PUBLIC_STORY). */

@font-face { font-family: "Fraunces"; src: url("/assets/fonts/fraunces-latin.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url("/assets/fonts/ibm-plex-sans-latin.woff2") format("woff2"); font-weight: 100 700; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("/assets/fonts/jetbrains-mono-latin.woff2") format("woff2"); font-weight: 400 800; font-display: swap; }

:root {
  --ink: #0E1512; --ink2: #111A17; --ivory: #F6F3EA; --muted: #C9D2CD;
  --mint: #6FD3A6; --mint-d: #066A4B; --gold: #DCC78E; --dawn: #F7A96B;
  --amber: #E8A93B; --coral: #E5735F; --line: rgba(246,243,234,0.18);
  --serif: "Fraunces", Georgia, serif; --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --mono: "JetBrains Mono", ui-monospace, monospace;
  --soil: 60vh;          /* the soil line: the same height on every page */
  --gutter: clamp(20px, 6vw, 96px);
  --travel: 600ms;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html { background: var(--ink2); }
body { margin: 0; font-family: var(--sans); color: var(--ivory); background: var(--ink2); -webkit-font-smoothing: antialiased; }
a { color: inherit; }
img { display: block; }

/* ------------------------------------------------------------ the nav */
.nav { position: fixed; inset: 0 0 auto 0; height: 72px; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 0 var(--gutter); view-transition-name: nav; }
.nav::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(8,14,12,0.55), rgba(8,14,12,0)); pointer-events: none; }
.nav::after { content: ""; position: absolute; inset: 0; background: rgba(8,14,12,0.86); backdrop-filter: blur(14px) saturate(1.2); -webkit-backdrop-filter: blur(14px) saturate(1.2); opacity: 0; transition: opacity 240ms ease; pointer-events: none; z-index: -1; }
.scrolled .nav::after { opacity: 1; }
/* On a phone the header is solid once you scroll, so copy never reads
   through it; a hairline marks where it ends. */
@media (max-width: 720px) {
  .nav::after { background: #090F0D; backdrop-filter: none; -webkit-backdrop-filter: none; border-bottom: 1px solid rgba(246,243,234,0.08); }
}
.nav > * { position: relative; }
.brand { position: relative; font: 600 24px/1 var(--serif); text-decoration: none; }
.brand span { color: var(--mint); }
.nav ul { position: relative; display: flex; gap: clamp(16px, 2.6vw, 32px); margin: 0; padding: 0; list-style: none; font-size: 15px; }
.nav ul a { text-decoration: none; opacity: 0.86; padding-bottom: 4px; border-bottom: 2px solid transparent; }
.nav ul a:hover { opacity: 1; }
.nav ul a[aria-current="page"] { opacity: 1; border-bottom-color: var(--mint); }
/* Members sign in here, quietly beside the one mint button that is for
   new visitors (Nathanael, Nov 3). */
.nav-end { display: flex; align-items: center; gap: clamp(14px, 2vw, 24px); }
.nav-in { display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; text-decoration: none; opacity: 0.86; white-space: nowrap; }
.nav-in:hover { opacity: 1; text-decoration: underline; text-underline-offset: 4px; }
.nav-end .btn { white-space: nowrap; }
/* Tablets: the links run close to Sign in, so a hairline keeps Sign in
   reading as its own thing, not a fifth page. */
@media (min-width: 721px) and (max-width: 1099px) {
  .nav ul { gap: 18px; font-size: 14px; }
  .nav-end { gap: 16px; }
  .nav-in { font-size: 14px; padding-left: 16px; min-height: 44px; background: linear-gradient(rgba(246,243,234,0.22), rgba(246,243,234,0.22)) left center / 1px 22px no-repeat; }
  .nav .nav-end .btn { padding: 11px 18px; font-size: 14px; }
}
@media (max-width: 380px) {
  /* Fold cover screens (344): the hidden page list still took a flex gap,
     which pushed the button off the edge. Drop it and tighten the rest. */
  .nav { gap: 8px; }
  .nav > nav { display: none; }
  .brand { font-size: 22px; }
  .nav-end { gap: 10px; }
  .nav-in { font-size: 13px; }
  .nav .nav-end .btn { padding: 8px 12px; font-size: 12.5px; }
}
.st-member { margin: 0; color: var(--muted); }
.st-member a { color: var(--mint); font-weight: 600; text-underline-offset: 3px; }
.btn { position: relative; display: inline-block; padding: 12px 20px; border-radius: 999px; background: var(--mint); color: var(--ink); font-weight: 600; font-size: 15px; text-decoration: none; box-shadow: 0 8px 24px rgba(111,211,166,0.25); transition: transform 160ms ease, box-shadow 160ms ease; }
.btn:hover { transform: translateY(-1px); box-shadow: 0 12px 30px rgba(111,211,166,0.35); }
.btn:focus-visible, .nav a:focus-visible, .door:focus-visible { outline: 2px solid var(--mint); outline-offset: 3px; }
/* Skip link: off screen until a keyboard reaches it, then a mint pill at the top left. */
.skip { position: absolute; left: -9999px; top: 12px; z-index: 100; padding: 10px 16px; border-radius: 999px; background: var(--mint); color: var(--ink); font-weight: 600; font-size: 15px; text-decoration: none; }
.skip:focus, .skip:focus-visible { left: 12px; outline: 2px solid var(--ivory); outline-offset: 2px; }
.btn-lg { padding: 16px 28px; font-size: 17px; }

/* ------------------------------------------------------------ the scene */
.scene { position: fixed; inset: 0; z-index: 0; view-transition-name: scene; background: var(--ink2); }
.scene img, .scene picture { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 60%; }
.scene .shot { opacity: 0; transition: opacity 900ms ease; }
.scene .shot.on { opacity: 1; }
html.reel-on .scene .shot { transition: none; }
.scene .shot.on { z-index: 1; }
.scene .shot.under { opacity: 1; transition: none; z-index: 0; }
.scene .reel { z-index: 2; }
.scene .veil { z-index: 3; }
.scene .veil { position: absolute; inset: 0; background:
  linear-gradient(90deg, rgba(8,14,12,0.72) 0%, rgba(8,14,12,0.5) 30%, rgba(8,14,12,0.12) 52%, rgba(8,14,12,0) 64%),
  linear-gradient(180deg, rgba(8,14,12,0.42) 0%, rgba(8,14,12,0.08) 38%, rgba(8,14,12,0) 55%, rgba(8,14,12,0.35) 100%); }
/* Home opens centred on the night garden: the scrim follows the words. */
/* Nov 4: every page shares one scrim, so a walk between pages never
   swaps it; Home adds its centre pool on top, which only ever fades. */
[data-place="home"] .scene .veil::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 60% 45% at 50% 50%, rgba(8,14,12,0.4), rgba(8,14,12,0) 70%); transition: opacity 900ms ease; }
html.travelling .scene .veil::after { opacity: 0; }
@media (max-width: 720px) {
  [data-place="home"] .scene .veil::after { display: none; }
  .scene .veil, [data-place="home"] .scene .veil { background: linear-gradient(180deg, rgba(8,14,12,0.5) 0%, rgba(8,14,12,0) 13%, rgba(8,14,12,0) 32%, rgba(8,14,12,0.5) 44%, rgba(8,14,12,0.8) 100%); }
}

/* ------------------------------------------------------------ copy */
main { position: relative; z-index: 2; }
.hero { min-height: 100svh; padding: 0 var(--gutter); display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: calc(100svh - var(--soil) + 36px); }
.hero.center { align-items: center; text-align: center; }
.hero-copy { max-width: 760px; display: flex; flex-direction: column; gap: 16px; view-transition-name: copy; }
.hero.center .hero-copy { align-items: center; }
.eyebrow { font: 600 12px/1 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--mint); }
h1, h2 { margin: 0; font-family: var(--serif); font-weight: 500; letter-spacing: -0.01em; text-wrap: balance; }
h1 { font-size: clamp(40px, 6.2vw, 78px); line-height: 1.02; }
h2 { font-size: clamp(32px, 4.2vw, 52px); line-height: 1.06; }
.lead { margin: 0; font-size: clamp(17px, 1.5vw, 19px); line-height: 1.55; color: var(--muted); max-width: 620px; text-wrap: pretty; }
.small { font-size: 13px; color: var(--muted); }
.actions { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.text-shadow h1, .text-shadow h2, .text-shadow .lead { text-shadow: 0 2px 24px rgba(8,14,12,0.45); }
/* Tablets and portrait screens show the bright phone stills: the hero's small
   words keep the phone's firmer shadow at every width so they never wash out. */
.hero .lead, .hero .eyebrow { text-shadow: 0 1px 2px rgba(8,14,12,0.7), 0 2px 18px rgba(8,14,12,0.75); }

/* The panels that rise over the scene as you read on. */
.band { position: relative; padding: clamp(64px, 10vw, 120px) var(--gutter); }
.panel { max-width: 1100px; margin: 0 auto; padding: clamp(28px, 4vw, 48px); border-radius: 28px; background: rgba(14,21,18,0.72); border: 1px solid var(--line); backdrop-filter: blur(18px) saturate(1.2); -webkit-backdrop-filter: blur(18px) saturate(1.2); display: grid; gap: 22px; }
.panel.light { background: rgba(246,243,234,0.9); color: var(--ink2); border-color: rgba(17,26,23,0.08); }
.panel.light .lead, .panel.light .small { color: #3D4A44; }
.panel.light .eyebrow { color: var(--mint-d); }
.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.card { padding: 22px; border-radius: 18px; border: 1px solid var(--line); background: rgba(246,243,234,0.04); display: grid; gap: 8px; align-content: start; }
.panel.light .card { background: #fff; border-color: rgba(17,26,23,0.1); }
.card b { font: 500 22px/1.2 var(--serif); }
.card p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--muted); }
.panel.light .card p { color: #3D4A44; }
.price { font: 600 34px/1 var(--serif); }

/* What needs Nathanael's words: gold, unmistakably not final copy. */
/* Open questions for Nathanael. Clean by default: a proposed value reads as
   plain copy and a bare question is hidden. Add ?review to any /world URL
   to see every open question in place (it stays on while you browse). */
.ask { font: inherit; color: inherit; }
.ask.q { display: none; }
html.review .ask { display: inline; padding: 1px 6px; border: 1px dashed var(--gold); border-radius: 6px; background: rgba(220,199,142,0.08); }
html.review .ask::after { content: "  " attr(data-q); font: 500 11px/1.3 var(--mono); color: var(--gold); letter-spacing: 0; text-transform: none; }
html.review .ask.q::after { content: attr(data-q); }
html.review .light .ask::after, html.review .panel.light .ask::after { color: #8A6A1E; }

/* The door to the next place, at the foot of every page. */
.door { display: grid; gap: 6px; justify-items: center; text-align: center; padding: 26px; margin: 0 auto; max-width: 520px; border-radius: 22px; text-decoration: none; border: 1px solid var(--line); background: rgba(14,21,18,0.55); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: border-color 200ms ease, transform 200ms ease; }
.door:hover { border-color: var(--mint); transform: translateY(-2px); }
.door .eyebrow { color: var(--gold); }
.door b { font: 500 26px/1.15 var(--serif); }
.door span { font-size: 14px; color: var(--muted); }
footer { position: relative; z-index: 2; padding: 40px var(--gutter) 56px; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--muted); background: linear-gradient(180deg, transparent, rgba(8,14,12,0.85) 40%); }
.ft { flex-direction: column; justify-content: flex-start; gap: 10px; }
.ft-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px 24px; }
.ft-brand { color: var(--ivory); }
.ft-links { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.ft-links a { color: var(--muted); text-decoration: none; min-height: 32px; display: inline-flex; align-items: center; }
.ft-links a:hover, .ft-links a:focus-visible { color: var(--mint); }
.ft p { margin: 0; font-size: 12px; line-height: 1.5; }
.ft-preview { color: var(--gold); }

.preview-pill { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 30; padding: 8px 14px; border-radius: 999px; background: rgba(8,14,12,0.78); border: 1px solid var(--line); font: 500 12px/1 var(--mono); color: var(--gold); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); white-space: nowrap; }

/* ------------------------------------------------------------ home: one day */
.beat { min-height: 120svh; padding: 0 var(--gutter); display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: calc(100svh - var(--soil) + 36px); }
.beat .hero-copy { view-transition-name: none; }
.beat.hero { min-height: 100svh; }
.beat.below { justify-content: flex-start; padding-top: calc(var(--soil) + 48px); padding-bottom: 20svh; }
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 700ms ease, transform 700ms cubic-bezier(.2,.7,.2,1); }
.reveal.in { opacity: 1; transform: none; }

/* ------------------------------------------------------------ travel moments
   Scenic doors keep their reel.js camera move and walked arrival below.
   Ordinary arrivals fade live content: cross-document snapshots exclude
   participating links from hit testing and lose rapid pointer selections. */
@view-transition { navigation: none; }
@media (prefers-reduced-motion: no-preference) {
  html.arrive:not(.walked):not(.rm) main,
  html.arrive:not(.walked):not(.rm) footer { animation: fade-in 240ms ease-out both; }
}
:root { --vt: 360ms; }
html:active-view-transition-type(k-nav) { --vt: 420ms; }
html:active-view-transition-type(k-link) { --vt: 280ms; }
html:active-view-transition-type(k-cta) { --vt: 520ms; }
html:active-view-transition-type(k-back) { --vt: 340ms; }
::view-transition-group(*) { animation-duration: var(--vt); animation-timing-function: cubic-bezier(.22,.7,.18,1); }
::view-transition-old(scene), ::view-transition-new(scene) { animation-duration: var(--vt); animation-fill-mode: both; mix-blend-mode: normal; }
::view-transition-old(copy) { animation: fade-out 200ms ease both; }
::view-transition-new(copy) { animation: rise-in 460ms 120ms cubic-bezier(.2,.7,.2,1) both; }
html:active-view-transition-type(k-link)::view-transition-new(copy) { animation: fade-in 320ms 60ms ease both; }
html:active-view-transition-type(k-back)::view-transition-new(copy) { animation: back-in 420ms 80ms cubic-bezier(.2,.7,.2,1) both; }

@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(16px); } }
@keyframes back-in { from { opacity: 0; transform: translateX(-18px); } }

.mnav { display: none; position: fixed; left: 12px; right: 12px; bottom: 52px; z-index: 25; justify-content: space-around; padding: 2px 4px; border-radius: 16px; background: rgba(8,14,12,0.78); border: 1px solid var(--line); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); font-size: 13px; view-transition-name: mnav; }
.mnav a { text-decoration: none; opacity: 0.8; padding: 0 6px; min-height: 44px; display: inline-flex; align-items: center; }
.mnav a[aria-current="page"] { opacity: 1; color: var(--mint); }

/* Phones: the same world for less battery and data, a short crossfade. */
@media (max-width: 720px) {
  /* The scene holds the top of the screen; the words stand on the ground
     below the soil line, which the phone renders put at 38%. */
  :root { --soil: 38svh; }
  .hero, .hero.center { justify-content: flex-start; padding-top: calc(var(--soil) + 18px); padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
  .beat, .beat.below { min-height: 100svh; justify-content: flex-start; padding-top: calc(var(--soil) + 18px); padding-bottom: 14svh; }
  .hero-copy { gap: 12px; }
  .hero .lead, .hero .eyebrow { text-shadow: 0 1px 2px rgba(8,14,12,0.7), 0 2px 18px rgba(8,14,12,0.75); }
  /* Later beats scroll their words up over the sky: give them a soft glass
     backing so they stay readable over any still. */
  .beat > .hero-copy { margin: 0 -14px; padding: 20px 18px 22px; border-radius: 20px; background: rgba(8,14,12,0.58); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border: 1px solid rgba(246,243,234,0.10); }
  .nav ul { display: none; }
  .nav .btn { padding: 10px 16px; font-size: 14px; }
  .nav-end { gap: 14px; }
  .nav-in { font-size: 14px; }
  .mnav { display: flex; bottom: calc(12px + env(safe-area-inset-bottom)); }
  .preview-pill { bottom: calc(68px + env(safe-area-inset-bottom)); font-size: 11px; padding: 6px 12px; transition: opacity 240ms ease; }
  .scrolled .preview-pill { opacity: 0; pointer-events: none; }
  footer { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
  h1 { font-size: clamp(32px, 9vw, 42px); }
  .lead { font-size: 15.5px; line-height: 1.5; }
  .price { font-size: 30px; }
  .price .ask { font-size: 15px; line-height: 1.35; }
}
/* Portrait tablets (Nov 5): they load the tall stills the phones use, whose
   soil line sits at 38%. The scene keeps the top of the screen and the
   words stand on the ground below it, as on a phone, with no card. */
@media (min-width: 721px) and (max-aspect-ratio: 4/5) {
  :root { --soil: 38svh; }
  .hero, .hero.center { justify-content: flex-start; padding-top: calc(var(--soil) + 28px); padding-bottom: 12svh; }
  .hero .lead, .hero .eyebrow { color: var(--ivory); text-shadow: 0 1px 2px rgba(8,14,12,0.7), 0 2px 18px rgba(8,14,12,0.75); }
  /* The ground darkens softly under the words: a shade on the scene, not a card. */
  .hero { background: linear-gradient(to bottom, transparent calc(var(--soil) - 40px), rgba(8,14,12,0.5) calc(var(--soil) + 160px), rgba(8,14,12,0.5) 85%, transparent); }
}
@keyframes phone-in { from { opacity: 0; transform: scale(1.03); } }

/* Reduced motion: every place is its final still; travel is a quick fade. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(*), ::view-transition-new(*) { animation-name: fade-out !important; animation-duration: 150ms !important; filter: none !important; transform: none !important; clip-path: none !important; }
  ::view-transition-new(*) { animation-name: phone-in !important; }
  .scene .shot { transition: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* Round 4: the scene moves. Home scrubs rendered frames between beats;
   a door plays the walk to the next place over the whole screen. */
.scene .reel { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 160ms ease; pointer-events: none; transform-origin: 50% 60%; will-change: transform; }
.scene .reel.on { opacity: 1; transition: none; } /* on at once, fades only on the way out: scrolling back into a move, a fade-in let the still behind it (the place before the move) show for a frame (Nov 3) */
/* A walk is one move (Nathanael, Nov 3: it hard-jumped on landing). The
   page's words step aside and the scene walks under the nav, which stays put;
   the next page opens on the same frame, its words easing in in the flavor
   of the click that brought you. */
html.travelling main, html.travelling footer { opacity: 0; pointer-events: none; transition: opacity 240ms ease; }
html.travel-link main, html.travel-link footer { transition-duration: 150ms; }
html.travel-cta main, html.travel-cta footer { transition-duration: 320ms; transform: scale(0.985); transition-property: opacity, transform; }
/* Once the words have stepped aside, stop painting them: the frosted tiles
   and the drifting app rows kept re-blurring the moving scene under them
   every frame, the last 150 to 280 ms stutters on desktop walks from the
   app rows (Nov 4, round 10 walk test). */
html.travelling main, html.travelling footer { visibility: hidden; transition-property: opacity, visibility; transition-delay: 0s, 240ms; }
html.travel-link main, html.travel-link footer { transition-delay: 0s, 150ms; }
html.travel-cta main, html.travel-cta footer { transition-property: opacity, transform, visibility; transition-delay: 0s, 0s, 320ms; }
html.travelling main *, html.travelling footer * { animation-play-state: paused !important; }
/* The words get their own layer once a hand reaches for a link (and at
   idle on a desktop), so the fade at the click is the compositor's work.
   Without it, the click repainted the whole of Home's words into a new
   layer in the walk's first frames: the 130 to 200 ms stalls left on links
   from Home at 1920 (Nov 4, round 10 walk test). main is already its own
   stacking context, so nothing moves. */
html.travel-ready main, html.travel-ready footer { will-change: opacity; } /* not transform: that would pin the fixed layers inside main (Connections) to main */
/* Frosted glass re-blurs the moving scene under it every frame, the
   heaviest thing a desktop draws (Nov 4: 12 to 25 fps walks at 1920 with it,
   45 fps without). While the scene travels, the glass turns to a plain tint
   for the few frames the words take to fade, and the pill and nav bar too. */
html.travelling main *, html.travelling footer *, html.travelling .nav::after, html.travelling .preview-pill, html.travelling .mnav { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
/* The scrim holds steady through a walk (Nathanael, Nov 4: it pulsed as
   the words left and came back); only the words step aside. */
html[data-place="home"].walked .scene .veil::after { animation: veil-in 700ms ease both; }
html.walked.arrive-nav main, html.walked.arrive-nav footer { animation: walk-in 520ms 40ms cubic-bezier(.2,.7,.2,1) both; }
html.walked.arrive-link main, html.walked.arrive-link footer { animation: fade-in 320ms ease both; }
html.walked.arrive-cta main, html.walked.arrive-cta footer { animation: step-in 640ms 60ms cubic-bezier(.2,.7,.2,1) both; }
html.walked.arrive-back main, html.walked.arrive-back footer { animation: back-in 440ms cubic-bezier(.2,.7,.2,1) both; }
@keyframes veil-in { from { opacity: 0; } }
@keyframes walk-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes step-in { from { opacity: 0; transform: translateY(24px) scale(0.985); } }
/* ?motion=reduced (preview only) puts html.rm on, to walk these travel
   rules on a device that has motion on. */
html.rm::view-transition-old(*), html.rm::view-transition-new(*) { animation-name: fade-out !important; animation-duration: 150ms !important; filter: none !important; transform: none !important; clip-path: none !important; }
html.rm::view-transition-new(*) { animation-name: phone-in !important; }
@media (prefers-reduced-motion: reduce) {
  html.walked main, html.walked footer { animation: none !important; }
  html.travelling main, html.travelling footer { transition: none; transform: none; }
}

/* ------------------------------------------------------------ round 6
   Healthy roots, the same on every page: the number sits on the ring's true
   centre (JetBrains Mono's figures are measured to sit centred in a 1em
   line), the sprout rides in the space above it. --fs is the number's size,
   --gs the sprout's. */
.seed .hm-ring, .seed .ring, .hr-ring { position: relative; display: block !important; }
.seed .hm-ring > .hm-score, .seed .ring > .stack, .hr-ring > .hr-num { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); margin: 0; text-align: center; font-size: var(--fs, 32px); line-height: 1; }
.seed .hm-ring > .g, .seed .ring > .g, .hr-ring > .g { position: absolute; left: 50%; top: calc((50% - var(--fs, 32px) * 0.37) / 2 - var(--gs, 18px) / 2); width: var(--gs, 18px) !important; height: var(--gs, 18px) !important; margin: 0; translate: -50% 0; }
/* Roots flowing into Healthy roots (roots.js). */
.fr-roots { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 0; }
.fr-root path { fill: none; stroke-linecap: round; transition: stroke 400ms ease, opacity 400ms ease; }
.fr-base { stroke-width: 1.5; opacity: 0; }
.fr-root .fr-body { stroke: none; }
.fr-hair { stroke-width: 0.7; opacity: 0.4; }
.fr-tip { opacity: 0.9; filter: drop-shadow(0 0 3px currentColor); transition: opacity 400ms ease; }
.fr-flow { stroke: #F6F3EA; stroke-width: 2; stroke-dasharray: 3 97; stroke-dashoffset: 3; opacity: 0; animation: fr-flow 3.4s linear infinite; filter: drop-shadow(0 0 4px rgba(111,211,166,0.85)); }
/* Out of Healthy roots: the pulse leaves the seed and runs out to each signal. */
@keyframes fr-flow { 0% { stroke-dashoffset: 3; opacity: 0; } 14% { opacity: 0.8; } 80% { opacity: 0.8; } 100% { stroke-dashoffset: 100; opacity: 0; } }
/* A root that breaks goes coral and quiet: no pulse reaches the seed. */
.fr-broken .fr-base, .fr-broken .fr-hair { stroke: var(--coral) !important; stroke-dasharray: 3 4; }
.fr-broken .fr-base { opacity: 1; }
.fr-broken .fr-body, .fr-broken .fr-tip { opacity: 0; }
.fr-broken .fr-flow { animation: none; opacity: 0; }
@media (prefers-reduced-motion: reduce) { .fr-flow { display: none; } }

/* Round 6: a real soil medium under every root, drawn from noise (crumb,
   dark clods and pale grit) over the earth's own colour, so roots run
   through earth, not a flat brown fill. */
:root { --soil-crumb: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='c' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 0.86  0 0 0 0 0.74  0 0 0 0 0.55  0 0 0 2.2 -1.25'/%3E%3C/filter%3E%3Cfilter id='k' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.045' numOctaves='4' seed='3'/%3E%3CfeColorMatrix values='0 0 0 0 0.05  0 0 0 0 0.03  0 0 0 0 0.02  0 0 0 2.4 -1.05'/%3E%3C/filter%3E%3Cfilter id='g' x='0' y='0'%3E%3CfeTurbulence type='turbulence' baseFrequency='0.35' numOctaves='1' seed='11'/%3E%3CfeColorMatrix values='0 0 0 0 0.93  0 0 0 0 0.88  0 0 0 0 0.76  0 0 0 9 -7.6'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url%28%23k%29'/%3E%3Crect width='240' height='240' filter='url%28%23c%29' opacity='0.55'/%3E%3Crect width='240' height='240' filter='url%28%23g%29' opacity='0.5'/%3E%3C/svg%3E"); }
.soil-tex { background: linear-gradient(180deg, rgba(18,13,8,0.05) 0%, rgba(18,13,8,0.5) 78%, rgba(18,13,8,0.62) 100%), var(--soil-crumb) 0 0 / 240px 240px, radial-gradient(120% 70% at 30% 20%, rgba(92,68,42,0.55), transparent 60%), radial-gradient(90% 60% at 80% 70%, rgba(20,14,9,0.6), transparent 70%), linear-gradient(180deg, #3D2E1F 0%, #2B2117 55%, #18120C 100%) !important; }

/* Real time (clock.js): a day or time stays hidden until the visitor's own
   clock has set it, so no page ever paints a stale day. */
[data-clock]:not([data-set]) { visibility: hidden; }

/* Money is second (Nathanael, Nov 4): Healthy roots first, Money next, then the rest.
   Money sits beside the seed and reads a step above the others: a slightly larger ring in its own
   colour with a soft glow and a heavier name. Never ivory; that stays Healthy roots' alone. */
.hm-s-money .hm-ring, .s-money .ring, .hm-p.hm-s-money .hm-ring { scale: 1.14; box-shadow: 0 0 0 6px rgba(255,255,255,0.03), 0 0 18px color-mix(in srgb, var(--c) 32%, transparent); }
.hm-s-money .hm-name, .s-money .sig-n, .hm-p.hm-s-money .hm-name, .pick.s-money span, .phone-sigs .s-money span, .brk-sig.s-money .brk-sig-n { font-weight: 600; }
.pick.s-money, .phone-sigs .s-money, .brk-sig.s-money { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c, #6E8FE0) 34%, transparent); }

/* Review mode: how the last walk went (world.js). */
.walk-log { position: fixed; left: 12px; bottom: 12px; z-index: 40; max-width: calc(100vw - 24px); padding: 6px 10px; border-radius: 10px; background: rgba(8,14,12,0.86); border: 1px solid var(--line); font: 11px/1.4 var(--mono); color: var(--cream, #F6F3EA); pointer-events: none; }

/* Consent pill (owner, 2026-11-05), the same pill as public/assets/css/site.css:
   frosted glass in the night palette, pinned bottom-left on every world page
   at every scroll position, a cookie lit by the moon glow. Markup and gating
   come from consent.js. On phones it sits above the places bar, and while it
   shows, the preview label steps aside so the two never overlap. */
.consent-banner {
  --cp-ink: #EEF6F1; --cp-ink-2: rgba(238, 246, 241, .74);
  --cp-mint: #6FD3A6; --cp-mint-ink: #0B2A1E; --cp-line: rgba(238, 246, 241, .16);
  position: fixed; left: 16px; bottom: 16px; right: auto; z-index: 90;
  width: max-content; max-width: calc(100% - 32px);
  border-radius: 999px; color: var(--cp-ink);
  background: linear-gradient(180deg, rgba(30, 58, 47, .70), rgba(9, 27, 21, .78));
  border: 1px solid var(--cp-line);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .65), inset 0 1px 0 rgba(255, 255, 255, .10);
  -webkit-backdrop-filter: blur(16px) saturate(140%); backdrop-filter: blur(16px) saturate(140%);
}
.consent-banner[hidden] { display: none; }
.consent-banner:has(.consent-details:not([hidden])) { border-radius: 22px; width: min(440px, calc(100% - 32px)); }
.consent-inner {
  margin: 0; padding: 6px 6px 6px 8px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
}
.consent-banner:has(.consent-details:not([hidden])) .consent-inner { padding: 18px 18px 14px; }
.consent-text { flex: 1 1 auto; margin: 0; font-size: 14px; line-height: 20px; color: var(--cp-ink); }
.consent-text a { color: inherit; text-decoration: underline; text-decoration-color: rgba(238, 246, 241, .45); text-underline-offset: 2px; }
.consent-text a:hover { text-decoration-color: currentColor; }
.consent-text strong { color: var(--cp-ink); }
.consent-status { flex: 1 1 100%; margin: 0; padding: 0 12px 6px; font-size: 13px; line-height: 18px; color: var(--cp-ink-2); }
.consent-status:empty { display: none; }
.consent-actions { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.consent-decline {
  font: inherit; font-size: 14px; padding: 8px 10px; cursor: pointer; border-radius: 999px;
  background: none; border: 0; color: var(--cp-ink); text-decoration: underline; text-decoration-color: rgba(238, 246, 241, .45); text-underline-offset: 2px;
}
.consent-decline:hover { text-decoration-color: currentColor; }
.consent-banner .btn {
  cursor: pointer;
  transform: none; transition: background 140ms ease, box-shadow 140ms ease;
  min-height: 36px; padding: 0 16px; border-radius: 999px; font-size: 14px; font-weight: 600; box-shadow: none;
  background: var(--cp-mint); border: 1px solid var(--cp-mint); color: var(--cp-mint-ink);
}
.consent-banner .btn:hover { transform: none; background: #8BE0BA; border-color: #8BE0BA; color: var(--cp-mint-ink); box-shadow: 0 0 18px -4px rgba(111, 211, 166, .7); }
.consent-banner .btn:active { background: #5BC394; border-color: #5BC394; color: var(--cp-mint-ink); box-shadow: none; }
.consent-banner .btn:focus-visible, .consent-decline:focus-visible { outline: 2px solid var(--cp-mint); outline-offset: 2px; }

/* Compact privacy choice: cookie, one line, Allow, Decline, Choices. */
.consent-summary { display: flex; align-items: center; gap: 10px; width: 100%; }
.consent-summary[hidden], .consent-details[hidden] { display: none; }
.consent-summary::before {
  content: ''; flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%23E9C48A' d='M16 3a13 13 0 1 0 13 13 4 4 0 0 1-4.6-4.4A4 4 0 0 1 20 7.2 4 4 0 0 1 16 3z'/%3E%3Cg fill='%237A4E2A'%3E%3Ccircle cx='11' cy='12' r='1.9'/%3E%3Ccircle cx='17.5' cy='18' r='1.7'/%3E%3Ccircle cx='10.5' cy='20.5' r='1.6'/%3E%3Ccircle cx='22' cy='22.5' r='1.4'/%3E%3Ccircle cx='15' cy='25' r='1.1'/%3E%3C/g%3E%3C/svg%3E") center / 24px no-repeat,
    radial-gradient(circle, rgba(255, 244, 214, .30), rgba(255, 244, 214, 0) 70%);
  box-shadow: 0 0 14px 2px rgba(255, 238, 196, .38), 0 0 32px 6px rgba(255, 238, 196, .14);
}
.consent-summary .consent-text { white-space: nowrap; }
.consent-summary .consent-actions { flex: none; margin-left: 4px; }
.consent-summary .consent-decline { padding: 8px 8px; }
.consent-details { width: 100%; max-height: min(70vh, 580px); overflow-y: auto; }
.consent-details .consent-text { margin: 0 0 8px; color: var(--cp-ink-2); }
.consent-details .consent-text strong { color: var(--cp-ink); }
.consent-details .consent-status { padding: 0; margin: 0 0 8px; }
.consent-details .consent-actions { margin: 0 0 12px; flex-wrap: wrap; justify-content: flex-start; }
/* One bar (owner, 2026-11-02): the summary never wraps. Phone bar is at most
   56px tall (8px + 40px control + 8px); the guard in consent-one-bar.test.js
   fails if copy or controls grow past one bar. Copy is never clipped.
   Decline matches Allow in weight: the same pill, outlined. */
.consent-banner .consent-summary .consent-decline-all { background: rgba(238, 246, 241, .06); border-color: rgba(238, 246, 241, .55); color: var(--cp-ink); }
.consent-banner .consent-summary .consent-decline-all:hover {
  background: rgba(238, 246, 241, .14); border-color: var(--cp-ink); color: var(--cp-ink); box-shadow: none;
}
.consent-banner .consent-summary .consent-decline-all:active {
  background: rgba(238, 246, 241, .20); border-color: var(--cp-ink); color: var(--cp-ink); box-shadow: none;
}
body:has(.consent-banner:not([hidden])) .preview-pill { display: none; }
@media (max-width: 720px) {
  .consent-banner { left: 10px; bottom: calc(66px + env(safe-area-inset-bottom)); }
}
/* Tablets: the short line only, so the pill never outgrows the screen. */
@media (max-width: 820px) {
  .consent-summary .consent-more { display: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .consent-banner { background: #10261D; -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (max-width: 560px) {
  .consent-banner { left: 10px; max-width: calc(100% - 20px); }
  .consent-banner:has(.consent-details:not([hidden])) { width: calc(100% - 20px); }
  .consent-inner { padding: 7px 8px; }
  .consent-summary { flex-wrap: nowrap; gap: 8px; }
  .consent-summary::before { width: 26px; height: 26px; background-size: 20px, auto; }
  .consent-summary .consent-text { flex: 1 1 auto; min-width: 0; white-space: normal; font-size: 13px; line-height: 17px; }
  .consent-summary .consent-more { display: none; }
  .consent-summary .consent-actions { margin-left: 0; gap: 4px; }
  .consent-summary .btn { min-height: 40px; padding: 0 12px; font-size: 14px; }
  .consent-summary .consent-choices { min-height: 40px; padding: 0 4px; font-size: 13px; }
  /* Phones: a short label keeps the pill one slim line; the full question stays for screen readers. */
  .consent-summary .consent-text { font-size: 0; line-height: 0; white-space: nowrap; }
  .consent-summary .consent-text::before { content: "Allow analytics?"; content: "Allow analytics?" / ""; font-size: 13px; line-height: 17px; color: var(--cp-ink); }
}
@media (max-width: 360px) {
  .consent-summary::before { display: none; }
  .consent-summary .btn { padding: 0 10px; }
  .consent-summary .consent-choices { padding: 0 2px; }
}
