/* ============================================================
   Velun teaser  ·  XReliqua
   Decayed-reliquary register · painterly · cosmic-thread
   ------------------------------------------------------------
   Design intent:
     The page is a chapel space, not a marketing page.
     Cosmic-indigo never settles into pure black.
     Gilt is tarnished, never bright. Cream is parchment, not white.
     Cosmic glints are the rarest, brightest pixels on the page.
     Animation is candlelight, not neon.
   ============================================================ */

/* === reset === */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body, h1, h2, h3, p, ul, hr { margin: 0; padding: 0; }
ul { list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, button { font-family: inherit; }

/* === tokens === */
:root {
  /* base — strict palette, never deviate */
  --bg:           #0a0816;     /* cosmic indigo, page base */
  --bg-deep:      #07050f;     /* candle-shadow ground */
  --bg-shrine:    #100d22;     /* niche back-panel */
  --indigo:       #15163a;     /* deeper accent indigo */
  --indigo-soft:  #1f1d4a;     /* halo indigo */

  /* gilt — three states (tarnished, dim, brighter) */
  --gilt:         #c9a865;
  --gilt-dim:     #8a7242;
  --gilt-bright:  #e0c081;

  /* cream — parchment register on dark */
  --cream:        #e8dcc4;
  --cream-dim:    #b5ab95;
  --cream-faint:  #6e6750;

  /* cosmic glint — used only as pin-pricks of highlight */
  --cosmic:       #d8d4f0;

  /* type stack — quieter chapel register.
     Display = Cinzel (clean Trajan-derived, no "decorative" flourish).
     Heading caps = Cormorant SC (small-caps body face for plates).
     Body = Cormorant Garamond (text register).
     Utility = Syne (UI). */
  --font-display: "Cinzel", "Trajan Pro", "Cormorant SC", serif;
  --font-caps:    "Cormorant SC", "Cinzel", serif;
  --font-body:    "Cormorant Garamond", "EB Garamond", Georgia, serif;
  --font-utility: "Syne", system-ui, -apple-system, sans-serif;

  /* motion — slow, soft, never snappy */
  --ease:         cubic-bezier(.25, .65, .35, 1);
  --slow:         700ms var(--ease);
  --med:          420ms var(--ease);
  --fast:         260ms var(--ease);

  /* layout */
  --max:          1180px;
  --col-narrow:   620px;

  /* ---- editor-tunable values (overridable from site-editor.html) ----
     All hardcoded opacities/intensities that were scattered through
     the file are now pulled up here so they can be tuned from one place. */
  --grain-opacity:           0.72;
  --vignette-intensity:      0.42;
  --breath-intensity:        0.70;
  --mist-base-opacity:       0.18;
  --mist-scroll-multiplier:  0.82;
  --pearl-ornament-opacity:  0.79;
  --silhouette-glow:         1.00;   /* multiplier on hover rim-light */
  --patina-opacity-peak:     0.22;
  --niche-corner-rest:       0.55;
  --niche-corner-hover:      1.00;
  --pitch-card-strength:     0.65;   /* multiplier on the reading-card alpha */
}

/* === defs (offscreen) === */
.defs {
  position: absolute;
  width: 0; height: 0;
  overflow: hidden;
  pointer-events: none;
}

/* === base === */
html, body {
  background: var(--bg);
  color: var(--cream);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(16px, 1vw + 12px, 19px);
  line-height: 1.6;
  letter-spacing: 0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Contain horizontal overflow so decorative transforms (studio mark,
     pitch backdrop, frame extensions) never trigger horizontal scroll
     on narrow viewports. */
  overflow-x: hidden;
  max-width: 100vw;
}

body {
  min-height: 100vh;
  position: relative;
  overflow-x: hidden;
}

/* === backdrop layers (deep gradient + grain) === */
.page-bg {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 38% at 50% 0%,    rgba(40, 35, 80, 0.55), transparent 70%),
    radial-gradient(ellipse 50% 50% at 50% 100%,  rgba(40, 30, 60, 0.4),  transparent 70%),
    radial-gradient(ellipse 30% 22% at 18% 64%,   rgba(201, 168, 101, 0.04), transparent 70%),
    radial-gradient(ellipse 30% 22% at 82% 36%,   rgba(216, 212, 240, 0.03), transparent 70%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
  z-index: -2;
  pointer-events: none;
}

/* breathing vignette — a dark radial that pulses inward, the
   edges of the page closing on the V star-wheel. Sits ABOVE
   page-bg but BELOW page-grain and content. */
.page-vignette {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 60% at 50% 50%,
      transparent 0%,
      transparent 38%,
      rgba(4, 3, 10, 0.35) 72%,
      rgba(2, 1, 6, 0.85) 100%);
  animation: vignette-breathe 6.5s ease-in-out infinite;
  mix-blend-mode: multiply;
}
@keyframes vignette-breathe {
  0%, 100% { transform: scale(1.04); opacity: 0.85; }
  50%      { transform: scale(0.92); opacity: 1;    }
}
@media (prefers-reduced-motion: reduce) {
  .page-vignette { animation: none; }
}

/* ---- Baroque pearl ornament above the studio mark ----
   Compact pearl-cluster crowning the EXR / ELIQUA wordmark from above-
   and-slightly-behind. Crops the wider ribbon image to a focused section
   so we see one cluster of pearls + a gem, not the whole strand. Soft
   radial mask so edges fade smoothly. */
.studio-mark { isolation: isolate; }
.studio-mark::before {
  content: "";
  position: absolute;
  /* Large diagonal pearl-ribbon backdrop, rotated -54.5° so the ribbon
     flows from upper-right to lower-left behind the wordmark.
     Tuned via tools/teaser-website-logo-editor/ornament.html. */
  top:    -6.45em;
  left:   -4em;
  width:  22em;
  height: 12em;
  background-image: url("assets/baroque-backdrop.png");
  background-size: 145% auto;
  background-position: 20% 49%;
  background-repeat: no-repeat;
  z-index: -1;
  opacity: var(--pearl-ornament-opacity, 0.79);
  mix-blend-mode: soft-light;
  pointer-events: none;
  transform: rotate(-54.5deg);
  -webkit-mask-image: radial-gradient(ellipse 85% 78% at center, black 0%, transparent 66%);
          mask-image: radial-gradient(ellipse 85% 78% at center, black 0%, transparent 66%);
}
/* Modern browsers: prefer WebP (6x smaller). Old browsers stay on PNG. */
@supports (background-image: image-set(url("a") type("image/webp"))) {
  .studio-mark::before {
    background-image: image-set(
      url("assets/baroque-backdrop.webp") type("image/webp"),
      url("assets/baroque-backdrop.png")  type("image/png")
    );
  }
}

.page-grain {
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.4' numOctaves='2' seed='3'/><feColorMatrix values='0 0 0 0 0.92  0 0 0 0 0.86  0 0 0 0 0.74  0 0 0 0.06 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
  z-index: -1;
  opacity: var(--grain-opacity, 0.55);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* page-patina — mottled tarnish/stain layer that adds decay across
   the whole page. Warm sepia-umber patches simulate aged plaster and
   candle-soot; cooler dark patches read as smoke-darkened corners.
   Multiply blend darkens the bg unevenly (the "stained wall" feel).
   Sits between page-vignette and page-grain in the layer stack. */
.page-patina {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    /* warm umber stains — sepia aging blooms */
    radial-gradient(ellipse 26% 22% at  8% 22%, rgba(110, 75, 45, 0.32), transparent 65%),
    radial-gradient(ellipse 22% 20% at 92% 68%, rgba( 95, 65, 40, 0.28), transparent 65%),
    radial-gradient(ellipse 30% 18% at 38% 92%, rgba( 80, 55, 35, 0.24), transparent 65%),
    radial-gradient(ellipse 18% 16% at 72% 12%, rgba(120, 85, 55, 0.20), transparent 65%),
    /* cool soot patches — smoke-darkening at opposite corners */
    radial-gradient(ellipse 24% 20% at 78% 18%, rgba( 16, 14, 30, 0.42), transparent 65%),
    radial-gradient(ellipse 26% 22% at 18% 78%, rgba( 12, 10, 24, 0.38), transparent 65%),
    radial-gradient(ellipse 20% 18% at 50% 50%, rgba( 18, 14, 32, 0.18), transparent 70%);
  mix-blend-mode: multiply;
  opacity: 0.85;
}

/* === studio mark (top-left) === */
.studio-mark {
  position: fixed;
  top: clamp(20px, 3vw, 36px);
  left: clamp(20px, 3vw, 40px);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 14px;
}

/* slide-in studio menu \u2014 reveals from behind the wordmark on hover/focus.
   A small bridge of padding keeps the hover live as the cursor crosses
   from the logo into the menu items. */
.studio-menu {
  position: relative;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-12px);
  transition: opacity 240ms var(--ease, ease), transform 320ms var(--ease, ease);
}
.studio-mark:hover .studio-menu,
.studio-mark:focus-within .studio-menu {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}
.studio-menu ul {
  list-style: none;
  margin: 0;
  padding: 8px 14px 8px 16px;
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.6vw, 26px);
  border-left: 1px solid rgba(201, 168, 101, 0.28);
}
.studio-menu a {
  font-family: var(--font-utility, var(--font-display));
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gilt-dim, #8a7242);
  text-decoration: none;
  padding: 4px 0;
  position: relative;
  transition: color 200ms ease;
  white-space: nowrap;
}
.studio-menu a::after {
  content: "";
  position: absolute;
  left: 0; right: 100%;
  bottom: 0;
  height: 1px;
  background: var(--gilt-bright, #e7c479);
  transition: right 260ms var(--ease, ease);
}
.studio-menu a:hover,
.studio-menu a:focus-visible {
  color: var(--gilt-bright, #e7c479);
  outline: none;
}
.studio-menu a:hover::after,
.studio-menu a:focus-visible::after {
  right: 0;
}
@media (max-width: 640px) {
  .studio-menu { display: none; }
}

/* logo CSS variables — overridden by Tweaks */
:root {
  --logo-gilt:        var(--gilt);
  --logo-gilt-dim:    var(--gilt-dim);
  --logo-cream:       var(--cream);
  --logo-cosmic:      var(--cosmic);
  --logo-cosmic-opacity: 0.85;
}

.studio-link {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 6px;
  transition: opacity var(--med);
  text-decoration: none;
}

.studio-link:hover,
.studio-link:focus-visible { outline: none; }

.studio-glyph-mount {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  flex: none;
  transition: opacity var(--med);
}
.studio-glyph-mount svg { width: 100%; height: 100%; display: block; }

.studio-wordmark {
  display: inline-flex; flex-direction: column;
  line-height: 1; gap: 3px;
}
.studio-word {
  font-family: var(--font-display);
  text-transform: uppercase;
  transition: color var(--med), letter-spacing var(--slow);
}
.studio-word--ex {
  font-weight: 400;
  font-size: 0.62rem;
  letter-spacing: 0.42em;
  color: var(--gilt);
}
.studio-word--reliqua {
  font-weight: 700;
  font-size: 0.92rem;
  letter-spacing: 0.18em;
  color: var(--cream);
}
.studio-link:hover .studio-word--ex,
.studio-link:focus-visible .studio-word--ex { color: var(--gilt-bright); letter-spacing: 0.46em; }
.studio-link:hover .studio-word--reliqua,
.studio-link:focus-visible .studio-word--reliqua { color: var(--gilt-bright); letter-spacing: 0.22em; }

/* ---- Header stylization: EXR / ELIQUA monogram lockup
   Layout reverse-engineered from CD's design + the user's
   pixel-perfect tweaks in the visual editor (May 2026).

   Every dimension, position, and type-size is expressed as a
   ratio of a single base unit (--u) so the entire mark scales
   uniformly when --u changes. X is exactly 1 × --u; everything
   else is a fraction of that.

   The pixel-perfect spec was:
     E      Cinzel       27.5px       (= 0.557 × --u)
     X      Cinzel-Dec   49.4px       (= 1.000 × --u)   <- anchor
     R      Cinzel-Dec   49.4px       (= 1.000 × --u)
     ELIQUA Cinzel       15.96px      (= 0.323 × --u)
   …with X+R overlap, E baselined to X-top, ELIQUA baselined to R-bottom.
*/
.studio-wordmark[data-style="xr-stack"] {
  --u: clamp(34px, 4vw, 49.4px); /* base unit; bump everything together */
  position: relative;
  display: inline-block;
  width:  calc(3.40 * var(--u));
  height: calc(1.65 * var(--u));
  font-size: var(--u);
  font-family: var(--font-display);
  vertical-align: middle;
  /* Group transform — moves the whole wordmark as one unit.
     Tuned via studio-mark-editor.html. */
  transform: translate(-26px, -20px) scale(1.22);
  transform-origin: 0 50%;
}
.studio-wordmark[data-style="xr-stack"] .studio-letter {
  position: absolute;
  display: block;
  text-transform: uppercase;
  line-height: 1;
  margin: 0;
  transition: color var(--med);
}

/* E ─ small Cinzel regular, gilt-bright, anchored at the top
   so its cap-height aligns with X's cap-height. */
.studio-wordmark[data-style="xr-stack"] .studio-letter--e {
  top:    0;
  left:   calc(0.181 * var(--u));
  width:  calc(0.57 * var(--u));
  font-family: "Cinzel", "Cinzel Decorative", serif;
  font-weight: 500;
  font-size:      calc(0.557 * var(--u));
  letter-spacing: calc(0.065 * var(--u));
  color: #e0c081;
  text-align: center;
}

/* ELIQUA ─ small Cinzel regular, gilt-bright, baselined to R-bottom. */
.studio-wordmark[data-style="xr-stack"] .studio-letter--eliqua {
  bottom: calc(0.625 * var(--u));
  left:   calc(1.456 * var(--u));
  width:  calc(1.62 * var(--u));
  font-family: "Cinzel", "Cinzel Decorative", serif;
  font-weight: 500;
  font-size:      calc(0.323 * var(--u));
  letter-spacing: calc(0.052 * var(--u));
  color: #e0c081;
  text-align: left;
}

/* X ─ large italic Cinzel Decorative, gold-leaf metallic with sheen.
   Padding-right reserves space for the italic terminal so the
   embellishment isn't clipped. */
.studio-wordmark[data-style="xr-stack"] .studio-letter--x {
  /* Box shifted -5px top/left + 5px padding all sides keeps the
     glyph at its original position but gives the embellishments
     5px more breathing room every direction. Right padding stacks
     on top of the existing italic-terminal allowance. */
  top:           calc(-0.141 * var(--u));
  left:          calc(0.288 * var(--u));
  width:         calc(1.21 * var(--u));
  font-family:   "Cinzel Decorative", "Cinzel", "Trajan Pro", serif;
  font-weight:   700;
  font-style:    italic;
  font-size:     var(--u);
  line-height:   0.85;
  letter-spacing: 0;
  padding:       calc(0.141 * var(--u))    /* top    : 7px */
                 calc(0.502 * var(--u))    /* right  : 7px embellishment + 4px more */
                 calc(0.162 * var(--u))    /* bottom : 8px (unchanged) */
                 calc(0.141 * var(--u));   /* left   : 7px */
  color: #ffffff;
  background:
    linear-gradient(115deg,
      transparent 0%, transparent 38%,
      rgba(255, 248, 214, 0.95) 50%,
      transparent 62%, transparent 100%) 0 0 / 220% 100% no-repeat,
    linear-gradient(180deg,
      #fff8d8 0%,
      #f0d294 28%,
      #d6b676 58%,
      #a48a58 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.45);
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.7));
  z-index: 1;
  overflow: visible;
  animation: xr-sheen 6.5s ease-in-out infinite;
}

/* R ─ large italic Cinzel Decorative, metallic, overlaps X
   to the lower-right. */
.studio-wordmark[data-style="xr-stack"] .studio-letter--r {
  top:           calc(0.509 * var(--u));
  left:          calc(0.686 * var(--u));
  width:         calc(1.13 * var(--u));
  font-family:   "Cinzel Decorative", "Cinzel", "Trajan Pro", serif;
  font-weight:   700;
  font-style:    italic;
  font-size:     var(--u);
  line-height:   0.85;
  letter-spacing: 0;
  padding-right:  calc(0.201 * var(--u));   /* italic-terminal allowance + 4px more */
  padding-bottom: calc(0.061 * var(--u));   /* 3px breathing room below baseline */
  color: #fffefe;
  background:
    linear-gradient(115deg,
      transparent 0%, transparent 38%,
      rgba(255, 248, 214, 0.95) 50%,
      transparent 62%, transparent 100%) 0 0 / 220% 100% no-repeat,
    linear-gradient(180deg,
      #fff8d8 0%,
      #f0d294 28%,
      #d6b676 58%,
      #a48a58 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.45);
  filter: drop-shadow(0 -2px 4px rgba(0, 0, 0, 0.75)) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.5));
  z-index: 2;
  overflow: visible;
  animation: xr-sheen 6.5s ease-in-out infinite;
}

@keyframes xr-sheen {
  0%   { background-position: 200% 0, 0 0; }
  60%  { background-position: -100% 0, 0 0; }
  100% { background-position: -100% 0, 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .studio-wordmark[data-style="xr-stack"] .studio-letter--x,
  .studio-wordmark[data-style="xr-stack"] .studio-letter--r { animation: none; }
}

/* Hover: monogram lifts to brightest gilt; small letters lift to cream-cosmic. */
.studio-link:hover .studio-wordmark[data-style="xr-stack"] .studio-letter--x,
.studio-link:hover .studio-wordmark[data-style="xr-stack"] .studio-letter--r,
.studio-link:focus-visible .studio-wordmark[data-style="xr-stack"] .studio-letter--x,
.studio-link:focus-visible .studio-wordmark[data-style="xr-stack"] .studio-letter--r {
  background:
    linear-gradient(180deg,
      #fff8d8 0%,
      var(--gilt-bright, #e7c479) 35%,
      var(--gilt, #c9a865) 100%);
  -webkit-background-clip: text;
          background-clip: text;
}
.studio-link:hover .studio-wordmark[data-style="xr-stack"] .studio-letter--e,
.studio-link:hover .studio-wordmark[data-style="xr-stack"] .studio-letter--eliqua,
.studio-link:focus-visible .studio-wordmark[data-style="xr-stack"] .studio-letter--e,
.studio-link:focus-visible .studio-wordmark[data-style="xr-stack"] .studio-letter--eliqua {
  color: #fff8d8;
}

/* Footer mark — seal lockup, larger seal, small wordmark, socials */
.footer-seal {
  display: inline-flex; align-items: center; gap: 0.85em;
  text-decoration: none;
}
.footer-glyph--seal { width: 56px; height: 56px; flex: none; opacity: 1; }
.footer-glyph--seal svg.logo-glyph--seal { overflow: visible; }
.footer-glyph--seal .logo-seal-ring {
  transform-origin: 16px 16px;
  transition: animation 1.6s var(--ease);
  animation: seal-drift 80s linear infinite;
}
.footer-seal:hover .logo-seal-ring,
.footer-seal:focus-visible .logo-seal-ring,
.footer-glyph-mount:hover .logo-seal-ring {
  animation: seal-spin 5s linear infinite;
}
@keyframes seal-drift { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes seal-spin  { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

.footer-mark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 0.6rem;
  letter-spacing: 0.34em;
  color: var(--gilt);
  transition: color var(--med);
}
.footer-seal:hover .footer-mark,
.footer-seal:focus-visible .footer-mark { color: var(--gilt-bright); }

.footer-socials {
  display: inline-flex; align-items: center; gap: 18px;
  margin-left: auto;
}
.social {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  color: var(--gilt);
  opacity: 0.85;
  transition: color var(--med), opacity var(--med), transform var(--med);
}
.social svg { width: 100%; height: 100%; display: block; }
.page-mist {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: 65vh;
  pointer-events: none;
  z-index: 4;
  /* baseline 0.18 (always faintly visible) + ramps with scroll */
  opacity: calc(0.18 + var(--scroll-progress, 0) * 0.82);
  background:
    radial-gradient(ellipse 80% 60% at 50% 100%, rgba(60, 52, 110, 0.55), transparent 70%),
    radial-gradient(ellipse 110% 55% at 50% 105%, rgba(120, 100, 80, 0.18), transparent 80%),
    linear-gradient(180deg, transparent 0%, rgba(8, 6, 18, 0.55) 60%, rgba(8, 6, 18, 0.85) 100%);
  mix-blend-mode: screen;
  transition: opacity 600ms var(--ease);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, black 35%, black 100%);
          mask-image: linear-gradient(180deg, transparent 0%, black 35%, black 100%);
}
.page-mist::before, .page-mist::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  mix-blend-mode: screen;
}
.page-mist::before {
  width: 70vw; height: 30vh;
  left: -10vw; bottom: -10vh;
  background: radial-gradient(circle, rgba(216, 212, 240, 0.18), transparent 65%);
  animation: mist-drift-l 28s ease-in-out infinite alternate;
}
.page-mist::after {
  width: 65vw; height: 28vh;
  right: -8vw; bottom: -6vh;
  background: radial-gradient(circle, rgba(201, 168, 101, 0.12), transparent 65%);
  animation: mist-drift-r 34s ease-in-out infinite alternate;
}
@keyframes mist-drift-l { 0% { transform: translate(0, 0) scale(1); } 100% { transform: translate(8vw, -3vh) scale(1.1); } }
@keyframes mist-drift-r { 0% { transform: translate(0, 0) scale(1); } 100% { transform: translate(-6vw, -4vh) scale(1.08); } }

/* breath motes — small drifting particles that fall slowly and pool
   at the bottom of the viewport. Always visible but intensify with
   scroll. Sit inside .page-mist (which is fixed, bottom: 0). */
.mote {
  position: absolute;
  display: block;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(232, 220, 188, 0.85) 0%, rgba(224, 192, 129, 0.45) 50%, transparent 75%);
  filter: blur(1.4px);
  mix-blend-mode: screen;
  opacity: 0;
  will-change: transform, opacity;
  animation: mote-fall 14s linear infinite;
}
.mote--1  { left:  6%; width: 5px;  height: 5px;  animation-duration: 16s; animation-delay:  -1s; }
.mote--2  { left: 14%; width: 3px;  height: 3px;  animation-duration: 22s; animation-delay:  -7s; }
.mote--3  { left: 22%; width: 7px;  height: 7px;  animation-duration: 19s; animation-delay: -12s; }
.mote--4  { left: 30%; width: 4px;  height: 4px;  animation-duration: 17s; animation-delay:  -3s; }
.mote--5  { left: 38%; width: 6px;  height: 6px;  animation-duration: 24s; animation-delay: -18s; }
.mote--6  { left: 47%; width: 3px;  height: 3px;  animation-duration: 15s; animation-delay:  -9s; }
.mote--7  { left: 54%; width: 8px;  height: 8px;  animation-duration: 26s; animation-delay: -14s; }
.mote--8  { left: 63%; width: 4px;  height: 4px;  animation-duration: 18s; animation-delay:  -2s; }
.mote--9  { left: 71%; width: 5px;  height: 5px;  animation-duration: 21s; animation-delay: -16s; }
.mote--10 { left: 79%; width: 6px;  height: 6px;  animation-duration: 23s; animation-delay:  -5s; }
.mote--11 { left: 87%; width: 3px;  height: 3px;  animation-duration: 17s; animation-delay: -11s; }
.mote--12 { left: 93%; width: 5px;  height: 5px;  animation-duration: 20s; animation-delay: -19s; }
@keyframes mote-fall {
  0%   { transform: translate(0, -10vh); opacity: 0; }
  10%  { opacity: 0.55; }
  60%  { opacity: 0.85; }
  85%  { opacity: 0.7; }
  100% { transform: translate(calc(var(--mote-drift, 12px)), 65vh); opacity: 0; }
}
.mote--2  { --mote-drift: -22px; }
.mote--3  { --mote-drift:  18px; }
.mote--5  { --mote-drift: -14px; }
.mote--7  { --mote-drift:  24px; }
.mote--9  { --mote-drift: -18px; }
.mote--11 { --mote-drift:  16px; }
@media (prefers-reduced-motion: reduce) {
  .page-mist::before, .page-mist::after { animation: none; }
  .mote { animation: none; opacity: 0.4; }
}

.social:hover, .social:focus-visible {
  color: var(--gilt-bright);
  opacity: 1;
  transform: translateY(-1px);
}
.footer-rule {
  display: inline-block; width: 1px; height: 1.4em;
  background: linear-gradient(180deg, transparent, rgba(201,168,101,0.35), transparent);
  margin: 0 0.4em;
}

/* === breath layer (rolling cosmic fog behind everything) === */
.logo-cosmic { opacity: var(--logo-cosmic-opacity, 0.85); transition: opacity 700ms var(--ease); }

.page-breath {
  position: fixed; inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: var(--breath-intensity, 0.7);
  mix-blend-mode: screen;
  transition: opacity 800ms var(--ease);
}
.breath-cloud {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  will-change: transform, opacity;
}
.breath-cloud--1 {
  width: 70vw; height: 70vw; left: -20vw; top: -20vw;
  background: radial-gradient(circle, rgba(60, 50, 130, 0.55), transparent 60%);
  animation: breath-drift-a 38s ease-in-out infinite alternate;
}
.breath-cloud--2 {
  width: 60vw; height: 60vw; right: -10vw; top: 30vh;
  background: radial-gradient(circle, rgba(120, 90, 60, 0.32), transparent 60%);
  animation: breath-drift-b 52s ease-in-out infinite alternate;
}
.breath-cloud--3 {
  width: 50vw; height: 50vw; left: 10vw; bottom: -10vw;
  background: radial-gradient(circle, rgba(80, 60, 110, 0.45), transparent 60%);
  animation: breath-drift-c 46s ease-in-out infinite alternate;
}
.breath-cloud--4 {
  width: 38vw; height: 38vw; right: 12vw; bottom: 18vh;
  background: radial-gradient(circle, rgba(216, 212, 240, 0.18), transparent 60%);
  animation: breath-drift-d 60s ease-in-out infinite alternate;
}
@keyframes breath-drift-a {
  0%   { transform: translate(0, 0)         scale(1);   opacity: 0.55; }
  50%  { transform: translate(8vw, 6vh)     scale(1.15); opacity: 0.85; }
  100% { transform: translate(-4vw, 10vh)   scale(0.95); opacity: 0.6;  }
}
@keyframes breath-drift-b {
  0%   { transform: translate(0, 0)         scale(1);   opacity: 0.45; }
  50%  { transform: translate(-10vw, -8vh)  scale(1.1);  opacity: 0.7;  }
  100% { transform: translate(6vw, 4vh)     scale(0.95); opacity: 0.5;  }
}
@keyframes breath-drift-c {
  0%   { transform: translate(0, 0)         scale(1);   opacity: 0.5;  }
  50%  { transform: translate(12vw, -6vh)   scale(1.12); opacity: 0.75; }
  100% { transform: translate(-6vw, 4vh)    scale(0.9);  opacity: 0.55; }
}
@keyframes breath-drift-d {
  0%   { transform: translate(0, 0)         scale(1);   opacity: 0.4;  }
  50%  { transform: translate(-8vw, 8vh)    scale(1.2);  opacity: 0.7;  }
  100% { transform: translate(4vw, -6vh)    scale(1);    opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .breath-cloud { animation: none; opacity: 0.5; }
}

/* === atmospheric breath ===================================== */
.hero-stars {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
}
.hero-star {
  position: absolute; width: 2px; height: 2px; border-radius: 50%;
  background: #d8d4f0; opacity: 0;
  box-shadow: 0 0 6px rgba(216, 212, 240, 0.7);
  animation: star-pulse 5.4s ease-in-out infinite;
}
.hero-star--1 { top: 12%; left: 14%; animation-delay: 0s; }
.hero-star--2 { top: 22%; left: 78%; animation-delay: 1.4s; width: 1.5px; height: 1.5px; }
.hero-star--3 { top: 36%; left: 9%;  animation-delay: 2.8s; width: 1.2px; height: 1.2px; }
.hero-star--4 { top: 58%; left: 84%; animation-delay: 0.6s; width: 1.6px; height: 1.6px; }
.hero-star--5 { top: 70%; left: 18%; animation-delay: 2.0s; width: 1.4px; height: 1.4px; }
.hero-star--6 { top: 14%; left: 52%; animation-delay: 3.4s; width: 1px;   height: 1px;   }
.hero-star--7 { top: 80%; left: 62%; animation-delay: 4.2s; width: 1.2px; height: 1.2px; }
@keyframes star-pulse {
  0%, 100% { opacity: 0; transform: scale(0.6); }
  50%      { opacity: 0.85; transform: scale(1); }
}
.hero-flourish {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: clamp(24px, 4vw, 48px); height: clamp(220px, 36vh, 360px);
  pointer-events: none; z-index: 0;
  animation: flourish-breath 7.5s ease-in-out infinite;
}
.hero-flourish--l { left: clamp(20px, 6vw, 96px); }
.hero-flourish--r { right: clamp(20px, 6vw, 96px); animation-delay: 1.2s; }
@keyframes flourish-breath {
  0%, 100% { opacity: 0.55; transform: translateY(-50%) scaleY(1); }
  50%      { opacity: 0.85; transform: translateY(-50%) scaleY(1.02); }
}
.tagline { position: relative; }
.tagline-bracket {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(201,168,101,0.5), transparent);
}
.tagline-bracket--l { right: calc(100% + 14px); }
.tagline-bracket--r { left:  calc(100% + 14px); background: linear-gradient(90deg, transparent, rgba(201,168,101,0.5), transparent); }
@media (max-width: 640px) { .tagline-bracket { display: none; } .hero-flourish { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .hero-star, .hero-flourish { animation: none; opacity: 0.55; }
}

/* Mobile media query moved to the end of the file so it always wins
   the cascade against any later-defined desktop rules. */

/* === hero === */
.hero {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(80px, 12vh, 160px) clamp(20px, 4vw, 48px) clamp(60px, 10vh, 120px);
  position: relative;
}

/* a faint cathedral light-column behind the wordmark */
.hero::after {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: clamp(280px, 50vw, 720px);
  height: 100%;
  background:
    radial-gradient(ellipse 30% 60% at 50% 50%, rgba(201, 168, 101, 0.06), transparent 70%),
    radial-gradient(ellipse 12% 80% at 50% 30%, rgba(216, 212, 240, 0.04), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

.hero-frame {
  text-align: center;
  position: relative;
  z-index: 1;
}

.wordmark {
  position: relative;
  display: inline-block;
  font-family: "Cinzel Decorative", var(--font-display);
  font-weight: 700;
  font-style: italic;
  font-size: clamp(6rem, 12vw, 9rem);
  letter-spacing: 0.06em;
  line-height: 1.2;
  /* padding: top  right  bottom  left — extra right-pad so the italic
     N-terminal swash doesn't clip */
  padding: 0.18em 0.85em 0.18em 0.4em;
  margin-left: 0.06em;
  text-shadow: 0 0 70px rgba(201, 168, 101, 0.06);
  animation: wordmark-breathe 4.3s ease-in-out infinite;
}

.wordmark-glow {
  position: absolute;
  inset: 0;
  color: transparent;
  /* Tarnished-gilt halo — deeper dusty umber per title-editor tune. */
  background: radial-gradient(ellipse 80% 100% at 50% 50%,
    rgba(101, 70, 47, 0.55),
    transparent 70%);
  -webkit-background-clip: text;
          background-clip: text;
  pointer-events: none;
  animation: wordmark-glow-pulse 6.2s ease-in-out infinite;
}

/* Tarnished-gilt fill — clean 6-stop vertical gradient sampled from
   the painted hero_ornament. The 40% stop is intentionally lifted
   toward a warm peach-coral (#ffc18f) for a candle-warmth highlight
   in the upper-middle of the letters. */
.wordmark-fill {
  position: relative;
  background: linear-gradient(180deg,
    #e3cb98   0%,
    #ba9266  20%,
    #ffc18f  40%,    /* warm peach-coral highlight */
    #7b5f3c  60%,
    #6e4e34  82%,
    #5c4732 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

@keyframes wordmark-breathe {
  0%, 100% { opacity: 0.86; transform: translateY(0);    filter: brightness(0.92); }
  50%      { opacity: 1;    transform: translateY(-3px); filter: brightness(1.08); }
}

@keyframes wordmark-glow-pulse {
  0%, 100% { opacity: 1;    filter: blur(0px); }
  50%      { opacity: 0.84; filter: blur(6px); }
}

/* Sheen — bright diagonal band swept across the wordmark via
   background-position animation. Layered on top of wordmark-fill so the
   gilt + tarnish texture stays intact underneath. Modeled on the XR
   studio mark's sheen pattern but tuned for the wider VELUN canvas
   (softer band, slower pace). */
.wordmark-sheen {
  position: absolute;
  inset: 0;
  color: transparent;
  /* Softer + wider sheen band, leaning closer to vertical (27deg) per
     title-editor tune. Peak alpha 0.25 keeps it subtle. */
  background: linear-gradient(27deg,
    transparent 0%,
    transparent 35%,
    rgba(255, 245, 210, 0.16) 46.25%,
    rgba(255, 248, 220, 0.25) 50%,
    rgba(255, 245, 210, 0.16) 53.75%,
    transparent 65%,
    transparent 100%) 0 0 / 240% 100% no-repeat;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  pointer-events: none;
  animation: wordmark-sheen-sweep 7.9s ease-in-out infinite;
}

@keyframes wordmark-sheen-sweep {
  0%   { background-position: 240% 0; opacity: 0.95; }
  55%  { background-position: -140% 0; opacity: 0.95; }
  60%  { background-position: -140% 0; opacity: 0; }
  100% { background-position: -140% 0; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .wordmark-sheen { animation: none; opacity: 0; }
}

.tagline {
  margin-top: clamp(1.6em, 3vh, 2.6em);
  font-family: var(--font-body);
  font-size: clamp(1.05rem, 1.5vw, 1.4rem);
  font-weight: 300;
  line-height: 1.75;
  color: var(--cream-dim);
  letter-spacing: 0.04em;
  max-width: 38em;
  margin-inline: auto;
}

.tagline em {
  font-style: italic;
  color: var(--cream);
  display: inline-block;
  margin-top: 0.4em;
  font-weight: 400;
}

.hero-ornament-pic {
  display: block;
  margin: clamp(2em, 6vh, 4em) auto 0;
  text-align: center;
}
.hero-ornament {
  display: inline-block;
  width: clamp(280px, 40vw, 540px);
  height: auto;
  opacity: 0.82;
  pointer-events: none;
  user-select: none;
}

/* Section dividers — painterly decayed-gilt ornament between major
   sections. Replaces the old <hr class="ornament-rule">. Asset's
   own alpha shapes the visible ornament; the rest is transparent. */
.section-divider-pic {
  display: block;
  margin: clamp(2.5em, 7vh, 5em) auto;
  text-align: center;
}
.section-divider {
  display: inline-block;
  height: auto;
  width: clamp(320px, 50vw, 720px);
  opacity: 0.78;
  pointer-events: none;
  user-select: none;
}

.hero-scroll-cue {
  position: absolute;
  bottom: clamp(28px, 5vh, 48px);
  left: 50%;
  transform: translateX(-50%);
  width: 1px;
  height: 56px;
  background: linear-gradient(180deg, transparent 0%, rgba(201, 168, 101, 0.4) 100%);
  pointer-events: none;
}

.hero-scroll-cue span {
  position: absolute;
  bottom: -3px;
  left: -2.5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gilt);
  opacity: 0.6;
  animation: scroll-drip 3.4s var(--ease) infinite;
}

@keyframes scroll-drip {
  0%   { transform: translateY(-56px); opacity: 0; }
  20%  { opacity: 0.7; }
  80%  { opacity: 0.6; }
  100% { transform: translateY(0);     opacity: 0; }
}

/* === pitch === */
.pitch {
  padding: clamp(80px, 14vh, 160px) clamp(20px, 4vw, 48px);
  display: grid;
  place-items: center;
}

.pitch-column {
  max-width: var(--col-narrow);
  text-align: center;
  font-size: clamp(1.05rem, 1.4vw, 1.32rem);
  line-height: 1.85;
  letter-spacing: 0.018em;
  color: var(--cream-dim);
  font-weight: 300;
  position: relative;
  isolation: isolate;
}

/* Alpha-gradient reading-card backdrop — soft fade in at the top, solid
   middle, soft fade out at the bottom. Sits behind the liturgical
   paragraphs so they read clearly above the page mist + grain. No blur
   (glass-morphism is out of register); just a vignette-style alpha wash.
   Horizontal extension uses clamp() so the backdrop reaches further into
   the page margins at wide viewports but pulls in cleanly on mobile. */
.pitch-column::before {
  content: "";
  position: absolute;
  inset: -1.6em clamp(-3em, -6vw, -7em);
  background: linear-gradient(90deg,
      rgba(7, 5, 14, 0)    0%,
      rgba(7, 5, 14, 0.55) 12%,
      rgba(7, 5, 14, 0.65) 50%,
      rgba(7, 5, 14, 0.55) 88%,
      rgba(7, 5, 14, 0)    100%),
    linear-gradient(180deg,
      rgba(7, 5, 14, 0)    0%,
      rgba(7, 5, 14, 0.55) 22%,
      rgba(7, 5, 14, 0.65) 50%,
      rgba(7, 5, 14, 0.55) 78%,
      rgba(7, 5, 14, 0)    100%);
  border-radius: 14px;
  pointer-events: none;
  z-index: -1;
}

.pitch-column p {
  margin-bottom: 1.7em;
}

.pitch-column p:last-child { margin-bottom: 0; }

.pitch-final {
  margin-top: 2.4em !important;
  color: var(--cream);
  font-size: 1.06em;
  letter-spacing: 0.04em;
  position: relative;
  font-weight: 400;
}

.pitch-final::before {
  content: "";
  display: block;
  width: 40px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gilt-dim), transparent);
  margin: 0 auto 1.6em;
}

/* === ornament rule === */
.ornament-rule {
  border: 0;
  height: 32px;
  width: clamp(120px, 30vw, 240px);
  margin: 0 auto;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 32'><line x1='0' y1='16' x2='90' y2='16' stroke='%23c9a865' stroke-width='0.5' opacity='0.4'/><circle cx='108' cy='16' r='1.4' fill='%23c9a865'/><circle cx='120' cy='10' r='0.9' fill='%23d8d4f0'/><circle cx='132' cy='16' r='1.4' fill='%23c9a865'/><line x1='150' y1='16' x2='240' y2='16' stroke='%23c9a865' stroke-width='0.5' opacity='0.4'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

/* === companions === */
.companions {
  padding: clamp(60px, 10vh, 120px) clamp(20px, 4vw, 48px) clamp(80px, 12vh, 140px);
  max-width: var(--max);
  margin: 0 auto;
}

.section-heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.7rem, 3.6vw, 2.6rem);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--cream);
  text-align: center;
  margin-bottom: 0.45em;
  padding-left: 0.34em;
}

.section-heading::after {
  content: "";
  display: block;
  width: 32px;
  height: 1px;
  background: var(--gilt-dim);
  margin: 0.7em auto 0;
}

.section-sub {
  text-align: center;
  font-style: italic;
  font-weight: 300;
  font-size: 1.05rem;
  color: var(--cream-faint);
  letter-spacing: 0.05em;
  margin-bottom: clamp(3em, 6vh, 5em);
}

.companion-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(40px, 4vw, 64px) clamp(28px, 3vw, 48px);
}

@media (max-width: 920px) {
  .companion-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .companion-grid {
    grid-template-columns: minmax(0, 1fr);
    max-width: 360px;
    margin-inline: auto;
    gap: 48px;
  }
}

.companion {
  text-align: center;
  position: relative;
  outline: none;
  transition: transform var(--slow);
  /* 18px padding all around so painted card_frame can extend outward
     past the card boundary without overlapping neighbor cards. */
  padding: 18px;
}

.companion:hover,
.companion:focus-visible,
.companion:focus-within {
  transform: translateY(-4px);
}
.companion:hover .niche-floor,
.companion:focus-visible .niche-floor,
.companion:focus-within .niche-floor {
  width: 72%;
}
.companion:hover .plate-rule,
.companion:focus-visible .plate-rule,
.companion:focus-within .plate-rule {
  background: linear-gradient(90deg, transparent, var(--gilt-bright), transparent);
  width: 70%;
}
.plate-rule { transition: background var(--med), width var(--med); }

/* === card flip mechanic ===
   Each companion card slowly spins around its vertical axis. The bust
   portrait lives on the front face; the back face holds the per-companion
   motif (added in a later pass). Hovering / focusing the card halts the
   spin and snaps the front face into view. */
.companion-card {
  /* --card-thickness controls perceived cardboard depth in the 3D spin. */
  --card-thickness: 16px;
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  margin-bottom: clamp(1.2em, 2.5vh, 1.8em);
  perspective: 1200px;
}

/* Ground shadow beneath the card — lives outside the 3D rotation
   context (it's on .companion-card not .companion-card-inner) so it
   stays flat against the page and reads as the card's weight + light. */
.companion-card::after {
  content: "";
  position: absolute;
  bottom: -20px;
  left: 10%;
  right: 10%;
  height: 22px;
  background: radial-gradient(ellipse 50% 100% at 50% 0%,
    rgba(0, 0, 0, 0.65) 0%,
    rgba(0, 0, 0, 0.22) 45%,
    transparent 75%);
  filter: blur(5px);
  z-index: -1;
  pointer-events: none;
}

.companion-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  animation: card-spin 22s linear infinite;
  transition: transform 600ms cubic-bezier(.25, .65, .35, 1);
}
@keyframes card-spin {
  0%   { transform: rotateY(0deg); }
  100% { transform: rotateY(360deg); }
}

/* Card cardboard side-faces — perpendicular strips that span the front-
   to-back thickness. Visible during the rotation as the actual cardstock
   edge (gilt highlight catching front-edge light, fading to dark sepia
   at the back). */
.companion-card-inner::before,
.companion-card-inner::after {
  content: "";
  position: absolute;
  top: 0;
  width: var(--card-thickness);
  height: 100%;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(186, 146, 102, 0.85) 0%,   /* gilt highlight edge */
    rgba(123,  95,  60, 0.95) 32%,  /* tarnished mid */
    rgba( 60,  42,  26, 1.00) 72%,  /* deep umber */
    rgba( 35,  24,  16, 1.00) 100%  /* deep sepia */
  );
  /* No backface-visibility: hidden here — the side strips need to read
     from both halves of the spin to maintain continuous cardboard depth.
     The painted-frame artifact fix lives on the frame/tear pseudos, not
     these structural side faces. */
}
.companion-card-inner::before {
  /* RIGHT side face */
  right: 0;
  transform-origin: 100% 50%;
  transform: rotateY(-90deg) translateZ(calc(var(--card-thickness) / 2));
}
.companion-card-inner::after {
  /* LEFT side face */
  left: 0;
  transform-origin: 0 50%;
  transform: rotateY(90deg) translateZ(calc(var(--card-thickness) / 2));
}

.companion-card-front,
.companion-card-back {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}
/* Push front face forward + back face back by half-thickness — the
   cardstock now has actual depth, not just a flip animation. */
.companion-card-front {
  transform: translateZ(calc(var(--card-thickness) / 2));
}
.companion-card-back {
  transform: rotateY(180deg) translateZ(calc(var(--card-thickness) / 2));
}

/* Stagger animation start times so the 6 cards don't rotate in unison. */
.companion:nth-of-type(1) .companion-card-inner { animation-delay:   0s; }
.companion:nth-of-type(2) .companion-card-inner { animation-delay:  -3.6s; }
.companion:nth-of-type(3) .companion-card-inner { animation-delay:  -7.3s; }
.companion:nth-of-type(4) .companion-card-inner { animation-delay: -11.0s; }
.companion:nth-of-type(5) .companion-card-inner { animation-delay: -14.7s; }
.companion:nth-of-type(6) .companion-card-inner { animation-delay: -18.3s; }

/* Orin spins slightly faster — courier register, hint of motion. */
.companion[data-companion="orin"] .companion-card-inner {
  animation-duration: 14s;
}

/* Hover / focus locks the front face forward with a smooth transition. */
.companion:hover .companion-card-inner,
.companion:focus-within .companion-card-inner {
  animation: none;
  transform: rotateY(0deg);
}

/* Card-back niche styling — same base as the front but darker, more
   interior. Motif animations attach to .card-back-motif per companion. */
.silhouette-frame--back {
  background:
    radial-gradient(ellipse 50% 65% at 50% 45%, rgba(22, 20, 50, 0.7), transparent 80%),
    linear-gradient(180deg, rgba(12, 10, 28, 0.95), rgba(6, 4, 16, 1));
}
.card-back-motif {
  position: absolute;
  inset: 10%;
  z-index: 3;
  pointer-events: none;
  overflow: hidden;
}

/* ============================================================
   Card-back motif — unified across all six companions.
   A continuous drift of warm gilt-ochre particles, like dust
   falling through a chapel light shaft. Per-companion identity
   is carried by the niche-relic SVG above; the motif is the
   room's air, not the room's owner.
   ============================================================ */
.card-back-motif::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  /* Sickly bilious yellow-green — reads as chapel mildew / verdigris
     dust drifting through the niche. Sits in contrast with the gilt
     ring framework above, reinforcing the decayed-reliquary register. */
  background-image:
    radial-gradient(circle 2.5px at 8%  6%,  rgba(165, 185, 100, 0.82), transparent 70%),
    radial-gradient(circle 1.5px at 22% 18%, rgba(150, 175,  90, 0.62), transparent 70%),
    radial-gradient(circle 2px   at 36% 4%,  rgba(170, 188, 105, 0.78), transparent 70%),
    radial-gradient(circle 1px   at 48% 22%, rgba(155, 178,  95, 0.52), transparent 70%),
    radial-gradient(circle 2.5px at 60% 8%,  rgba(168, 186, 102, 0.80), transparent 70%),
    radial-gradient(circle 1.5px at 74% 16%, rgba(152, 175,  92, 0.62), transparent 70%),
    radial-gradient(circle 2px   at 88% 4%,  rgba(162, 182,  98, 0.76), transparent 70%),
    radial-gradient(circle 1.5px at 14% 38%, rgba(158, 180,  95, 0.60), transparent 70%),
    radial-gradient(circle 2px   at 32% 50%, rgba(165, 185, 100, 0.72), transparent 70%),
    radial-gradient(circle 1px   at 52% 42%, rgba(150, 172,  90, 0.52), transparent 70%),
    radial-gradient(circle 2.5px at 68% 36%, rgba(170, 188, 105, 0.78), transparent 70%),
    radial-gradient(circle 1.5px at 84% 48%, rgba(155, 178,  95, 0.62), transparent 70%),
    radial-gradient(circle 1px   at 12% 72%, rgba(148, 170,  88, 0.52), transparent 70%),
    radial-gradient(circle 2px   at 28% 84%, rgba(162, 182,  98, 0.68), transparent 70%),
    radial-gradient(circle 1.5px at 46% 76%, rgba(155, 178,  95, 0.60), transparent 70%),
    radial-gradient(circle 2px   at 64% 88%, rgba(168, 186, 102, 0.70), transparent 70%),
    radial-gradient(circle 1px   at 78% 82%, rgba(150, 172,  90, 0.50), transparent 70%),
    radial-gradient(circle 1.5px at 92% 90%, rgba(158, 180,  95, 0.58), transparent 70%);
  background-size: 100% 50%;
  background-repeat: repeat-y;
  animation: motif-niche-fall 9s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .card-back-motif::before {
    animation: none !important;
  }
}

@keyframes motif-niche-fall {
  0%   { background-position: 0% 0%;   }
  100% { background-position: 0% 100%; }
}

/* Stagger animation-delay per companion so the 6 cards aren't
   all dropping grains in unison — feels like six different rooms. */
.companion[data-companion="iren"]    .card-back-motif::before { animation-delay:  0s;   }
.companion[data-companion="sirael"]  .card-back-motif::before { animation-delay: -1.5s; }
.companion[data-companion="vesta"]   .card-back-motif::before { animation-delay: -3.0s; }
.companion[data-companion="nochtli"] .card-back-motif::before { animation-delay: -4.5s; }
.companion[data-companion="kasira"]  .card-back-motif::before { animation-delay: -6.0s; }
.companion[data-companion="orin"]    .card-back-motif::before { animation-delay: -7.5s; }

/* ============================================================
   Card-back ornate ring framework.
   Concentric gilt rings + cardinal fleurons + soft halo, with
   the companion's niche-relic symbol enlarged and centered as
   the focal point. The four corner brackets already exist on
   the silhouette-frame; these rings sit between them.

   Higher specificity (.silhouette-frame.silhouette-frame--back)
   to override the global .silhouette-frame::before disable rule.
   ============================================================ */
.silhouette-frame.silhouette-frame--back::before {
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 68%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  z-index: 2;
  border: 1px dashed rgba(201, 168, 101, 0.38);
  /* Eight fleuron pinpoints on the dashed ring (cardinal + ordinal) */
  background:
    radial-gradient(circle 4px at 50%   0%,  rgba(201, 168, 101, 0.70), transparent 65%),
    radial-gradient(circle 3px at 85%  15%,  rgba(201, 168, 101, 0.55), transparent 65%),
    radial-gradient(circle 4px at 100% 50%,  rgba(201, 168, 101, 0.70), transparent 65%),
    radial-gradient(circle 3px at 85%  85%,  rgba(201, 168, 101, 0.55), transparent 65%),
    radial-gradient(circle 4px at 50% 100%,  rgba(201, 168, 101, 0.70), transparent 65%),
    radial-gradient(circle 3px at 15%  85%,  rgba(201, 168, 101, 0.55), transparent 65%),
    radial-gradient(circle 4px at  0%  50%,  rgba(201, 168, 101, 0.70), transparent 65%),
    radial-gradient(circle 3px at 15%  15%,  rgba(201, 168, 101, 0.55), transparent 65%);
}

.silhouette-frame.silhouette-frame--back::after {
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 46%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  z-index: 2;
  border: 1.5px solid rgba(201, 168, 101, 0.55);
  /* Warm gilt halo behind the relic + 4 small inner cardinal marks */
  background:
    radial-gradient(circle, rgba(201, 168, 101, 0.10) 0%, transparent 70%),
    radial-gradient(circle 2.5px at 50%   0%, rgba(201, 168, 101, 0.7), transparent 60%),
    radial-gradient(circle 2.5px at 100% 50%, rgba(201, 168, 101, 0.7), transparent 60%),
    radial-gradient(circle 2.5px at 50% 100%, rgba(201, 168, 101, 0.7), transparent 60%),
    radial-gradient(circle 2.5px at  0%  50%, rgba(201, 168, 101, 0.7), transparent 60%);
}

/* Re-position the niche-relic for the card-back: large, centered,
   on top of the rings. The card-front keeps its original
   top-right corner placement (rule at line ~1605). */
.companion-card-back .niche-relic {
  top: 50%;
  left: 50%;
  right: auto;
  width: 28%;
  height: auto;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  opacity: 0.85;
  color: var(--gilt);
  z-index: 6;
}

/* The general hover rule applies a rotate transform that would
   break the centered translate — override for the back face.
   (The back isn't actually visible during hover anyway, since
   the card snaps to rotateY(0deg), but this prevents paint
   shifts during the snap-transition.) */
.companion:hover         .companion-card-back .niche-relic,
.companion:focus-visible .companion-card-back .niche-relic,
.companion:focus-within  .companion-card-back .niche-relic {
  transform: translate(-50%, -50%);
  color: var(--gilt-bright);
}

@media (prefers-reduced-motion: reduce) {
  .companion-card-inner {
    animation: none !important;
    transform: rotateY(0deg);
    transition: none;
  }
}

/* === silhouette frame (the niche) === */
.silhouette-frame {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  /* layered niche back: cool indigo wash + subtle vertical light-shaft
     behind the figure to lift the silhouette outline. */
  background:
    radial-gradient(ellipse 38% 85% at 50% 38%, rgba(56, 50, 110, 0.55), transparent 75%),
    radial-gradient(ellipse 70% 95% at 50% 30%, var(--bg-shrine), var(--bg-deep) 80%);
  border: 1px solid rgba(201, 168, 101, 0.18);
  box-shadow:
    inset 0 24px 48px rgba(0, 0, 0, 0.45),
    inset 0 -24px 48px rgba(0, 0, 0, 0.55);
}

.niche-floor { display: none; }
.silhouette-frame::before, .silhouette-frame::after { content: none; display: none; }

/* ============================================================
   Painted decay chrome on the front face of companion cards.
   - ::before on .companion-card-front carries the painted gilt
     frame (assets/decay/card_frame). Replaces the CSS corner
     brackets + 1px border on the front.
   - ::after on .companion-card-front carries the per-companion
     tear overlay (assets/decay/tear_chunk_a or tear_strip_b),
     positioned + rotated differently per companion so no two
     cards have the same wear pattern.
   - .companion-card-front overflow:hidden clips tears that
     extend slightly past the card boundary.
   ============================================================ */
.companion-card-front {
  overflow: visible;  /* allow painted frame + tear to extend outside the card */
}

.companion-card-front::before,
.companion-card-back::before {
  content: "";
  position: absolute;
  /* Extend 18px outside the card on all sides. The .companion padding
     of 18px isolates this extension from neighbor cards. */
  inset: -18px;
  /* z 6 — sits ABOVE the tear so the painted gilt frame stays intact;
     tears only show through the frame's transparent interior window. */
  z-index: 6;
  pointer-events: none;
  /* Per-companion background-image is set below; all 6 variants are
     normalized to 600x800 so bg-size: 100% 100% keeps them visually
     consistent against the element bounds. */
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
  /* Backface hidden so the front-face frame doesn't show through when
     the card spins to the back, and vice versa. Pseudo-elements don't
     always inherit backface-visibility from their parent — must set
     explicitly. */
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}

/* Per-companion painted card frame — each variant carries motifs
   specific to that companion (Iren bolts, Sirael chord-rings, etc.). */
.companion[data-companion="iren"]    .companion-card-front::before,
.companion[data-companion="iren"]    .companion-card-back::before  { background-image: url("assets/decay/card_frame_iren.png"); }
.companion[data-companion="sirael"]  .companion-card-front::before,
.companion[data-companion="sirael"]  .companion-card-back::before  { background-image: url("assets/decay/card_frame_sirael.png"); }
.companion[data-companion="vesta"]   .companion-card-front::before,
.companion[data-companion="vesta"]   .companion-card-back::before  { background-image: url("assets/decay/card_frame_vesta.png"); }
.companion[data-companion="nochtli"] .companion-card-front::before,
.companion[data-companion="nochtli"] .companion-card-back::before  { background-image: url("assets/decay/card_frame_nochtli.png"); }
.companion[data-companion="kasira"]  .companion-card-front::before,
.companion[data-companion="kasira"]  .companion-card-back::before  { background-image: url("assets/decay/card_frame_kasira.png"); }
.companion[data-companion="orin"]    .companion-card-front::before,
.companion[data-companion="orin"]    .companion-card-back::before  { background-image: url("assets/decay/card_frame_orin.png"); }

@supports (background-image: image-set(url("a") type("image/webp"))) {
  .companion[data-companion="iren"]    .companion-card-front::before,
  .companion[data-companion="iren"]    .companion-card-back::before  { background-image: image-set(url("assets/decay/card_frame_iren.webp")    type("image/webp"), url("assets/decay/card_frame_iren.png")    type("image/png")); }
  .companion[data-companion="sirael"]  .companion-card-front::before,
  .companion[data-companion="sirael"]  .companion-card-back::before  { background-image: image-set(url("assets/decay/card_frame_sirael.webp")  type("image/webp"), url("assets/decay/card_frame_sirael.png")  type("image/png")); }
  .companion[data-companion="vesta"]   .companion-card-front::before,
  .companion[data-companion="vesta"]   .companion-card-back::before  { background-image: image-set(url("assets/decay/card_frame_vesta.webp")   type("image/webp"), url("assets/decay/card_frame_vesta.png")   type("image/png")); }
  .companion[data-companion="nochtli"] .companion-card-front::before,
  .companion[data-companion="nochtli"] .companion-card-back::before  { background-image: image-set(url("assets/decay/card_frame_nochtli.webp") type("image/webp"), url("assets/decay/card_frame_nochtli.png") type("image/png")); }
  .companion[data-companion="kasira"]  .companion-card-front::before,
  .companion[data-companion="kasira"]  .companion-card-back::before  { background-image: image-set(url("assets/decay/card_frame_kasira.webp")  type("image/webp"), url("assets/decay/card_frame_kasira.png")  type("image/png")); }
  .companion[data-companion="orin"]    .companion-card-front::before,
  .companion[data-companion="orin"]    .companion-card-back::before  { background-image: image-set(url("assets/decay/card_frame_orin.webp")    type("image/webp"), url("assets/decay/card_frame_orin.png")    type("image/png")); }
}

/* Painted frame replaces CSS corner brackets on both faces. */
.companion-card .niche-corner { display: none; }

/* Per-companion tear overlay — placed above the painted frame so the
   tear visually "takes a bite" out of the frame edge. Asset's painted
   alpha shapes the natural torn-paper edge. */
/* Base rule for tear pseudo-element — applies to BOTH faces.
   z-index 5 sits BELOW the painted frame (z 6) so the frame perimeter
   stays intact; tears only show through the frame's transparent
   interior window (and beyond the frame's outer edge). */
.companion-card-front::after,
.companion-card-back::after {
  content: "";
  position: absolute;
  z-index: 5;
  pointer-events: none;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  /* Backface hidden so the tear doesn't bleed through during the spin. */
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}

/* Per-companion tear — alternates front/back across the 6 cards so
   not every tear is on the front face:
     Iren    FRONT   |  Sirael  BACK
     Vesta   FRONT   |  Nochtli BACK
     Kasira  FRONT   |  Orin    BACK
*/
/* Positive insets only — tears now sit WITHIN the frame's interior
   cutout area, never extending past the painted gilt perimeter. The
   frame at z 6 still covers tears at z 5 in their overlap zones
   (mostly the corners) — tears read as "interior decay" showing
   through the bust window rather than "tear extending off the card." */
.companion[data-companion="iren"] .companion-card-front::after {
  top: 4%; left: 4%;
  width: 48%; height: 38%;
  background-image: url("assets/decay/tear_chunk_a.png");
  transform: rotate(0deg);
}
.companion[data-companion="sirael"] .companion-card-back::after {
  top: 4%; right: 4%;
  width: 46%; height: 36%;
  background-image: url("assets/decay/tear_chunk_a.png");
  transform: rotate(90deg);
}
.companion[data-companion="vesta"] .companion-card-front::after {
  top: 4%; right: 4%;
  width: 38%; height: 44%;
  background-image: url("assets/decay/tear_strip_b.png");
  transform: rotate(0deg);
}
.companion[data-companion="nochtli"] .companion-card-back::after {
  bottom: 4%; left: 4%;
  width: 38%; height: 44%;
  background-image: url("assets/decay/tear_strip_b.png");
  transform: rotate(180deg);
}
.companion[data-companion="kasira"] .companion-card-front::after {
  bottom: 4%; left: 4%;
  width: 46%; height: 38%;
  background-image: url("assets/decay/tear_chunk_a.png");
  transform: rotate(270deg);
}
.companion[data-companion="orin"] .companion-card-back::after {
  bottom: 4%; right: 4%;
  width: 46%; height: 38%;
  background-image: url("assets/decay/tear_chunk_a.png");
  transform: rotate(180deg);
}

@supports (background-image: image-set(url("a") type("image/webp"))) {
  /* tear_chunk_a users — Iren / Sirael / Kasira / Orin */
  .companion[data-companion="iren"]    .companion-card-front::after,
  .companion[data-companion="sirael"]  .companion-card-back::after,
  .companion[data-companion="kasira"]  .companion-card-front::after,
  .companion[data-companion="orin"]    .companion-card-back::after {
    background-image: image-set(
      url("assets/decay/tear_chunk_a.webp") type("image/webp"),
      url("assets/decay/tear_chunk_a.png")  type("image/png")
    );
  }
  /* tear_strip_b users — Vesta / Nochtli */
  .companion[data-companion="vesta"]   .companion-card-front::after,
  .companion[data-companion="nochtli"] .companion-card-back::after {
    background-image: image-set(
      url("assets/decay/tear_strip_b.webp") type("image/webp"),
      url("assets/decay/tear_strip_b.png")  type("image/png")
    );
  }
}

/* per-niche hover animation — a small gilt SVG sigil specific to the
   character, plays only on hover/focus. Sits at the niche floor,
   below the silhouette. Replaces the generic ground glow. */
/* removed: per-niche hover SVG sigils. The gilded outline glow on the
   silhouette PNG now carries the hover affordance. */
.niche-anim { display: none !important; }
.companion:hover .niche-anim,
.companion:focus-visible .niche-anim,
.companion:focus-within .niche-anim {
  opacity: 0.95;
}

/* Iren — the bolt rattles loose, sliding back and forth in its eyelet. */
.anim-iren-bolt {
  transform-origin: center;
  transform-box: fill-box;
}
.companion[data-companion="iren"]:hover .anim-iren-bolt,
.companion[data-companion="iren"]:focus-visible .anim-iren-bolt,
.companion[data-companion="iren"]:focus-within .anim-iren-bolt {
  animation: anim-iren-rattle 1.6s ease-in-out infinite;
}
@keyframes anim-iren-rattle {
  0%, 100% { transform: translateX(0); }
  35%      { transform: translateX(6px); }
  70%      { transform: translateX(-3px); }
}

/* Sirael — three concentric rings ripple outward from the centre. */
.anim-ripple { opacity: 0; transform-origin: 50px 22px; transform-box: fill-box; }
.companion[data-companion="sirael"]:hover .anim-ripple,
.companion[data-companion="sirael"]:focus-visible .anim-ripple,
.companion[data-companion="sirael"]:focus-within .anim-ripple {
  animation: anim-sirael-ripple 2.6s ease-out infinite;
}
.companion[data-companion="sirael"]:hover .anim-ripple--2,
.companion[data-companion="sirael"]:focus-visible .anim-ripple--2,
.companion[data-companion="sirael"]:focus-within .anim-ripple--2 { animation-delay: 0.85s; }
.companion[data-companion="sirael"]:hover .anim-ripple--3,
.companion[data-companion="sirael"]:focus-visible .anim-ripple--3,
.companion[data-companion="sirael"]:focus-within .anim-ripple--3 { animation-delay: 1.7s; }
@keyframes anim-sirael-ripple {
  0%   { r: 1; opacity: 0.85; }
  60%  { opacity: 0.5; }
  100% { r: 14; opacity: 0; }
}

/* Vesta — three notches on the rod illuminate in lawful sequence. */
.anim-vesta-dot { opacity: 0.25; }
.companion[data-companion="vesta"]:hover .anim-vesta-dot,
.companion[data-companion="vesta"]:focus-visible .anim-vesta-dot,
.companion[data-companion="vesta"]:focus-within .anim-vesta-dot {
  animation: anim-vesta-pulse 1.8s ease-in-out infinite;
}
.companion[data-companion="vesta"]:hover .anim-vesta-dot--2,
.companion[data-companion="vesta"]:focus-visible .anim-vesta-dot--2,
.companion[data-companion="vesta"]:focus-within .anim-vesta-dot--2 { animation-delay: 0.3s; }
.companion[data-companion="vesta"]:hover .anim-vesta-dot--3,
.companion[data-companion="vesta"]:focus-visible .anim-vesta-dot--3,
.companion[data-companion="vesta"]:focus-within .anim-vesta-dot--3 { animation-delay: 0.6s; }
@keyframes anim-vesta-pulse {
  0%, 100% { opacity: 0.25; r: 1.1; }
  50%      { opacity: 1;    r: 1.6; }
}

/* Nochtli — the vine grows along its path; leaves emerge in turn. */
.anim-vine {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
.anim-leaf { opacity: 0; transform-origin: center; transform-box: fill-box; }
.companion[data-companion="nochtli"]:hover .anim-vine,
.companion[data-companion="nochtli"]:focus-visible .anim-vine,
.companion[data-companion="nochtli"]:focus-within .anim-vine {
  animation: anim-noch-grow 2.4s ease-out infinite;
}
.companion[data-companion="nochtli"]:hover .anim-leaf,
.companion[data-companion="nochtli"]:focus-visible .anim-leaf,
.companion[data-companion="nochtli"]:focus-within .anim-leaf {
  animation: anim-noch-bud 2.4s ease-out infinite;
}
.companion[data-companion="nochtli"]:hover .anim-leaf--2,
.companion[data-companion="nochtli"]:focus-visible .anim-leaf--2,
.companion[data-companion="nochtli"]:focus-within .anim-leaf--2 { animation-delay: 0.6s; }
@keyframes anim-noch-grow {
  0%   { stroke-dashoffset: 100; }
  60%  { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 0; opacity: 0.5; }
}
@keyframes anim-noch-bud {
  0%, 30% { opacity: 0; transform: scale(0.4); }
  60%     { opacity: 1; transform: scale(1); }
  100%    { opacity: 0.6; transform: scale(0.95); }
}

/* Kasira — the sun rotates and pulses with desert breath. */
.anim-sun { transform-origin: 50px 18px; transform-box: fill-box; }
.companion[data-companion="kasira"]:hover .anim-sun,
.companion[data-companion="kasira"]:focus-visible .anim-sun,
.companion[data-companion="kasira"]:focus-within .anim-sun {
  animation: anim-kasira-spin 9s linear infinite;
}
.companion[data-companion="kasira"]:hover .anim-rays,
.companion[data-companion="kasira"]:focus-visible .anim-rays,
.companion[data-companion="kasira"]:focus-within .anim-rays {
  animation: anim-kasira-pulse 1.8s ease-in-out infinite;
  transform-origin: center;
  transform-box: fill-box;
}
@keyframes anim-kasira-spin {
  from { transform: translate(50px, 18px) rotate(0deg); }
  to   { transform: translate(50px, 18px) rotate(360deg); }
}
@keyframes anim-kasira-pulse {
  0%, 100% { opacity: 0.6; transform: scale(0.92); }
  50%      { opacity: 1;   transform: scale(1.08); }
}

/* Orin — fragments orbit a fixed centre, never quite reuniting. */
.anim-orbit { transform-origin: center; transform-box: fill-box; }
.companion[data-companion="orin"]:hover .anim-orbit,
.companion[data-companion="orin"]:focus-visible .anim-orbit,
.companion[data-companion="orin"]:focus-within .anim-orbit {
  animation: anim-orin-orbit 6s linear infinite;
}
.anim-frag {
  transform-origin: center;
  transform-box: fill-box;
}
.companion[data-companion="orin"]:hover .anim-frag,
.companion[data-companion="orin"]:focus-visible .anim-frag,
.companion[data-companion="orin"]:focus-within .anim-frag {
  animation: anim-orin-flicker 1.4s ease-in-out infinite;
}
.companion[data-companion="orin"]:hover .anim-frag--2,
.companion[data-companion="orin"]:focus-visible .anim-frag--2,
.companion[data-companion="orin"]:focus-within .anim-frag--2 { animation-delay: 0.4s; }
.companion[data-companion="orin"]:hover .anim-frag--3,
.companion[data-companion="orin"]:focus-visible .anim-frag--3,
.companion[data-companion="orin"]:focus-within .anim-frag--3 { animation-delay: 0.8s; }
@keyframes anim-orin-orbit {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes anim-orin-flicker {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .niche-anim * { animation: none !important; }
  .anim-vine { stroke-dashoffset: 0; }
  .anim-leaf, .anim-ripple { opacity: 0.6; }
  .anim-vesta-dot { opacity: 0.7; }
}

   A flattened semicircle that reads as a glass dome of light
   the figure stands ON, lit from below. Sits BEHIND the figure
   (z-index 1, while .silhouette is 2). */
.niche-floor {
  position: absolute;
  left: 50%;
  bottom: 4%;
  transform: translateX(-50%);
  width: 78%;
  aspect-ratio: 3 / 1;
  border-radius: 50%;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    radial-gradient(ellipse 50% 100% at 50% 65%, rgba(255, 232, 178, 0.85) 0%, rgba(224, 192, 129, 0.55) 28%, rgba(201, 168, 101, 0.18) 55%, transparent 80%),
    radial-gradient(ellipse 80% 75% at 50% 80%, rgba(216, 212, 240, 0.18), transparent 75%);
  filter: blur(0.4px);
  opacity: 0.95;
  transition: opacity var(--med), transform var(--med);
}
.niche-floor::before {
  /* highlight crest — a thin cresc of brighter light at the top of the dome */
  content: "";
  position: absolute;
  left: 18%; right: 18%;
  top: 38%;
  height: 6%;
  border-radius: 50%;
  background: radial-gradient(ellipse 50% 100% at 50% 50%, rgba(255, 240, 200, 0.55), transparent 80%);
  filter: blur(0.6px);
}
.niche-floor::after {
  /* base shadow — grounds the dome to the floor */
  content: "";
  position: absolute;
  left: 6%; right: 6%; bottom: -4%;
  height: 30%;
  border-radius: 50%;
  background: radial-gradient(ellipse 50% 100% at 50% 0%, rgba(0, 0, 0, 0.55), transparent 75%);
  filter: blur(2px);
  mix-blend-mode: multiply;
}
.companion:hover .niche-floor,
.companion:focus-visible .niche-floor {
  opacity: 1;
  transform: translateX(-50%) translateY(-1px);
}

/* legacy ::before/::after on silhouette-frame are off — we use .niche-floor now. */
.silhouette-frame::before,
.silhouette-frame::after { content: none; }

/* fake ground plate — a tight pool that pads only the lowest hem
   so the silhouette reads as standing on light, not bathed in it.
   Pulled in tight on the X-axis + low-opacity so it never overwhelms
   the figure outline. */
.silhouette-frame::before {
  content: "";
  position: absolute;
  left: 18%; right: 18%; bottom: 4%;
  height: 12%;
  background:
    radial-gradient(ellipse 60% 80% at 50% 100%, rgba(224, 192, 129, 0.32), rgba(201, 168, 101, 0.10) 50%, transparent 80%),
    radial-gradient(ellipse 90% 30% at 50% 100%, rgba(216, 212, 240, 0.10), transparent 80%);
  pointer-events: none;
  z-index: 0;
  opacity: 0.85;
  mix-blend-mode: screen;
  transition: opacity var(--med);
}
.silhouette-frame::after {
  content: "";
  position: absolute;
  left: 14%; right: 14%; bottom: 5%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(224, 192, 129, 0.7), transparent);
  z-index: 4;
  pointer-events: none;
  filter: blur(0.3px);
  opacity: 0.85;
  transition: opacity var(--med), background var(--med);
}
/* silhouette sits ABOVE the floor pool so its dark mass reads
   crisply against the niche back, with a subtle drop-shadow for
   edge separation. */
.silhouette {
  z-index: 2;
  filter:
    drop-shadow(0 0 1px rgba(216, 212, 240, 0.18))
    drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55));
  /* slow gilt breath at rest — alpha-aware (drop-shadow follows
     the silhouette outline) so each figure looks like it's
     softly catching candlelight. The :hover rule below replaces
     this filter chain with the strong 4-layer rim. */
  animation: silhouette-breathe 7.4s ease-in-out infinite;
}
@keyframes silhouette-breathe {
  0%, 100% {
    filter:
      drop-shadow(0 0 1px rgba(216, 212, 240, 0.18))
      drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55));
  }
  50% {
    filter:
      drop-shadow(0 0 1px rgba(216, 212, 240, 0.18))
      drop-shadow(0 0 5px  rgba(224, 192, 129, 0.22))
      drop-shadow(0 0 14px rgba(201, 168, 101, 0.13))
      drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55));
  }
}
@media (prefers-reduced-motion: reduce) {
  .silhouette { animation: none; }
}
/* hover state — a tight gilded halo hugging the PNG outline.
   Several short-radius drop-shadows in gilt stack to read as a
   hand-drawn rim of light just outside the silhouette. */
.companion:hover .silhouette,
.companion:focus-visible .silhouette {
  filter:
    drop-shadow(0 0 1.2px rgba(255, 232, 178, 0.95))
    drop-shadow(0 0 4px  rgba(224, 192, 129, 0.85))
    drop-shadow(0 0 10px rgba(201, 168, 101, 0.6))
    drop-shadow(0 0 22px rgba(201, 168, 101, 0.35))
    drop-shadow(0 8px 18px rgba(0, 0, 0, 0.6));
}
.companion:hover .silhouette-frame::before,
.companion:focus-visible .silhouette-frame::before { opacity: 1; }
.companion:hover .silhouette-frame::after,
.companion:focus-visible .silhouette-frame::after {
  background: linear-gradient(90deg, transparent, rgba(255, 230, 170, 0.95), transparent);
}

/* Character fills the whole card. Bust PNGs are 9:16 portrait; cards are
   3:4 — `object-fit: cover` anchored to the top crops the lower body
   cleanly (which also hides any awkward hand cutoffs at the source-canvas
   edges). Per-companion Y anchor keeps each face well-positioned. */
.silhouette {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 25%;
  transition: filter var(--slow);
}
/* per-companion bust + silhouette positioning — tuned via card-editor.html
   Applies to both .silhouette and .bust img so the two layers stay aligned
   during the hover cross-fade. */
.companion[data-companion="iren"] .silhouette,
.companion[data-companion="iren"] .bust img {
  object-fit: scale-down;
  object-position: 78% 69%;
  transform: scale(1) translate(0px, 0px);
  transform-origin: 50% 100%;
}

.companion[data-companion="sirael"] .silhouette,
.companion[data-companion="sirael"] .bust img {
  object-fit: cover;
  object-position: 100% 0%;
  transform: scale(1) translate(0px, 0px);
  transform-origin: 50% 100%;
}

.companion[data-companion="vesta"] .silhouette,
.companion[data-companion="vesta"] .bust img {
  object-fit: scale-down;
  object-position: 100% 100%;
  transform: scale(2.43) translate(10px, -38px);
  transform-origin: 50% 16%;
}

.companion[data-companion="nochtli"] .silhouette,
.companion[data-companion="nochtli"] .bust img {
  object-fit: cover;
  object-position: 50% 0%;
  transform: scale(1.46) translate(-11px, 80px);
  transform-origin: 50% 100%;
}

.companion[data-companion="kasira"] .silhouette,
.companion[data-companion="kasira"] .bust img {
  object-fit: cover;
  object-position: 52% 0%;
  transform: scale(1.39) translate(-14px, 26px);
  transform-origin: 50% 100%;
}

.companion[data-companion="orin"] .silhouette,
.companion[data-companion="orin"] .bust img {
  object-fit: contain;
  object-position: 100% 0%;
  transform: scale(2.35) translate(-80px, 29px);
  transform-origin: 50% 8%;
}

/* ===== HOVER REVEAL — silhouette → bust + face-veil =====
   On hover/focus the silhouette fades out, the full-color bust fades in
   underneath, and a particle face-veil overlays the head area to obscure
   features. Companions stay teased rather than revealed. */
.silhouette-frame .bust {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms cubic-bezier(.25, .65, .35, 1);
}
.silhouette-frame .bust img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 25%;
}
/* Bust per-companion positioning is unified with .silhouette above
   (see the .companion[data-companion="..."] .silhouette, ... .bust img blocks). */

/* Face veil — particle obscuring layer covering the upper portion
   of the bust (where faces typically sit). Multi-layer radial gradients
   create a soft mist + cosmic-glint dots, animated by drifting the
   background positions. */
.face-veil {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 60%;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  mix-blend-mode: normal;
  transition: opacity 900ms cubic-bezier(.25, .65, .35, 1);
  background-image:
    /* soft dark fog over the face zone */
    radial-gradient(ellipse 75% 65% at 50% 35%, rgba(10, 8, 22, 0.62), rgba(10, 8, 22, 0.15) 70%, transparent 90%),
    /* cosmic-glint pinpoints — pale lilac */
    radial-gradient(circle 3px at 25% 18%, rgba(216, 212, 240, 0.85), transparent 70%),
    radial-gradient(circle 4px at 52% 12%, rgba(216, 212, 240, 0.95), transparent 70%),
    radial-gradient(circle 3px at 76% 22%, rgba(216, 212, 240, 0.8), transparent 70%),
    radial-gradient(circle 2.5px at 18% 38%, rgba(224, 192, 129, 0.7), transparent 70%),
    radial-gradient(circle 3px at 68% 32%, rgba(224, 192, 129, 0.75), transparent 70%),
    radial-gradient(circle 2px at 88% 45%, rgba(216, 212, 240, 0.65), transparent 70%),
    radial-gradient(circle 2.5px at 38% 50%, rgba(216, 212, 240, 0.7), transparent 70%);
  background-size:
    100% 100%,                 /* fog stays */
    auto, auto, auto, auto, auto, auto, auto;
  animation: face-veil-drift 11s linear infinite;
}
@keyframes face-veil-drift {
  0% {
    background-position:
      0 0,
      0 0,    0 0,    0 0,
      0 0,    0 0,    0 0,    0 0;
  }
  50% {
    background-position:
      0 0,
      -3% -8%,   2% -10%,  -1% -6%,
       4% -9%,  -2% -7%,    3% -11%,  -4% -8%;
  }
  100% {
    background-position:
      0 0,
      0 0,    0 0,    0 0,
      0 0,    0 0,    0 0,    0 0;
  }
}

/* hover/focus: silhouette out, bust + veil in */
.companion:hover .silhouette,
.companion:focus-within .silhouette { opacity: 0; }
.companion:hover .bust,
.companion:focus-within .bust { opacity: 1; }
.companion:hover .face-veil,
.companion:focus-within .face-veil { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .face-veil { animation: none; }
}
.silhouette-frame {
  margin-bottom: clamp(1.2em, 2.5vh, 1.8em);
  isolation: isolate;
  transition: border-color var(--med), box-shadow var(--med);
}

.companion:hover .silhouette-frame,
.companion:focus-visible .silhouette-frame {
  border-color: rgba(201, 168, 101, 0.45);
  box-shadow:
    0 0 0 1px rgba(201, 168, 101, 0.08),
    0 24px 60px -28px rgba(201, 168, 101, 0.32),
    inset 0 0 80px rgba(201, 168, 101, 0.05);
}

.companion:hover .silhouette,
.companion:focus-visible .silhouette {
  filter: brightness(1.05) contrast(1.05);
}

/* niche corner gilt brackets — quiet by default, lit on hover */
.niche-corner {
  position: absolute;
  width: 14px;
  height: 14px;
  z-index: 5;
  border: 1px solid var(--gilt-dim);
  pointer-events: none;
  opacity: 0.55;
  transition: opacity var(--med), border-color var(--med), width var(--slow), height var(--slow);
}

.niche-tl { top: 6px;    left: 6px;   border-right: 0; border-bottom: 0; }
.niche-tr { top: 6px;    right: 6px;  border-left: 0;  border-bottom: 0; }
.niche-bl { bottom: 6px; left: 6px;   border-right: 0; border-top: 0;    }
.niche-br { bottom: 6px; right: 6px;  border-left: 0;  border-top: 0;    }

.companion:hover .niche-corner,
.companion:focus-visible .niche-corner {
  opacity: 1;
  border-color: var(--gilt-bright);
  width: 18px;
  height: 18px;
}

/* niche-relic: small attribute mark in the upper corner of each niche */
.niche-relic {
  position: absolute;
  top: 14px; right: 14px;
  width: 22px; height: 22px;
  z-index: 5;
  color: var(--gilt);
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--med), color var(--med), transform var(--med);
}
.companion:hover .niche-relic,
.companion:focus-visible .niche-relic {
  opacity: 1;
  color: var(--gilt-bright);
  transform: rotate(-3deg);
}

/* caption plate — museum-label register beneath each niche */
.companion-plate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4em;
  margin: 1em auto 0.6em;
  max-width: 22em;
  position: relative;
}
.plate-rule {
  display: block;
  width: 56%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gilt-dim), transparent);
  margin-bottom: 0.4em;
}
.companion-title {
  font-family: var(--font-caps);
  font-weight: 500;
  font-size: clamp(0.95rem, 1.25vw, 1.12rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cream);
  line-height: 1.25;
  text-align: center;
  text-wrap: balance;
  margin: 0;
  transition: color var(--med);
}
.companion-given {
  font-family: var(--font-utility);
  font-weight: 400;
  font-size: 0.62rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--gilt);
  transition: color var(--med);
}
.companion:hover .companion-title,
.companion:focus-visible .companion-title { color: #fff; }
.companion:hover .companion-given,
.companion:focus-visible .companion-given { color: var(--gilt-bright); }

/* hero patina — the V star-wheel, now sized as a true background
   element behind the wordmark. Wrap is positioned in the hero, the
   svg is centred and oversized, and the outer ring spins under scroll
   (driven by --patina-spin set in script.js). */
.hero { position: relative; }
.hero-frame { position: relative; z-index: 2; }
/* lift every page-content layer above the fixed patina (z-index: 0) */
main { position: relative; z-index: 1; }
.studio-mark { z-index: 5; }
.footer { position: relative; z-index: 1; }
.hero-patina-wrap {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: clamp(500px, calc(95vw - 60px), 1220px);
  aspect-ratio: 1 / 1;
  pointer-events: none;
  z-index: 0;
  display: grid;
  place-items: center;
  color: var(--gilt);
}
.hero-patina-glow {
  position: absolute; inset: 12%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, rgba(224, 192, 129, 0.16), rgba(216, 212, 240, 0.05) 45%, transparent 72%);
  filter: blur(28px);
  opacity: 0.85;
}
/* Aurora — three dim ribbons all clustered at the TOP of the hero,
   overlapping vertical zones so they weave through each other.
   Teal and amber are designed in OPPOSITE PHASE: when teal peaks
   amber dims, when amber peaks teal recedes — they fight for
   dominance in the same band. Glint is a quieter constant overlay.
   Total intensity dialed down so the cosmic-indigo + patina layer
   still read clearly. */
.hero-aurora {
  position: absolute;
  inset: -8% -10%;
  pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(38px);
  will-change: transform, opacity;
}

/* Pale cosmic-glint band — the quiet constant top layer */
.hero-aurora--glint {
  background: linear-gradient(176deg,
    transparent 6%,
    rgba(216, 212, 240, 0.20) 14%,
    rgba(232, 228, 252, 0.36) 17%,
    rgba(216, 212, 240, 0.20) 20%,
    transparent 28%);
  animation: aurora-weave-glint 22s ease-in-out infinite;
}

/* Teal & amber overlap in the same vertical zone (gradient stops
   roughly 8%–32% and 10%–34% respectively) and dance in opposite
   phase — see keyframes below. */
.hero-aurora--teal {
  background: linear-gradient(174deg,
    transparent 8%,
    rgba( 80, 180, 165, 0.36) 17%,
    rgba(125, 220, 200, 0.58) 20%,
    rgba( 80, 180, 165, 0.36) 23%,
    transparent 32%);
  animation: aurora-weave-teal 16s ease-in-out infinite;
}

.hero-aurora--amber {
  background: linear-gradient(178deg,
    transparent 10%,
    rgba(220, 180, 110, 0.34) 19%,
    rgba(240, 205, 140, 0.54) 22%,
    rgba(220, 180, 110, 0.34) 25%,
    transparent 34%);
  animation: aurora-weave-amber 16s ease-in-out infinite;
}

/* Glint just breathes gently — the quiet constant layer. */
@keyframes aurora-weave-glint {
  0%, 100% { opacity: 0.28; transform: translate(0, 0)    scaleY(1);    }
  50%      { opacity: 0.40; transform: translate(2%, 2%)  scaleY(1.15); }
}

/* Teal & amber: SAME 16s period, OPPOSITE opacity + scale phase.
   At 25% teal is at max (0.70) and amber is at min (0.18).
   At 75% they swap — amber peaks (0.65) and teal dips (0.20).
   Drift directions also opposite so the ribbons cross each other. */
@keyframes aurora-weave-teal {
  0%, 100% { opacity: 0.42; transform: translate(0, 0)     scaleY(1);    }
  25%      { opacity: 0.70; transform: translate(-2%, 2%)  scaleY(1.18); }
  50%      { opacity: 0.30; transform: translate(0, 1%)    scaleY(0.92); }
  75%      { opacity: 0.20; transform: translate(2%, -1%)  scaleY(0.85); }
}

@keyframes aurora-weave-amber {
  0%, 100% { opacity: 0.42; transform: translate(0, 0)     scaleY(1);    }
  25%      { opacity: 0.18; transform: translate(2%, -2%)  scaleY(0.85); }
  50%      { opacity: 0.30; transform: translate(0, -1%)   scaleY(0.92); }
  75%      { opacity: 0.65; transform: translate(-2%, 1%)  scaleY(1.18); }
}

@keyframes aurora-drift-violet {
  0%, 100% { transform: translate(0, 0)     scale(1)    rotate(0deg);   }
  50%      { transform: translate(8%, -4%)  scale(1.15) rotate(8deg);   }
}
@keyframes aurora-drift-teal {
  0%, 100% { transform: translate(0, 0)     scale(1.05) rotate(0deg);   }
  50%      { transform: translate(-6%, 5%)  scale(0.95) rotate(-10deg); }
}
@keyframes aurora-drift-rose {
  0%, 100% { transform: translate(0, 0)     scale(1.10) rotate(0deg);   }
  50%      { transform: translate(5%, 6%)   scale(0.95) rotate(6deg);   }
}
@keyframes aurora-drift-amber {
  0%, 100% { transform: translate(0, 0)     scale(1)    rotate(0deg);   }
  50%      { transform: translate(-7%, -5%) scale(1.10) rotate(-5deg);  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-aurora { animation: none !important; }
}
.wordmark, .tagline, .hero-ornament { position: relative; z-index: 1; }

/* cosmic-thread reveal — a single gilt line draws across the niche grid
   as the section enters view, tracing the X monogram + the central spine.
   Sits BEHIND the niches (z-index -1) so it reads as a thread woven
   through the wall, not as scratches across the figures. */
.companions { position: relative; }
.cosmic-thread {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: -1;
  opacity: calc(var(--logo-cosmic-opacity, 0.85) * 0.45);
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(ellipse 30% 22% at 50% 50%, transparent 30%, black 75%);
          mask-image: radial-gradient(ellipse 30% 22% at 50% 50%, transparent 30%, black 75%);
}
.companion-grid { position: relative; z-index: 1; }
.cosmic-thread-path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 2400ms cubic-bezier(.55,.05,.25,1);
  filter: drop-shadow(0 0 6px rgba(224, 192, 129, 0.55));
}
.companions.is-visible .cosmic-thread-path { stroke-dashoffset: 0; }

/* legacy companion-name styles — swallowed by the new plate. */
.companion-name { display: none; }

.companion-tease {
  font-family: var(--font-body);
  font-size: 1.02rem;
  font-weight: 300;
  line-height: 1.55;
  color: var(--cream-dim);
  letter-spacing: 0.018em;
  max-width: 22em;
  margin-inline: auto;
  opacity: 0;
  max-height: 0;
  margin-top: 0;
  overflow: hidden;
  transform: translateY(-4px);
  transition: opacity var(--med), max-height var(--slow), transform var(--med), margin-top var(--med);
}
.companion:hover .companion-tease,
.companion:focus-visible .companion-tease,
.companion:focus-within .companion-tease,
.companion.is-active .companion-tease {
  opacity: 1;
  max-height: 6em;
  margin-top: 0.4em;
  transform: none;
  color: var(--cream);
}
  transition: color var(--slow);
}

.companion-tease em { font-style: italic; }

.companion:hover .companion-tease,
.companion:focus-visible .companion-tease { color: var(--cream); }

/* === capture === */
.capture {
  padding: clamp(80px, 12vh, 140px) clamp(20px, 4vw, 48px);
  text-align: center;
  max-width: 600px;
  margin: 0 auto;
}

.capture-heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  letter-spacing: 0.18em;
  color: var(--cream);
  margin-bottom: 0.55em;
  line-height: 1.3;
}

.capture-sub {
  font-style: italic;
  font-weight: 300;
  color: var(--cream-faint);
  margin-bottom: clamp(2em, 4vh, 3em);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

.capture-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  align-items: stretch;
  max-width: 480px;
  margin: 0 auto;
}

.capture-form input[type="email"] {
  flex: 1 1 240px;
  background: rgba(8, 6, 18, 0.7);
  border: 1px solid rgba(201, 168, 101, 0.25);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: 1.02rem;
  letter-spacing: 0.04em;
  padding: 14px 18px;
  outline: none;
  transition: border-color var(--med), background var(--med);
}

.capture-form input[type="email"]:focus {
  border-color: var(--gilt);
  background: rgba(15, 12, 30, 0.85);
}

.capture-form input[type="email"]::placeholder {
  color: var(--cream-faint);
  font-style: italic;
}

.capture-form button {
  position: relative;
  background: rgba(15, 12, 30, 0.7);
  border: 1px solid var(--gilt);
  color: var(--gilt);
  font-family: var(--font-utility);
  font-weight: 500;
  font-size: 0.85rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  padding: 14px 28px;
  transition: background var(--med), color var(--med), border-color var(--med), letter-spacing var(--slow);
  overflow: hidden;
}

.capture-form button:hover,
.capture-form button:focus-visible {
  background: rgba(201, 168, 101, 0.08);
  color: var(--gilt-bright);
  border-color: var(--gilt-bright);
  letter-spacing: 0.36em;
}

/* inner painterly bracket on the button — appears on hover */
.capture-form button::after {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid rgba(201, 168, 101, 0);
  pointer-events: none;
  transition: border-color var(--slow);
}

.capture-form button:hover::after,
.capture-form button:focus-visible::after {
  border-color: rgba(201, 168, 101, 0.28);
}

.disclaimer {
  margin-top: 1.6em;
  font-family: var(--font-utility);
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cream-faint);
}

/* === footer === */
/* The footer is an open band that reaches the very bottom of the
   page — no panel chrome, just a soft vertical fade from transparent
   into a deeper tone so it ties into the night sky underneath. */
.footer {
  margin: clamp(60px, 10vh, 100px) 0 0;
  padding: 28px clamp(20px, 4vw, 48px) clamp(28px, 4vh, 44px);
  border: 0;
  border-top: 1px solid rgba(201, 168, 101, 0.18);
  background: linear-gradient(180deg,
    rgba(8, 6, 18, 0)   0%,
    rgba(8, 6, 18, 0.55) 60%,
    rgba(4, 3, 10, 0.85) 100%);
  box-shadow: none;
  border-radius: 0;
  position: relative;
}
.footer::before { content: none; }

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: clamp(16px, 3vw, 32px);
  max-width: var(--max);
  margin: 0 auto;
  font-family: var(--font-utility);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  color: var(--cream-faint);
}

.footer-mark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.16em;
  color: var(--gilt);
}
.footer-glyph-mount {
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0.95;
}
.footer-glyph-mount svg { width: 100%; height: 100%; display: block; }
/* the seal is the dominant lockup element — bigger than the wordmark */
.footer-seal .footer-glyph--seal { width: 64px; height: 64px; flex: none; opacity: 1; }

.footer-email {
  color: var(--cream-faint);
  transition: color var(--med);
}

.footer-email:hover { color: var(--gilt-bright); }

/* sirael — sleeves intentionally break the niche walls */
.companion--overflow .silhouette-frame--breaks { overflow: visible; }
.niche-break {
  position: absolute;
  top: 56%;
  width: 14px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gilt-dim), transparent);
  z-index: 5;
  opacity: 0.7;
  pointer-events: none;
}
.niche-break--l { left: -7px; }
.niche-break--r { right: -7px; }

/* === reveal animation === */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 950ms var(--ease), transform 950ms var(--ease);
  will-change: opacity, transform;
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* === a11y === */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: 1px solid var(--gilt);
  outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    transition-duration: 0.001s !important;
  }
  .reveal { opacity: 1; transform: none; }
  .wordmark { animation: none; }
  .hero-scroll-cue span { animation: none; opacity: 0.5; transform: translateY(-28px); }
}

/* ============================================================
   MOBILE — comprehensive mobile-light treatment.
   Strips heavy 3D + animation effects that crash low-end mobile
   browsers, fixes title centering, and neutralizes decorative
   transforms that were pixel-tuned for desktop. The painted art
   assets all still render — only GPU-expensive runtime effects
   are disabled.

   Placed at the END of the file so it cascade-wins against every
   desktop rule above (same specificity, later-in-source wins).

   KEPT: silhouette → bust focus-within reveal, page-grain noise,
     patina layer, ornament + section_divider assets, painted
     frames as static images, hero pinpoint stars, slow-fade
     reveal observers.

   REMOVED: card spinning, card 3D thickness, falling sand
     particles, two of three aurora layers, wordmark sheen sweep
     + glow pulse, breathing vignette, heavy blur filters.
   ============================================================ */
@media (max-width: 560px) {
  /* ── Studio mark — scale + neutralize desktop translate ── */
  .studio-wordmark[data-style="xr-stack"] {
    transform: scale(0.85);
    transform-origin: 0 50%;
  }
  .studio-mark::before { display: none; }

  /* ── Pitch reading-card — pull horizontal extension inside viewport ── */
  .pitch-column::before {
    inset: -1.2em -4%;
  }

  /* ── VELUN title: symmetric padding + smaller scale ──
     The desktop 0.85em right-pad (italic swash reserve) shoves
     the wordmark off-center at narrow widths. At smaller font-size
     the italic swash needs much less room, so symmetric works. */
  .wordmark {
    font-size: clamp(3.4rem, 14vw, 5rem);
    padding: 0.18em 0.4em;
    margin-left: 0;
    animation: none;
    opacity: 0.96;
  }
  .wordmark-sheen { display: none; }
  /* Glow halo with blur is a major zoom-crash culprit on iOS/Safari.
     Hidden entirely on mobile — wordmark stands on its own without it. */
  .wordmark-glow { display: none; }

  /* ── Aurora: hide ALL layers on mobile ──
     Even the glint with blur(24px) is GPU-expensive when the user zooms,
     because the browser re-rasterizes the blur at increasing resolution.
     Mobile gets a clean dark cosmic-indigo backdrop, no aurora. */
  .hero-aurora { display: none; }

  /* ── Atmospheric layers: kill all blur-and-blend GPU sinks on mobile ──
     vignette breathing, patina mottle, grain noise — all individually
     light, but combined they crash low-end mobile browsers on zoom. */
  .page-vignette { animation: none; opacity: 0.5; }
  .page-patina { display: none; }
  .page-grain { opacity: 0.3; mix-blend-mode: normal; }

  /* Face-veil drift on hover is heavy; static fallback on mobile. */
  .face-veil { animation: none; }

  /* Hero cathedral light-column behind the wordmark — small but adds
     to compositor load with the page-bg gradients. */
  .hero::after { display: none; }

  /* ── Companion cards: kill 3D spin + cardstock depth ──
     Mobile gets static painted cards. The spin animation triggers
     constant compositor work; the 3D side-faces double the pseudo
     elements per card; the back face is never visible without
     spin so it's hidden too. */
  .companion-card { perspective: none; }
  .companion-card::after { display: none; }            /* drop ground-shadow */
  .companion-card-inner {
    animation: none;
    transform: none;
    transform-style: flat;
  }
  .companion-card-inner::before,
  .companion-card-inner::after { display: none; }      /* drop side-strips */
  .companion-card-back { display: none; }              /* never seen sans spin */
  .companion-card-front {
    backface-visibility: visible;
    transform: none;                                    /* drop translateZ */
  }

  /* ── Card-back falling sand motif moot since card-back hidden ── */
  .card-back-motif::before { animation: none; }
}
