/* ============================================================
   LAUREL & LANTERN INN — magic.css (v19, 2026-10-17)
   The quiet magic: the Arrival, living paintings, the house that
   knows the hour, the enchanted floor plan, small found wonders,
   and the "Still the house" switch that stops all of it.
   Loaded after styles.css and welcome.css; uses only their tokens.

   Motion rules for this file:
   - Every animation here stops when the visitor presses
     "Still the house" (html.is-still) or when their device asks
     for reduced motion (styles.css already stops all animation then).
   - Nothing flashes: the fastest change is one soft lamp flicker,
     well under three per second.
   ============================================================ */

/* ---------- Still the house ---------- */
html.is-still *,
html.is-still *::before,
html.is-still *::after {
  animation: none !important;
  transition: none !important;
}
.still-btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--serif-caps); font-size: 0.7rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--parchment-dim);
  background: none; border: 0; padding: 8px 4px; cursor: pointer;
  transition: color 0.25s;
}
.still-btn:hover, .still-btn:focus-visible { color: var(--amber); }
.still-btn svg { width: 15px; height: 15px; flex: none; }
.still-btn .flame { fill: var(--amber); transition: opacity 0.4s; }
.still-btn[aria-pressed="true"] .flame { opacity: 0.18; }
.still-btn[aria-pressed="true"] { color: var(--copper); }

/* ---------- the Arrival (home page hero) ---------- */
/* Settled state first: this is what visitors see with no script, on a return visit,
   with the house stilled, or with reduced motion. The lamps simply glow. */
.lamps { position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: var(--lamp-gain, 0.85); }
.lamp, .door-glow {
  position: absolute; left: var(--x); top: var(--y);
  transform: translate(-50%, -50%);
  mix-blend-mode: screen;
}
.lamp {
  width: calc(var(--s, 5.4%) * 1.35); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 236, 196, 1) 0%,
    rgba(255, 186, 102, 0.7) 9%,
    rgba(255, 153, 51, 0.30) 24%,
    rgba(255, 153, 51, 0.10) 44%,
    rgba(255, 153, 51, 0) 66%);
  opacity: 0.82;
}
.door-glow {
  width: var(--w); height: var(--h); border-radius: 46% 46% 12% 12%;
  background: radial-gradient(ellipse at 50% 55%,
    rgba(255, 220, 160, 0.75) 0%,
    rgba(255, 153, 51, 0.32) 42%,
    rgba(255, 153, 51, 0) 74%);
  opacity: 0.85;
}
.arrival-line {
  font-style: italic; color: var(--copper);
  font-size: clamp(1.05rem, 0.95rem + 0.4vw, 1.25rem);
  margin-top: 10px;
}

@media (prefers-reduced-motion: no-preference) {
  /* every lamp breathes on its own clock */
  .lamp { animation: lamp-breathe var(--breath, 10s) ease-in-out var(--off, 0s) infinite; }
  .door-glow { animation: lamp-breathe 13s ease-in-out -4s infinite; }

  /* first visit of the day: dusk deepens, the lamps light toward the door, the door glows,
     and the house warms. The whole sequence is over in under five seconds. */
  html.arrive .hero-art img { animation: dusk-lift 4.6s ease-in-out both; }
  html.arrive .lamp {
    animation:
      lamp-ignite 0.9s ease-out calc(0.35s + var(--i) * 0.17s) both,
      lamp-breathe var(--breath, 10s) ease-in-out calc(4.8s + var(--off, 0s)) infinite;
  }
  html.arrive .door-glow {
    animation:
      door-open 1.1s ease-out 3.5s both,
      lamp-breathe 13s ease-in-out 4.8s infinite;
  }
  html.arrive .arrival-line { animation: line-in 1s ease-out 3.8s both; }
}
@keyframes lamp-breathe { 0%, 100% { opacity: 0.72; } 50% { opacity: 0.96; } }
@keyframes lamp-ignite {
  0%   { opacity: 0;    transform: translate(-50%, -50%) scale(0.35); }
  45%  { opacity: 1;    transform: translate(-50%, -50%) scale(1.08); }
  62%  { opacity: 0.7; }
  78%  { opacity: 0.92; }
  100% { opacity: 0.82; transform: translate(-50%, -50%) scale(1); }
}
@keyframes door-open {
  0%   { opacity: 0;   transform: translate(-50%, -50%) scaleY(0.7); }
  100% { opacity: 0.85; transform: translate(-50%, -50%) scaleY(1); }
}
@keyframes dusk-lift {
  0%   { filter: brightness(0.4) saturate(0.6); }
  65%  { filter: brightness(0.62) saturate(0.78); }
  100% { filter: none; }
}
@keyframes line-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- the house knows the hour ---------- */
/* data-hour is set on <html> from the visitor's own clock: day (6am–5pm), dusk (5–8pm), night (8pm–6am). */
html[data-hour="day"]   { --lamp-gain: 0.62; }
html[data-hour="dusk"]  { --lamp-gain: 0.86; }
html[data-hour="night"] { --lamp-gain: 1; }
html[data-hour="day"] body {
  background: radial-gradient(140% 120% at 50% 8%, #3A1236 0%, var(--night) 50%, var(--night-deep) 100%);
  background-attachment: fixed;
}
html[data-hour="night"] body {
  background: radial-gradient(140% 120% at 50% 8%, #230A26 0%, #120012 48%, #080009 100%);
  background-attachment: fixed;
}
.hour-line {
  text-align: center; font-style: italic; color: var(--parchment-dim);
  max-width: 620px; margin: -12px auto 28px;
}
.page-head .hour-line { margin: 18px auto 0; }
.wing-card { transition: border-color 0.6s, box-shadow 0.6s; }
html[data-hour="day"] .wing-focus,
html[data-hour="dusk"] .wing-focus {
  box-shadow: 0 0 0 1px rgba(255, 153, 51, 0.35), 0 14px 46px rgba(255, 153, 51, 0.10);
}
html[data-hour="night"] .wing-sleep {
  order: -1;
  box-shadow: 0 0 0 1px rgba(77, 158, 158, 0.45), 0 14px 46px rgba(77, 158, 158, 0.12);
}
.wing-lit {
  display: none;
  font-family: var(--serif-caps); font-size: 0.62rem; letter-spacing: 0.2em;
  text-transform: uppercase; margin: -4px 0 10px;
}
html[data-hour="day"] .wing-focus .wing-lit,
html[data-hour="dusk"] .wing-focus .wing-lit { display: block; color: var(--amber); }
html[data-hour="night"] .wing-sleep .wing-lit { display: block; color: #4D9E9E; }

/* ---------- living paintings ---------- */
/* Each room card is a framed painting. On hover or keyboard focus it quietly comes alive:
   the view drifts closer, a lamp-glow breathes, and dust motes drift up through the light.
   A room with a short muted loop clip ("loop" in rooms.json) plays that clip instead. */
.card-media { position: relative; overflow: hidden; }
.card-media::after {
  content: ""; position: absolute; inset: 7px; pointer-events: none;
  border: 1px solid rgba(204, 153, 102, 0.34); border-radius: 7px;
  box-shadow: inset 0 0 0 1px rgba(12, 0, 13, 0.35), 0 0 0 1px rgba(12, 0, 13, 0.25);
}
.card-media img { transition: transform 9s cubic-bezier(0.2, 0.6, 0.2, 1), filter 1.4s ease; }
.room-card:not(.is-soon):hover .card-media img,
.room-card:not(.is-soon):focus-within .card-media img {
  transform: scale(1.06);
  filter: brightness(1.06) saturate(1.04);
}
.alive {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  opacity: 0; transition: opacity 1.4s ease;
  background: radial-gradient(70% 55% at 50% 72%, rgba(255, 153, 51, 0.20), rgba(255, 153, 51, 0) 72%);
  mix-blend-mode: screen;
}
.alive::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 200%;
  background-image:
    radial-gradient(circle, rgba(255, 228, 186, 0.9) 0 1px, transparent 1.6px),
    radial-gradient(circle, rgba(255, 210, 150, 0.7) 0 1px, transparent 1.4px),
    radial-gradient(circle, rgba(243, 231, 214, 0.6) 0 0.8px, transparent 1.2px);
  background-size: 140px 170px, 190px 230px, 110px 150px;
  background-position: 20px 40px, 90px 10px, 60px 120px;
  opacity: 0.55;
}
.card-loop {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.9s ease; pointer-events: none;
}
.room-card.is-playing .card-loop { opacity: 1; }
.room-card:not(.is-soon):hover .alive,
.room-card:not(.is-soon):focus-within .alive { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .alive { animation: glow-breathe 7s ease-in-out infinite paused; }
  .alive::before { animation: motes-rise 22s linear infinite paused; }
  .room-card:not(.is-soon):hover .alive,
  .room-card:not(.is-soon):focus-within .alive,
  .room-card:not(.is-soon):hover .alive::before,
  .room-card:not(.is-soon):focus-within .alive::before { animation-play-state: running; }
  /* room pages: the painting at the top is always quietly alive */
  .alive-hero, .alive-hero::before { animation-play-state: running; }
}
.alive-hero { opacity: 0.85; }
@keyframes glow-breathe { 0%, 100% { opacity: 0.75; } 50% { opacity: 1; } }
@keyframes motes-rise { from { transform: translateY(0); } to { transform: translateY(-50%); } }
.alive-hero { animation-duration: 11s; }
.alive-hero::before { animation-duration: 40s; opacity: 0.4; }

/* ---------- the enchanted floor plan (rooms.html) ---------- */
.plan { padding: 8px 0 40px; }
.plan-frame {
  max-width: 820px; margin: 0 auto; padding: 18px 18px 8px;
  background: rgba(12, 0, 13, 0.45);
  border: 1px solid var(--parchment-faint); border-radius: 16px;
}
.plan-frame > svg { display: block; width: 100%; height: auto; overflow: visible; }
.plan-caption { text-align: center; font-style: italic; color: var(--parchment-dim); font-size: 1rem; margin: 6px 0 10px; }
.plan-house path, .plan-house line, .plan-house rect {
  fill: none; stroke: rgba(204, 153, 102, 0.42); stroke-width: 1.4;
  vector-effect: non-scaling-stroke; stroke-linejoin: round;
}
.plan-house .ground { stroke: rgba(204, 153, 102, 0.55); }
.plan-house .below { stroke-dasharray: 5 6; }
.plan-house .pane { stroke: rgba(204, 153, 102, 0.22); }
.plan-floor-label a { text-decoration: none; }
.plan-floor-label text {
  font-family: var(--serif-caps); font-size: 15px; letter-spacing: 0.22em;
  fill: var(--parchment-dim); text-transform: uppercase;
}
.plan-floor-label a:hover text, .plan-floor-label a:focus-visible text { fill: var(--amber); }
.plan-lines path {
  fill: none; stroke: rgba(204, 153, 102, 0.38); stroke-width: 1.1;
  vector-effect: non-scaling-stroke; stroke-dasharray: 1; stroke-dashoffset: 0;
}
html.js .plan:not(.in-view) .plan-lines path { stroke-dashoffset: 1; }
.plan-lines path { transition: stroke-dashoffset 2.6s ease-in-out; }
.node { cursor: pointer; }
.node a { outline: none; }
.node .halo { fill: rgba(255, 153, 51, 0.14); transition: opacity 0.3s; }
.node .star {
  fill: var(--parchment); transform-box: fill-box; transform-origin: center;
  transition: transform 0.35s ease, fill 0.3s;
}
.node .ring { fill: none; stroke: var(--amber); stroke-width: 1.5; opacity: 0; vector-effect: non-scaling-stroke; }
.node .name {
  font-family: var(--serif-display); font-size: 21px; font-weight: 500;
  fill: var(--parchment); transition: fill 0.3s;
}
.node .soon {
  font-family: var(--serif-caps); font-size: 11px; letter-spacing: 0.2em;
  fill: var(--copper); text-transform: uppercase;
}
.node.is-soon .star { fill: var(--parchment-dim); }
.node.is-soon .halo { opacity: 0.5; }
.node a:hover .star, .node a:focus-visible .star { fill: var(--amber); transform: scale(1.4); }
.node a:hover .name, .node a:focus-visible .name { fill: var(--amber); }
.node a:focus-visible .ring { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .node .halo { animation: star-twinkle var(--tw, 7s) ease-in-out var(--twoff, 0s) infinite; }
}
@keyframes star-twinkle { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
/* phones: the plan keeps a readable size and slides sideways inside its frame */
.plan-slide { display: none; }
@media (max-width: 680px) {
  .plan-frame { padding: 10px 0 4px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .plan-frame > svg { min-width: 640px; padding: 0 10px; }
  .plan-slide { display: block; text-align: center; font-family: var(--serif-caps); font-size: 0.66rem;
    letter-spacing: 0.2em; text-transform: uppercase; color: var(--parchment-dim); margin: 0 0 10px; }
}

/* ---------- small found wonders ---------- */
.has-wonder { position: relative; }
.home-sill.has-wonder { min-height: 52px; }   /* v21l: the brass key, now the wings are gone */
.wonder { position: absolute; top: 6px; right: 6px; z-index: 5; }
.plan .wonder { top: -6px; right: 0; }
.page .narrow.has-wonder .wonder { top: 44px; right: 0; }  /* beside the page title */
/* v19c (2026-10-18): easier to find — larger, brighter, on a soft halo, with a gentle glow now and then */
.wonder-btn {
  position: relative;
  width: 56px; height: 56px; display: grid; place-items: center;
  background: radial-gradient(circle, rgba(204, 153, 102, 0.16) 0%, rgba(204, 153, 102, 0.06) 50%, rgba(204, 153, 102, 0) 72%);
  border: 0; border-radius: 50%; cursor: pointer;
  color: var(--copper); opacity: 0.9; transition: opacity 0.3s, color 0.3s;
}
.wonder-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(255, 153, 51, 0.38) 0%, rgba(255, 153, 51, 0.12) 45%, rgba(255, 153, 51, 0) 70%);
  opacity: 0;
}
.wonder-btn:hover, .wonder-btn:focus-visible, .wonder-btn[aria-expanded="true"] { opacity: 1; color: var(--amber); }
.wonder-btn:hover::before, .wonder-btn:focus-visible::before, .wonder-btn[aria-expanded="true"]::before { opacity: 1; }
.wonder-btn svg { position: relative; width: 36px; height: 36px; }
@media (prefers-reduced-motion: no-preference) {
  .wonder-btn::before { animation: wonder-halo 7s ease-in-out infinite; }
  .wonder-btn svg { animation: wonder-glint 7s ease-in-out infinite; }
}
@keyframes wonder-halo {
  0%, 60%, 100% { opacity: 0; transform: scale(0.8); }
  78% { opacity: 1; transform: scale(1.15); }
}
@keyframes wonder-glint {
  0%, 60%, 100% { filter: none; }
  78% { filter: drop-shadow(0 0 7px rgba(255, 153, 51, 0.9)); color: var(--amber); }
}
.wonder-note {
  position: absolute; right: 0; top: 62px; width: min(320px, 78vw);
  padding: 20px 22px 18px; text-align: left;
  background: rgba(12, 0, 13, 0.96);
  border: 1px solid rgba(204, 153, 102, 0.45); border-radius: 12px;
  box-shadow: 0 18px 44px rgba(12, 0, 13, 0.6);
}
.wonder-note[hidden] { display: none; }
.wonder-note .eyebrow { font-size: 0.66rem; margin-bottom: 8px; }
.wonder-note p.wonder-text {
  font-style: italic; color: var(--parchment); font-size: 1.15rem; line-height: 1.45; margin: 0;
}
.wonder-close {
  margin-top: 12px; background: none; border: 0; padding: 4px 0; cursor: pointer;
  font-family: var(--serif-caps); font-size: 0.66rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--parchment-dim);
}
.wonder-close:hover, .wonder-close:focus-visible { color: var(--amber); }
@media (prefers-reduced-motion: no-preference) {
  .wonder-note:not([hidden]) { animation: line-in 0.5s ease-out both; }
}

/* ---------- phones: the menu bar never covers the page (v19d, 2026-10-18) ----------
   On wide screens the menu floats over the top of the page and each page leaves room for it.
   On phones the menu wraps onto several lines, so its height changes with the screen width and
   no fixed gap can match it. Here the menu takes up its own space at the top and stays pinned
   while scrolling (sticky), so the page always starts directly beneath it, at any width. */
@media (max-width: 760px) {
  .site-nav { position: sticky; top: 0; }
  .hero, .room-page { padding-top: 0; }
  .page { padding-top: 40px; }
  .page.room-page { padding-top: 0; }
  .skip:focus { z-index: 100; }
}
