:root{
  --cream:#f5f3ec; --cream2:#edeae0; --paper:#fdfbf4; --border:#ddd4c0;
  --ink:#2a2018; --ink-soft:#4a3d30; --muted:#7a6d5c;
  --terra:#c07a45; --hunter:#3a4a2e;
  --sage:#5a6b3a; --blush:#c9a4a0; --mauve:#9e8fa0;
  /* Two more for hotspot markers. Mustard is the token the insights page
     already uses, so it is not a new colour in the system, only newly used
     here. Royal is new: a royal blue pulled towards slate so it sits on a
     watercolour scene rather than on top of it, and dark enough to read
     against a pale sky, which is where half these markers land. */
  --mustard:#c39a3f; --royal:#3f5b86;
}
*{ box-sizing:border-box; margin:0; padding:0; }
body{ background:var(--cream2); font-family:'Jost',sans-serif; font-weight:300; color:var(--ink); -webkit-font-smoothing:antialiased; }
.page{ max-width:1280px; margin:0 auto; padding:18px 14px 26px; }

.world-frame{ position:relative; background:#f7f4ea; border-radius:14px; overflow:hidden; border:1px solid var(--border); box-shadow:0 10px 30px rgba(40,30,20,0.08); }

/* Noa acorn companion: her avatar sits in the top bar (always visible in the
   embed) and a warm greeting drops down beneath it. "Ask a question" focuses
   the ask bar right beside her. */
.noa-ava{ display:inline-flex; align-items:center; gap:7px; background:transparent; border:none; padding:0; cursor:pointer; }
.noa-acorn{ width:auto; height:30px; display:block; filter:drop-shadow(0 2px 4px rgba(60,40,20,.22)); transition:transform .18s ease; }
.noa-ava:hover .noa-acorn{ transform:scale(1.08); }
#noa-greet{ position:absolute; top:52px; left:14px; z-index:20; width:min(340px, calc(100% - 28px)); background:var(--paper); border:1px solid var(--border); border-radius:13px; padding:13px 15px 14px; box-shadow:0 12px 28px rgba(40,30,20,0.16); }
.ng-row{ display:flex; gap:12px; align-items:center; }
.ng-noa{ width:64px; height:auto; flex:none; }
.ng-content{ flex:1; min-width:0; }
#noa-greet[aria-hidden="true"]{ display:none; }
.ng-x{ position:absolute; top:7px; right:10px; font-size:15px; line-height:1; color:var(--muted); background:none; border:none; cursor:pointer; }
.ng-x:hover{ color:var(--ink); }
.ng-eyebrow{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--muted); margin-bottom:5px; }
.ng-say{ font-family:'Cormorant Garamond',serif; font-style:italic; font-size:16px; line-height:1.45; color:var(--ink); margin-bottom:11px; }
.ng-ask{ justify-content:center; padding:8px 14px; font-size:12.5px; }
.ng-tail{ position:absolute; top:-7px; left:22px; width:13px; height:13px; background:var(--paper); border-left:1px solid var(--border); border-top:1px solid var(--border); transform:rotate(45deg); }
.topbar{ position:relative; z-index:5; display:flex; align-items:center; gap:10px; padding:11px 15px; border-bottom:1px solid var(--border); flex-wrap:nowrap; }
.brand{ font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:500; font-size:19px; color:var(--ink); }
.wlabel{ font-size:28px; letter-spacing:2px; text-transform:uppercase; color:var(--ink-soft); font-weight:400; white-space:nowrap; }
.wcaption{ font-family:'Cormorant Garamond',serif; font-style:italic; font-size:20px; color:var(--ink-soft); white-space:nowrap; flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; }
@media (max-width:640px){
  .topbar{ gap:8px; padding:10px 12px; }
  .wlabel{ font-size:16px; letter-spacing:1.4px; min-width:0; flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; }
  .wcaption{ font-size:14px; }
  .btn-explore, .btn-open-world{ font-size:12px; padding:8px 12px; flex:none; }
}
@media (max-width:480px){
  .wcaption{ display:none; }
  /* Two rows: world name + heart above, the action buttons sharing the line
     below. One row cannot hold all four at phone widths. */
  .topbar{ flex-wrap:wrap; }
  /* The label's 55% basis plus the heart crowds row one, so both action
     buttons always land together on the second row. Long world names wrap
     onto a second line here rather than clipping to an ellipsis. */
  .wlabel{ flex:1 1 55%; white-space:normal; overflow:visible; text-overflow:clip; line-height:1.3; }
  .btn-explore, .btn-open-world{ flex:1 1 40%; margin-right:0; padding:9px 10px; font-size:12.5px; }
}
#ask{ flex:1; min-width:160px; font-family:'Jost',sans-serif; font-size:12.5px; background:#fffdf6; border:1px solid var(--border); border-radius:18px; padding:8px 14px; color:var(--ink); outline:none; }
#ask:focus{ border-color:var(--terra); }
.wbtn{ display:inline-flex; align-items:center; justify-content:center; gap:6px; font-family:'Jost',sans-serif; font-size:12.5px; font-weight:400; padding:7px 14px; border-radius:16px; cursor:pointer; border:none; text-decoration:none; white-space:nowrap; flex:none; }
.btn-idx{ background:#fffdf6; border:1px solid var(--border); color:var(--ink-soft); }
.btn-explore{ background:var(--terra); color:#fdf9ee; font-size:14px; padding:9px 18px; box-shadow:0 3px 10px rgba(192,122,69,0.3); }
.btn-open-world{ background:#3a4a2e; color:#f5f3ec; font-size:14px; padding:9px 18px; box-shadow:0 3px 10px rgba(58,74,46,0.3); text-decoration:none; display:inline-flex; align-items:center; margin-right:8px; }
.btn-open-world:hover{ background:#2f3d25; }
.btn-explore:hover{ background:#a9682f; }
.topbar .worldheart-slot{ margin-left:auto; display:inline-flex; align-items:center; }
.save-heart{ position:relative; display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; border-radius:999px; background:rgba(255,255,255,0.92); border:1px solid var(--border); color:#7a6d5c; cursor:pointer; box-shadow:0 2px 6px rgba(40,30,20,0.12); padding:0; transition:color .15s ease, transform .12s ease; }
.save-heart:hover{ color:var(--terra); transform:scale(1.08); }
.save-heart.on{ color:#BAA1A7; }
/* Discovery tooltip: what the heart does. Shows on hover/focus, and once on first visit (.sv-show). */
.save-heart .save-tip{ position:absolute; top:calc(100% + 8px); right:0; z-index:60; white-space:nowrap; background:#3a4a2e; color:#f5f3ec; font-family:inherit; font-size:12px; line-height:1; padding:7px 10px; border-radius:9px; box-shadow:0 6px 18px rgba(40,30,20,0.22); opacity:0; transform:translateY(-4px); pointer-events:none; transition:opacity .16s ease, transform .16s ease; }
.save-heart .save-tip::after{ content:''; position:absolute; bottom:100%; right:12px; border:5px solid transparent; border-bottom-color:#3a4a2e; }
.save-heart:hover .save-tip, .save-heart:focus-visible .save-tip, .save-heart.sv-show .save-tip{ opacity:1; transform:translateY(0); }
.fcard-heart{ position:absolute; top:11px; right:11px; z-index:2; }
.topbar-heart{ background:transparent; border:none; box-shadow:none; width:34px; height:34px; color:#8a7d6c; }
.topbar-heart:hover{ background:rgba(0,0,0,0.05); }
.btn-dl{ background:var(--hunter); color:var(--cream); }
.btn-ghost{ background:transparent; border:1px solid var(--border); color:var(--ink-soft); }

#scenewrap{ position:relative; overflow:hidden; }
#scene svg{ display:block; width:100%; height:auto; }

#popup{ position:absolute; left:16px; top:16px; width:320px; background:var(--paper); border:1px solid var(--border); border-radius:12px; padding:18px 20px; transition:opacity .2s ease; opacity:0; pointer-events:none; z-index:2; box-shadow:0 8px 22px rgba(40,30,20,0.10); }
.pkhead{ display:flex; justify-content:space-between; align-items:flex-start; }
.pkind{ font-size:13px; letter-spacing:2px; text-transform:uppercase; color:var(--muted); }
.pclose{ font-size:22px; color:var(--muted); cursor:pointer; line-height:1; background:none; border:none; }
.ptitle{ font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:500; font-size:29px; color:var(--ink); margin:5px 0 8px; }
.pdesc{ font-size:18px; color:var(--ink-soft); line-height:1.55; margin-bottom:12px; }
.pdots{ display:flex; gap:6px; margin-bottom:9px; }
.pdot{ width:9px; height:9px; border-radius:50%; display:inline-block; }
.pbtns{ display:flex; gap:8px; flex-wrap:wrap; }
#popup .wbtn{ font-size:16px; padding:10px 20px; border-radius:18px; }
.breathe-wrap{ display:flex; flex-direction:column; align-items:center; gap:8px; padding:2px 0; }
.blabel{ font-size:17px; }
.affirm{ font-family:'Cormorant Garamond',serif; font-style:italic; font-size:16px; color:var(--muted); text-align:center; line-height:1.5; }

#drawer{ position:absolute; top:0; right:0; bottom:0; width:230px; background:#f8f5ea; border-left:1px solid var(--border); padding:12px 14px; transition:transform .35s ease; transform:translateX(108%); z-index:3; overflow-y:auto; }
#drawer.open{ transform:translateX(0); }
.idxhead{ font-size:11.5px; letter-spacing:2px; text-transform:uppercase; color:var(--ink-soft); margin-bottom:8px; }
.idxrow{ display:flex; align-items:center; gap:9px; padding:11px 6px; border-bottom:1px solid #e4dcc8; cursor:pointer; font-size:14.5px; color:var(--ink-soft); }
.idxrow:last-child{ border-bottom:none; }
.idxrow:hover{ background:#f1ecdd; }
.idot{ width:8px; height:8px; border-radius:50%; flex:none; }

.shelf{ padding:13px 15px 15px; border-top:1px solid var(--border); }
.shelf-label{ font-size:15px; font-weight:500; letter-spacing:2px; text-transform:uppercase; color:var(--ink); margin-bottom:12px; }
.fgrid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:10px; }
.fcard{ position:relative; background:var(--paper); border:1px solid var(--border); border-radius:12px; padding:13px 15px; transition:box-shadow .3s ease; }
.fcard.lit{ box-shadow:0 0 0 2px var(--terra); }
.feyebrow{ font-size:11px; letter-spacing:2px; text-transform:uppercase; color:var(--muted); margin-bottom:4px; }
.ftitle{ font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:500; font-size:22px; color:var(--ink); margin-bottom:6px; }
.fdesc{ font-size:14px; color:var(--ink-soft); line-height:1.55; margin-bottom:10px; }

.foot{ text-align:center; font-size:12px; color:var(--muted); margin-top:14px; line-height:1.6; }

/* Ask Noa results: the ask bar calls the real /api/noa agent and shows Noa's
   curated activities inline, replacing the scene while you are asking. */
#results{ display:none; padding:15px 15px 20px; }
body.asking #scenewrap, body.asking .shelf{ display:none; }
body.asking #results{ display:block; }
.res-bar{ margin-bottom:12px; }
.res-intro{ font-family:'Cormorant Garamond',serif; font-style:italic; font-size:22px; color:var(--ink); line-height:1.5; margin-bottom:14px; }
.res-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:12px; }
.res-card{ background:var(--paper); border:1px solid var(--border); border-radius:12px; padding:14px 16px; }
.rc-title{ font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:500; font-size:22px; color:var(--ink); margin-bottom:7px; }
.rc-why{ font-size:14px; color:var(--ink-soft); line-height:1.55; margin-bottom:10px; }
.rc-how{ font-size:13px; color:var(--muted); line-height:1.5; margin-bottom:11px; }
.rc-lab{ display:block; text-transform:uppercase; letter-spacing:1.5px; font-size:9.5px; color:var(--muted); margin-bottom:2px; }
.res-foot{ margin-top:15px; }

.spot{ cursor:pointer; }
.spot:hover .dotc{ r:9; }

/* image-overlay hotspot markers (scene.mode == "image") */
.scene-img{ display:block; width:100%; height:auto; }
#markers{ position:absolute; inset:0; z-index:1; pointer-events:none; }
/* Each hotspot carries its own colour from the palette in --spot, set by the
   engine. Terra is the fallback, and stays the colour of a marker anywhere
   the variable has not been set. */
.imspot{ --spot:var(--terra); position:absolute; transform:translate(-50%,-50%); width:80px; height:80px; border:none; background:transparent; padding:0; cursor:pointer; display:flex; align-items:center; justify-content:center; pointer-events:auto; }

/* The ring. It sits behind whatever marker is in the middle, so a watercolour
   icon gets one as well as a plain dot, and it is drawn rather than animated
   into existence: with motion turned off it is simply a still ring, which is
   the point of it. Nineteen worlds were entered and no hotspot was clicked,
   and a marker nobody notices is a scene with nothing in it. */
.imspot::before{ content:""; position:absolute; left:50%; top:50%; width:66px; height:66px; margin:-33px 0 0 -33px; border-radius:50%; border:2px solid var(--spot); opacity:.55; pointer-events:none; }
.imspot.has-icon::before{ width:88px; height:88px; margin:-44px 0 0 -44px; }
.imspot:hover::before, .imspot:focus::before{ opacity:.8; }

/* Forty pixels, not thirty. A marker is 3 per cent of a 1152px scene at the
   old size, against a watercolour illustration it was drawn to sit inside, and
   a month of worlds produced no clicks at all. Bigger, with a heavier stroke,
   so it reads as a control placed on the picture rather than a part of it. */
.immark{ position:relative; width:40px; height:40px; border-radius:50%; background:var(--spot); border:3px solid #fdf9ee; box-shadow:0 2px 7px rgba(42,32,24,0.4); transition:transform .15s ease; }
/* The glow: a soft wash of the same colour, held still so the ring is the
   only thing that moves. */
.immark::after{ content:""; position:absolute; left:50%; top:50%; width:84px; height:84px; transform:translate(-50%,-50%); border-radius:50%; background:var(--spot); opacity:.28; z-index:-1; }
.imspot:hover .immark, .imspot:focus .immark{ transform:scale(1.18); }
.imicon{ width:100%; height:100%; object-fit:contain; filter:drop-shadow(0 2px 4px rgba(42,32,24,.35)); transition:transform .15s ease; }
.imspot:hover .imicon, .imspot:focus .imicon{ transform:scale(1.12); }
.imlabel{ position:absolute; left:50%; bottom:118%; transform:translateX(-50%); white-space:nowrap; background:#2a2018; color:#fdfbf4; font-size:12px; line-height:1; padding:6px 9px; border-radius:7px; opacity:0; pointer-events:none; transition:opacity .15s; }
.imspot:hover .imlabel, .imspot:focus .imlabel{ opacity:1; }

/* "Click for Activity", on a few markers only.

   Nineteen worlds were opened in a day and not one hotspot was clicked, so
   the markers needed to say what they are for rather than wait to be
   discovered. A cloud with a tail pointing down at the marker it belongs to,
   in paper and ink like every other card in the product. It sits where the
   hover label sits and steps aside when that appears, so the two never
   collide, and it is aria-hidden because the button already has an
   accessible name that says the same thing better. */
/* Offsets are measured, not eyeballed: the cloud's base sits eight pixels
   clear of the ring's outer edge and the tail closes the rest, so it points
   at the marker instead of hovering somewhere above it. A dot's ring is 26px
   from the centre and an icon's is 44px, which is why the two differ. */
.imhint{ position:absolute; left:50%; bottom:92%; transform:translateX(-50%); white-space:nowrap; background:var(--paper); color:var(--ink); border:1px solid var(--border); font-size:11.5px; line-height:1; padding:7px 11px; border-radius:999px; box-shadow:0 4px 12px rgba(40,30,20,0.16); pointer-events:none; transition:opacity .18s ease; }
.imhint::after{ content:""; position:absolute; left:50%; top:100%; width:9px; height:9px; margin:-5px 0 0 -5px; transform:rotate(45deg); background:var(--paper); border-right:1px solid var(--border); border-bottom:1px solid var(--border); }
/* Out of the way of the hover label, and gone for good once the lesson has
   landed. */
.imspot.has-icon .imhint{ bottom:115%; }
.imspot:hover .imhint, .imspot:focus .imhint{ opacity:0; }
#markers.hints-done .imhint{ opacity:0; }

/* On a phone the scene is under three hundred pixels wide, and six markers at
   their full size stop being pointers and start being the picture. Everything
   shrinks together so the proportions hold; the hit area stays comfortably
   above the forty four pixels a fingertip needs. */
@media (max-width:640px){
  .imspot{ width:52px; height:52px; }
  .imspot::before{ width:38px; height:38px; margin:-19px 0 0 -19px; }
  .imspot.has-icon::before{ width:58px; height:58px; margin:-29px 0 0 -29px; }
  .immark{ width:22px; height:22px; }
  .immark::after{ width:46px; height:46px; }
  .imhint{ font-size:10.5px; padding:5px 9px; bottom:102%; }
  /* One cloud, not two. The scene is under three hundred pixels across and
     two of these sit on top of each other, with the second one clipped by the
     edge of the frame. The lesson only needs teaching once. */
  .imspot.has-hint ~ .imspot.has-hint .imhint{ display:none; }
}

/* Email gate: shown on the first Download click, anchored near the button so it
   stays in view inside a full-height embedded iframe. Once an email is stored
   (shared key with the Noa agent) it never shows again. */
#gate{ display:none; }
#gate[aria-hidden="false"]{ display:block; }
.gate-backdrop{ position:absolute; left:0; top:0; width:100%; height:100%; background:rgba(42,32,24,0.34); z-index:40; }
.gate-card{ position:absolute; left:50%; transform:translateX(-50%); width:min(340px, calc(100% - 32px)); background:var(--paper); border:1px solid var(--border); border-radius:14px; padding:18px 18px 16px; box-shadow:0 18px 40px rgba(40,30,20,0.22); z-index:41; }
.gate-x{ position:absolute; top:9px; right:12px; font-size:17px; line-height:1; color:var(--muted); background:none; border:none; cursor:pointer; }
.gate-x:hover{ color:var(--ink); }
.gate-eyebrow{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--muted); margin-bottom:5px; }
.gate-title{ font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:500; font-size:22px; color:var(--ink); margin-bottom:7px; }
.gate-say{ font-size:13px; line-height:1.5; color:var(--ink-soft); margin-bottom:13px; }
#gate-form{ display:flex; flex-direction:column; gap:9px; }
#gate-email{ font-family:'Jost',sans-serif; font-size:14px; background:#fffdf6; border:1px solid var(--border); border-radius:10px; padding:11px 13px; color:var(--ink); outline:none; }
#gate-email:focus{ border-color:var(--terra); }
#gate-submit{ justify-content:center; padding:11px 14px; font-size:13.5px; }
.gate-err{ font-size:12px; color:#a33e3e; min-height:1px; }

@media (prefers-reduced-motion: no-preference){
  @keyframes drift{ from{ transform:translateX(0);} to{ transform:translateX(40px);} }
  @keyframes sway{ from{ transform:rotate(-1deg);} to{ transform:rotate(1deg);} }
  @keyframes pulse{ 0%,100%{ transform:scale(1); opacity:.25;} 50%{ transform:scale(1.5); opacity:.1;} }
  @keyframes inhale{ 0%,100%{ transform:scale(.62);} 50%{ transform:scale(1);} }
  @keyframes tick{ from{ transform:rotate(0deg);} to{ transform:rotate(360deg);} }
  @keyframes bob{ from{ transform:translateY(0);} to{ transform:translateY(1.8px);} }
  @keyframes bloomp{ 0%,100%{ transform:scale(1);} 50%{ transform:scale(1.25);} }
  @keyframes flow{ to{ stroke-dashoffset:-40; } }
  @keyframes impulse{ 0%,100%{ transform:translate(-50%,-50%) scale(1); opacity:.25; } 50%{ transform:translate(-50%,-50%) scale(1.5); opacity:.1; } }
  /* Gentle: out and away once every three seconds, transform and opacity
     only, and every marker on a scene breathes together rather than each on
     its own timer, which would read as a fairground. */
  @keyframes spotring{ 0%{ transform:scale(.82); opacity:.6; } 70%{ opacity:0; } 100%{ transform:scale(1.6); opacity:0; } }
  .imspot::before{ animation:spotring 3s ease-out infinite; }
  /* The cloud drifts rather than bounces: two pixels, four seconds. */
  @keyframes hintbob{ 0%,100%{ transform:translate(-50%,0); } 50%{ transform:translate(-50%,-2.5px); } }
  .imhint{ animation:hintbob 4s ease-in-out infinite; }
  .noa-acorn{ animation:bob 3.6s ease-in-out infinite alternate; }
  .cloud1{ animation:drift 26s ease-in-out infinite alternate; }
  .cloud2{ animation:drift 34s ease-in-out infinite alternate-reverse; }
  .boatdrift{ animation:drift 40s ease-in-out infinite alternate; }
  .canopy{ animation:sway 8s ease-in-out infinite alternate; transform-box:fill-box; transform-origin:50% 100%; }
  .wisteria{ animation:sway 9s ease-in-out infinite alternate; transform-box:fill-box; transform-origin:50% 0%; }
  .halo{ animation:pulse 2.6s ease-in-out infinite; transform-box:fill-box; transform-origin:center; }
  .bcircle{ animation:inhale 8s ease-in-out infinite; }
  .kids{ animation:bob 4s ease-in-out infinite alternate; }
  .bobber{ animation:bob 4s ease-in-out infinite alternate; }
  .bloomdot{ animation:bloomp 3.2s ease-in-out infinite; transform-box:fill-box; transform-origin:center; }
  .bloomdot.b2{ animation-delay:1.1s; }
  .bloomdot.b3{ animation-delay:2.2s; }
  .ripple{ stroke-dasharray:8 10; animation:flow 6s linear infinite; }
  .minhand{ animation:tick 60s linear infinite; transform-box:view-box; }
}
