:root {
  --bg: #0E0B08;
  --bg-raise: #17110B;                 /* one step lighter/warmer — gentle tonal shift */
  --gold: #C8972A;
  --ember: #C8601A;
  --fire: #C2371A;                     /* the "two fires" red (hamburger bars) */
  --rule-w: 1px;                       /* one hairline width for ALL separators */
  --rule: rgba(255,255,255,0.08);      /* hairline colour */
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  font-family: 'Space Grotesk', system-ui, sans-serif;
  overflow-x: hidden;
  color: rgba(255,255,255,0.65);
}

.svg-filters { position: absolute; width: 0; height: 0; }

/* ════ Keyframes ════ */

@keyframes bounce-y {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%       { transform: translateX(-50%) translateY(9px); }
}

/* Flame reveal — content emerges from a hot, blurred haze and cools into
   focus. Subtle: small lift, mostly blur + warm flare dissipating. */
@keyframes ignite {
  0%   { opacity: 0;   filter: blur(13px) brightness(1.7) saturate(2.6) sepia(0.5) hue-rotate(-12deg); transform: translateY(7px); }
  45%  { opacity: 0.85; }
  100% { opacity: 1;   filter: blur(0) brightness(1) saturate(1) sepia(0) hue-rotate(0deg); transform: none; }
}

.js .reveal { opacity: 0; will-change: opacity, filter, transform; }
.js .reveal.in { animation: ignite 1.35s cubic-bezier(0.2,0.7,0.2,1) var(--d, 0s) both; }

@keyframes fire-breathe {
  0%   { opacity: 0.26; }
  30%  { opacity: 0.46; }
  58%  { opacity: 0.32; }
  82%  { opacity: 0.42; }
  100% { opacity: 0.26; }
}

/* Cannon shot — a big, ambient round glow blooming from a side edge and
   fading toward the centre. Slow bloom + decay; mostly dark between shots. */
@keyframes cannon-fire {
  0%   { opacity: 0;    transform: translateX(0) scale(0.9); }
  4%   { opacity: 0.6;  transform: translateX(calc(var(--cx, 0px) * 0.30)) scale(1.0); }
  13%  { opacity: 0.30; transform: translateX(calc(var(--cx, 0px) * 0.62)) scale(1.06); }
  32%  { opacity: 0;    transform: translateX(var(--cx, 0px)) scale(1.12); }
  100% { opacity: 0;    transform: translateX(var(--cx, 0px)) scale(1.12); }
}
/* Same opacity curve as cannon-fire, minus the transform — .hero-man-light
   needs its own inline transform free for the scroll-parallax translateY
   updateParallax() sets (see main.js); an animated `transform` would
   override that inline value for the animation's duration and knock the
   mask out of alignment with the midground mid-flash. */
@keyframes cannon-fire-opacity {
  0%   { opacity: 0; }
  4%   { opacity: 0.6; }
  13%  { opacity: 0.30; }
  32%  { opacity: 0; }
  100% { opacity: 0; }
}

/* High-entropy flickering side-fire edges */
@keyframes fire-edge-left {
  0%   { clip-path: polygon(0 0, 82% 3%, 67% 11%, 90% 19%, 71% 27%, 86% 38%, 64% 47%, 91% 56%, 70% 65%, 88% 74%, 66% 84%, 84% 92%, 73% 100%, 0 100%); }
  22%  { clip-path: polygon(0 0, 74% 4%, 89% 13%, 68% 22%, 87% 30%, 66% 41%, 90% 49%, 69% 59%, 85% 67%, 64% 77%, 89% 86%, 70% 94%, 80% 100%, 0 100%); }
  47%  { clip-path: polygon(0 0, 88% 2%, 70% 12%, 84% 21%, 64% 31%, 91% 39%, 68% 48%, 86% 58%, 65% 66%, 90% 76%, 71% 85%, 83% 93%, 67% 100%, 0 100%); }
  68%  { clip-path: polygon(0 0, 79% 5%, 92% 14%, 66% 24%, 85% 33%, 63% 43%, 88% 51%, 71% 61%, 90% 69%, 67% 79%, 84% 88%, 69% 96%, 78% 100%, 0 100%); }
  86%  { clip-path: polygon(0 0, 85% 3%, 65% 13%, 90% 23%, 69% 32%, 86% 42%, 64% 50%, 91% 60%, 70% 68%, 87% 78%, 66% 87%, 82% 95%, 74% 100%, 0 100%); }
  100% { clip-path: polygon(0 0, 82% 3%, 67% 11%, 90% 19%, 71% 27%, 86% 38%, 64% 47%, 91% 56%, 70% 65%, 88% 74%, 66% 84%, 84% 92%, 73% 100%, 0 100%); }
}
@keyframes fire-edge-right {
  0%   { clip-path: polygon(18% 0%, 100% 0, 100% 100%, 27% 100%, 16% 92%, 34% 84%, 9% 74%, 30% 65%, 12% 56%, 36% 47%, 14% 38%, 29% 27%, 10% 19%, 33% 11%, 18% 3%); }
  25%  { clip-path: polygon(26% 0%, 100% 0, 100% 100%, 20% 100%, 30% 94%, 11% 86%, 32% 77%, 15% 67%, 36% 59%, 10% 49%, 34% 41%, 13% 30%, 32% 22%, 11% 13%, 26% 4%); }
  51%  { clip-path: polygon(12% 0%, 100% 0, 100% 100%, 33% 100%, 14% 93%, 36% 85%, 9% 76%, 35% 66%, 16% 58%, 34% 48%, 9% 39%, 31% 31%, 14% 21%, 35% 12%, 12% 2%); }
  72%  { clip-path: polygon(21% 0%, 100% 0, 100% 100%, 22% 100%, 33% 96%, 10% 88%, 34% 79%, 13% 69%, 36% 61%, 11% 51%, 35% 43%, 12% 33%, 30% 24%, 9% 14%, 21% 5%); }
  89%  { clip-path: polygon(15% 0%, 100% 0, 100% 100%, 30% 100%, 17% 95%, 35% 87%, 10% 78%, 31% 68%, 13% 60%, 36% 50%, 11% 42%, 33% 32%, 15% 23%, 34% 13%, 15% 3%); }
  100% { clip-path: polygon(18% 0%, 100% 0, 100% 100%, 27% 100%, 16% 92%, 34% 84%, 9% 74%, 30% 65%, 12% 56%, 36% 47%, 14% 38%, 29% 27%, 10% 19%, 33% 11%, 18% 3%); }
}

/* ════ Side fire ════ */

.fire-side {
  position: fixed;
  top: 0; bottom: 0;
  width: 120px;
  pointer-events: none;
  overflow: hidden;
  z-index: 49;
  transition: opacity 0.3s linear;
}
.fire-side.fire-left  { left: 0;  animation: fire-edge-left  7.3s ease-in-out infinite; }
.fire-side.fire-right { right: 0; animation: fire-edge-right 9.1s ease-in-out infinite; }

.fire-side .flame {
  position: absolute;
  left: 0; right: 0;
  top: -45%; bottom: -45%;
  filter: brightness(calc(1 + var(--flare, 0) * 1.5));
  will-change: transform, filter;
}
.fire-side.fire-left .flame {
  background:
    radial-gradient(ellipse 90px 220px at 0% 30%, rgba(200,58,10,0.13) 0%, transparent 76%),
    radial-gradient(ellipse 70px 340px at 3% 62%, rgba(180,46,8,0.09)  0%, transparent 82%),
    radial-gradient(ellipse 84px 200px at 1% 88%, rgba(196,54,9,0.11)  0%, transparent 80%);
  animation: fire-breathe 3.7s ease-in-out infinite;
}
.fire-side.fire-right .flame {
  background:
    radial-gradient(ellipse 90px 220px at 100% 36%, rgba(200,58,10,0.13) 0%, transparent 76%),
    radial-gradient(ellipse 70px 340px at 97% 64%, rgba(180,46,8,0.09)  0%, transparent 82%),
    radial-gradient(ellipse 84px 200px at 99% 90%, rgba(196,54,9,0.11)  0%, transparent 80%);
  animation: fire-breathe 4.5s ease-in-out 1.3s infinite;
}

/* Cannon glow layers + flashes (built in JS) */
.cannon-flash {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0;
  will-change: transform, opacity;
}

/* ════ Nav ════ */

#site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 56px;                  /* share the .sp content rail */
  transition: background 0.4s, border-color 0.4s, backdrop-filter 0.4s;
  border-bottom: var(--rule-w) solid transparent;
}

.nav-wordmark { display: inline-flex; align-items: center; }
/* img is the flat mark (media.php / error.php); .ktv-mark is the inline,
   animatable one (snippets/ktv-mark.php) — same size, no filter needed
   because its strokes are already white. */
.nav-wordmark img {
  height: 40px; width: auto; display: block;
  filter: brightness(0) invert(1);
}
.nav-wordmark .ktv-mark { height: 40px; width: auto; display: block; }

/* Big logo over the hero at the top on wide screens; collapses into the
   navbar as soon as you scroll. */
@media (min-width: 1100px) {
  .nav-wordmark img,
  .nav-wordmark .ktv-mark {
    transform-origin: left top;
    transition: transform 0.55s cubic-bezier(0.2,0.7,0.2,1);
  }
  #site-nav:not(.scrolled) .nav-wordmark img,
  #site-nav:not(.scrolled) .nav-wordmark .ktv-mark {
    transform: scale(3.1) translateY(20px) translateX(6px);
  }
}

/* ════ Animated mark ════
   The mark rigs itself on load: hull settles first, the grid rises bottom
   row up, then the sails fill masthead down (~1.4s). Per-path --d/--kd come
   from snippets/ktv-mark.php, and pathLength="100" there normalises every
   path so one keyframe drives all 25 of them.
   Without JS the mark just sits there finished — the .js gate keeps it from
   being stuck invisible if the script never runs. */
.ktv-mark path { fill: none; stroke: #fff; stroke-width: 11.65; }

@keyframes ktv-draw { to { stroke-dashoffset: 0; } }

.js .ktv-mark path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: ktv-draw var(--kd, 0.4s) cubic-bezier(0.35, 0, 0.15, 1) var(--d, 0s) both;
}

/* One-pager: no inline desktop nav — the hamburger menu serves every width. */
.nav-links { display: none; gap: 34px; align-items: center; }
.nav-links a {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.46); text-decoration: none; font-weight: 500;
  transition: color 0.2s;
}
.nav-links a:hover { color: var(--gold); }

.nav-divider { width: var(--rule-w); height: 14px; background: rgba(255,255,255,0.16); display: inline-block; }
.nav-lang-active { font-size: 11px; letter-spacing: 0.18em; color: var(--gold); font-weight: 600; }
.nav-lang-link { font-size: 11px; letter-spacing: 0.18em; color: rgba(255,255,255,0.4); text-decoration: none; font-weight: 500; transition: color 0.2s; }
.nav-lang-link:hover { color: var(--gold); }
.nav-lang-group { display: flex; gap: 22px; align-items: center; }

/* The hamburger. White, even lines at rest; on hover it reveals the "two
   fires" — red outer lines with a glowing gold ember between them
   (kahden tulen välissä). Colour only, no rotation. Shown at every width. */
@keyframes ember-pulse {
  0%, 100% { box-shadow: 0 0 4px rgba(200,151,42,0.55), 0 0 9px rgba(200,151,42,0.22);  opacity: 0.85; }
  50%      { box-shadow: 0 0 8px rgba(200,151,42,0.95), 0 0 18px rgba(200,151,42,0.5);  opacity: 1; }
}

.nav-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  width: 34px; height: 34px;
  background: none; border: none; cursor: pointer;
  padding: 0;
}
.nav-toggle span {
  display: block; height: 2px; width: 26px;
  background: #fff; border-radius: 2px;          /* white, even lines at rest */
  transition: transform 0.3s, opacity 0.3s, background 0.3s, box-shadow 0.3s;
}

/* Hover (closed) → the colour version: red outer fires, glowing gold ember
   between them. No movement. */
.nav-toggle:not([aria-expanded="true"]):hover span:nth-child(1),
.nav-toggle:not([aria-expanded="true"]):hover span:nth-child(3) {
  background: var(--fire);
}
.nav-toggle:not([aria-expanded="true"]):hover span:nth-child(2) {
  background: var(--gold);
  box-shadow: 0 0 6px rgba(200,151,42,0.85), 0 0 12px rgba(200,151,42,0.4);
  animation: ember-pulse 3.4s ease-in-out infinite;
}

/* Open state → X */
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: 0;
  z-index: 90;
  background: rgba(10,8,6,0.97);
  backdrop-filter: blur(16px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 30px;
  opacity: 0; visibility: hidden;
  transition: opacity 0.35s, visibility 0.35s;
}
.mobile-menu.open { opacity: 1; visibility: visible; }

/* Primary nav at every width — display Didot. */
.mobile-menu > a {
  font-family: 'linotype-didot-headline', 'linotype-didot', Georgia, serif;
  font-weight: 400;
  font-size: clamp(30px, 5.4vw, 48px);
  line-height: 1;
  color: #fff; text-decoration: none; letter-spacing: 0.02em;
  transition: color 0.25s;
}
.mobile-menu > a:hover { color: var(--gold); }
.mobile-menu-langs { display: flex; gap: 22px; margin-top: 12px; }

/* ════ Hero ════ */

/* isolation:isolate scopes every mix-blend-mode layer in here (cannon light,
   fire edges) to the hero's own stacking context instead of the whole page,
   so the compositor only has to re-evaluate blending against hero content —
   not everything beneath it in document order. contain:paint additionally
   fences off layout/paint invalidation from the scroll-driven transforms
   above. Both cut the compositing cost that was causing visible flicker on
   very wide viewports, where the blended/filtered layers are largest. */
#hero { position: relative; height: 100vh; min-height: 640px; overflow: hidden; isolation: isolate; contain: paint; }

/* Low-end desktop fallback (see the hardwareConcurrency/deviceMemory check
   in header.php, which adds .low-end to <html> before paint): the plain
   flattened poster.jpg, no parallax, no gradients, no filters. Hidden unless
   .low-end is set; the rule right after this one hides everything else. */
#hero-poster-fallback {
  position: absolute; inset: 0;
  background-position: center var(--hero-focus-y, 54%); background-size: cover; background-repeat: no-repeat;
  z-index: 1;
  display: none;
}
.low-end #hero-poster-fallback { display: block; }
.low-end #para-bg, .low-end #para-heraldics, .low-end #para-midground,
.low-end #para-embers, .low-end .heat-haze, .low-end .hero-fire-edge,
.low-end #para-particles {
  display: none;
}

.para-layer { position: absolute; top: -16%; left: 0; right: 0; bottom: -16%; will-change: transform; }
/* --hero-bg-url/--hero-mid-url/--hero-her-url/--hero-emb-url are set inline
   on #hero (see hero.php) — panel uploads (Hero-kuvat) override them,
   falling back to the static assets/hero/*.jpg|png defaults when nothing's
   uploaded. */
#para-bg { background: var(--hero-bg-url) center var(--hero-focus-y, 54%) / cover no-repeat; z-index: 1; }

/* Heraldic silhouettes — their own plane, drifting slower than the storm and
   breathing gently so they read as ghosts hovering behind the weather. */
#para-heraldics {
  /* The ghost artwork lives in the upper ~40% of hero-heraldics.png — but
     `cover`'s crop window on a wide/short viewport is only about as tall as
     the viewport itself relative to the image's full height, centred on
     the SHARED --hero-focus-y (54%, tuned for the man). On a wide desktop
     that window lands around 34-74% of the image, missing the ghosts
     entirely — they're just gone, not merely faint. Anchored to its own
     fixed position near the top instead, independent of --hero-focus-y,
     since this layer already drifts independently of the other planes. */
  background: var(--hero-her-url) center 18% / cover no-repeat;
  z-index: 2;
  pointer-events: none;
  animation: heraldic-breathe 11s ease-in-out infinite;
}
@keyframes heraldic-breathe {
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 1; }
}

/* Midground: the man + rocks. Same plane the old flattened poster.jpg used
   to be — kept at the same scroll speed so the figure doesn't shift. */
#para-midground {
  background: var(--hero-mid-url) center var(--hero-focus-y, 54%) / cover no-repeat;
  z-index: 3;
}

/* Embers plane: same crop/focus as the poster (it's a full-frame layer, not
   a top-anchored ghost like the heraldics), screen-blended so the near-black
   background drops out and only the baked-in spark glow shows through. */
#para-embers {
  background: var(--hero-emb-url) center var(--hero-focus-y, 54%) / cover no-repeat;
  z-index: 4;
  pointer-events: none;
  mix-blend-mode: screen;
}

/* Cannon light masked to the midground's own alpha shape (mask-image on a
   bitmap uses its alpha channel) — same crop/position as #para-midground
   so it lines up pixel-for-pixel, and it rides the exact same parallax
   transform (see updateParallax() in main.js) so it never drifts off the
   figure as you scroll. fire() sets the gradient + triggers the flash,
   reusing the SAME cannon-fire keyframe/duration as the background flash
   (not a separate one) so the two are exactly in sync rather than just
   coincidentally close. mix-blend-mode:screen (overlay was tried — it's
   muted to the point of invisible against how dark/underexposed this
   silhouette is; overlay only really shows up on midtones). What actually
   fixes "flat" is the gradient itself being directional and low-alpha
   (see fire() in main.js), not the blend mode. */
.hero-man-light {
  position: absolute;
  top: -16%; left: 0; right: 0; bottom: -16%;
  z-index: 3;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0;
  -webkit-mask-image: var(--hero-mid-url);
          mask-image: var(--hero-mid-url);
  -webkit-mask-position: center var(--hero-focus-y, 54%);
          mask-position: center var(--hero-focus-y, 54%);
  -webkit-mask-size: cover;
          mask-size: cover;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* Burning-scene mirage — heat-displaced copies of the midground, masked so the
   shimmer is heavy at the sides and the centre stays crisp. */
.heat-haze {
  position: absolute;
  top: -16%; left: 0; right: 0; bottom: -16%;
  background-position: center var(--hero-focus-y, 54%); background-size: cover; background-repeat: no-repeat;
  z-index: 4;
  pointer-events: none;
  opacity: 0.85;
  filter: url(#heat-haze) blur(0.4px);
  will-change: transform;
}
/* Confined to the outer edges only. The centre is fully cleared so the figure
   is never duplicated into a ghost/shadow by the displacement. */
.heat-left  {
  -webkit-mask-image: linear-gradient(to right, #000 0%, rgba(0,0,0,0.9) 9%, transparent 28%);
          mask-image: linear-gradient(to right, #000 0%, rgba(0,0,0,0.9) 9%, transparent 28%);
}
.heat-right {
  -webkit-mask-image: linear-gradient(to left, #000 0%, rgba(0,0,0,0.9) 9%, transparent 28%);
          mask-image: linear-gradient(to left, #000 0%, rgba(0,0,0,0.9) 9%, transparent 28%);
}

/* Black flame tongues rising from the bottom — displaced for chaos */
/* The fade is the element's BACKGROUND (not a CSS mask) so the displacement
   filter has a real edge to distort into flame tongues. Motion = slow slide. */
/* Only the TOP edge tongues into the scene. The element extends far below the
   viewport and is fully solid black from ~16% down, so the displaced bottom
   edge is off-screen and can never reveal the poster (no bright-band glitch).
   Rises on scroll via JS (transform-origin bottom). */
.hero-flame {
  position: absolute;
  left: -14%; right: -14%;
  bottom: -12%;
  height: 26%;                       /* thin tongued base so the revealed waves stay visible */
  z-index: 6;
  pointer-events: none;
  background: linear-gradient(to bottom,
    transparent 0%,
    rgba(14,11,8,0.45) 34%,
    var(--bg) 60%,
    var(--bg) 100%);
  transform-origin: 50% 100%;
  filter: url(#fire-edge);
  will-change: transform;
}

/* Hero-scale living flame edges — CSS gradients, not an image, built on the
   exact same technique as the site-wide .fire-side (below): radial-gradient
   blobs for the glow, the shared fire-edge-left/right clip-path keyframes
   for organic flicker, and --flare (set live from scroll velocity in
   fireLoop(), main.js) for brightness. Being pure CSS, it's infinitely
   scalable at any breakpoint with no overscan math, no background-size
   zoom tuning, and no image weight — everything the hero-embers.jpg layer
   needed constant recalibration for. */
.hero-fire-edge {
  position: absolute;
  top: -16%; bottom: -16%;
  width: 62%;
  /* Below .hero-gradient (5) and .hero-flame (6) on purpose — both of those
     fade to solid black at the top/bottom of the hero, and #hero itself
     clips at overflow:hidden. Sitting above them (z-index 7, as first
     built) let the glow ignore that fade entirely and hard-cut right at the
     clip boundary instead of dissolving into it. Still above heat-haze (4)
     via DOM order, so it reads over the mirage shimmer. */
  z-index: 4;
  pointer-events: none;
  overflow: hidden;
  mix-blend-mode: screen;
}
.hero-fire-edge.hero-fire-left  { left: 0;  animation: fire-edge-left  8.4s ease-in-out infinite; }
.hero-fire-edge.hero-fire-right { right: 0; animation: fire-edge-right 10.7s ease-in-out infinite; }

.hero-fire-edge .flame {
  position: absolute;
  top: -20%; bottom: -20%; left: 0; right: 0;
  filter: brightness(calc(1.2 + var(--flare, 0) * 1.2));
  will-change: filter;
}
.hero-fire-edge.hero-fire-left .flame {
  background:
    radial-gradient(ellipse 74% 38% at 4% 16%,  rgba(240,110,30,0.92) 0%, transparent 82%),
    radial-gradient(ellipse 66% 46% at 1% 52%,  rgba(214,78,14,0.85) 0%, transparent 85%),
    radial-gradient(ellipse 70% 40% at 6% 86%,  rgba(232,92,18,0.88) 0%, transparent 84%);
  animation: fire-breathe 5.4s ease-in-out infinite;
}
.hero-fire-edge.hero-fire-right .flame {
  background:
    radial-gradient(ellipse 74% 38% at 96% 20%, rgba(240,110,30,0.92) 0%, transparent 82%),
    radial-gradient(ellipse 66% 46% at 99% 58%, rgba(214,78,14,0.85) 0%, transparent 85%),
    radial-gradient(ellipse 70% 40% at 94% 90%, rgba(232,92,18,0.88) 0%, transparent 84%);
  animation: fire-breathe 6.2s ease-in-out 1.1s infinite;
}

#para-particles {
  inset: 0; top: 0; bottom: 0; overflow: hidden; z-index: 8; pointer-events: none;
  /* Embers fade IN out of the fire instead of popping from under the solid
     flame: fully transparent along the bottom (the spawn band + black-flame
     zone), ramping to visible as they rise. */
  -webkit-mask-image: linear-gradient(to top, transparent 0%, transparent 8%, #000 24%);
          mask-image: linear-gradient(to top, transparent 0%, transparent 8%, #000 24%);
}

/* Vignette + tasteful fade so the portrait poster melts into black */
.hero-gradient {
  position: absolute; inset: 0; pointer-events: none; z-index: 5;
  background:
    radial-gradient(ellipse 135% 100% at 50% 38%, transparent 78%, rgba(14,11,8,0.18) 100%),
    linear-gradient(to bottom,
      rgba(14,11,8,0.45) 0%, transparent 14%, transparent 88%,
      rgba(14,11,8,0.4) 97%, var(--bg) 100%);
}

#para-title-text {
  position: absolute;
  top: 9%; left: 0; right: 0;     /* title sits above the figure */
  z-index: 10;
  text-align: center;
  padding: 0 24px;
  will-change: transform;
}

.hero-logo { display: none; }   /* shown only on mobile */

.hero-eyebrow {
  font-size: clamp(12px, 1.8vw, 20px); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gold); font-weight: 500; margin-bottom: 32px;
}

.hero-h1 {
  font-family: 'linotype-didot-headline', 'linotype-didot', Georgia, serif;
  font-weight: 400;
  font-size: clamp(46px, 8.2vw, 124px);
  letter-spacing: 0.05em;
  line-height: 0.98;
  color: #fff;
  display: flex; flex-direction: column; align-items: center;
  text-shadow: 0 2px 22px rgba(14,11,8,0.5); /* subtle legibility, no glow */
  position: relative; z-index: 1; /* stay above .hero-h1-shimmer, which sits behind it */
}
.hero-h1-word { display: block; line-height: 0.98; white-space: nowrap; }

/* Heat-shimmer duplicate — sits BEHIND the real (crisp) h1, warped and
   blurred by the same displacement filter as the poster haze. The sharp
   text on top hides it almost entirely except where it bleeds out past the
   real glyph edges, masked so that glow only shows at the left/right edges
   of the block; the centre stays perfectly crisp. */
.hero-h1-wrap { position: relative; display: inline-flex; }
.hero-h1-shimmer {
  position: absolute; inset: 0; margin: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  filter: url(#heat-haze-text) blur(5px);
  -webkit-mask-image: linear-gradient(to right, #000 0%, transparent 26%, transparent 74%, #000 100%);
          mask-image: linear-gradient(to right, #000 0%, transparent 26%, transparent 74%, #000 100%);
  transition: opacity 1.2s ease 0.3s;
}
/* Fade the shimmer in alongside the real title's own ignite reveal. */
.hero-h1-wrap:has(.hero-h1.in) .hero-h1-shimmer { opacity: 1; }

/* A single-line title (e.g. Swedish "I KORSELDEN") is much shorter than the
   two/three-line versions and was reading as small and lonely in the hero's
   empty upper space — scale it up so it carries comparable visual weight. */
.hero-h1--lines-1 { font-size: clamp(56px, 9.5vw, 132px); }

/* A single line also leaves the title hugging the top with a big empty gap
   above the figure below it — nudge the whole title block down so it sits
   balanced in the middle of that space instead of stranded at the top. */
#para-title-text:has(.hero-h1--lines-1) { top: 16%; }

.scroll-cue {
  position: absolute; top: 88vh; bottom: auto; left: 50%; z-index: 11;
  animation: bounce-y 2.4s ease-in-out infinite;
  color: rgba(255,255,255,0.25); font-size: 15px; letter-spacing: 0.3em;
}

/* ════ Shared ════ */

.section-label {
  font-size: 18px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); font-weight: 500;
}
.sp { max-width: 1200px; margin: 0 auto; padding-left: 56px; padding-right: 56px; }

/* ════ Interstitial — italic Didot couplet bridging hero → Teos ════ */
.intro-line { background: var(--bg); padding: 104px 24px 0; text-align: center; }
.intro-couplet {
  font-family: 'linotype-didot', Georgia, serif;
  font-weight: 400; font-style: italic;
  font-size: clamp(23px, 3.1vw, 42px);
  line-height: 1.36;
  letter-spacing: 0.01em;
  color: rgba(255,255,255,0.85);
  max-width: 780px;
  margin: 0 auto;
  hyphens: auto;
}

/* ════ Teos ════ */

#teos { background: var(--bg); padding: 120px 0 100px; position: relative; }
/* Subtle warm "stage" glow lifting the themes text so it doesn't get lost after
   the heavy hero (client note). Centred low and masked at the top so it blooms
   softly behind the copy with no hard clipped edge at the section boundary. */
#teos::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(68% 46% at 50% 42%, rgba(200,151,42,0.06) 0%, transparent 60%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 26%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 26%);
}

/* Heraldic creatures — two edge-pinned layers (lion bottom-left, eagle
   bottom-right), each sized by HEIGHT so they always hug the edges at any
   width and are never cut. White drops out via multiply, leaving black
   silhouettes that catch the cannon glow. Above the cannons (z 50), below text. */
.teos-heraldics {
  position: absolute;
  inset: 0;                            /* full height of the Teos section */
  z-index: 50;
  pointer-events: none;
  background:
    url('../lion.png')  left  bottom / auto 100% no-repeat,
    url('../eagle.png') right bottom / auto 100% no-repeat;
  mix-blend-mode: multiply;
  opacity: 0.92;
}

.teos-wrap { position: relative; z-index: 51; max-width: 1200px; text-align: center; }
.teos-wrap .section-label { display: inline-block; margin-bottom: 40px; }

/* Centred Didot lead — a calmer, more even size than before */
.teos-lead {
  font-family: 'linotype-didot', Georgia, serif;
  font-weight: 400;
  font-size: clamp(22px, 2.7vw, 36px);
  line-height: 1.3; color: rgba(255,255,255,0.8);
  text-align: center;
  width: 100%; max-width: 860px;
  margin: 0 auto 40px;
  hyphens: auto;
}
.teos-lead p { margin-bottom: 0.5em; }
.teos-lead p:last-child { margin-bottom: 0; }

/* Body copy block — the three paragraphs render as uniform copy text */
.teos-questions, .teos-logline, .teos-body {
  border: none;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 300; font-style: normal;
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.8;
  letter-spacing: 0;
  color: rgba(255,255,255,0.64);
  text-align: center;
  max-width: 660px;
  margin: 0 auto 22px;
  hyphens: auto;
}
.teos-body p { margin-bottom: 0.8em; }
.teos-body p:last-child { margin-bottom: 0; }

/* CTA — smaller one-line head title, plain Didot, no glow or flame */
.teos-cta {
  font-family: 'linotype-didot', Georgia, serif;
  font-weight: 700;
  font-size: clamp(20px, 2.4vw, 34px);
  letter-spacing: 0.04em;
  line-height: 1.1;
  color: var(--gold);
  margin-top: 44px;
}

/* ════ Tekijät ════ */

#tekijat { position: relative; overflow: hidden; background: #0A0907; padding: 88px 0; border-top: var(--rule-w) solid var(--rule); }

/* Embers plane over the team grid — negative z-index was tried first (to sit
   behind the cards) but was invisible in practice: something in the real
   stacking chain between #tekijat and the root paints opaque content between
   a negative-z child and the viewer. Sitting ABOVE the content instead, same
   as the hero's own fire/ember layers, sidesteps that entirely — screen blend
   can only brighten pixels, never darken them, so the white/gold text stays
   fully legible underneath it. Fixed-height band anchored to the top, not
   the full (variable) section height: the source image's spark ring lives
   in its upper portion and fades to black lower down, so a shorter band
   already gets the visible part and lets the section's own near-identical
   dark bg carry the rest seamlessly — no need to stretch/crop the image to
   match every team-count. */
.tekijat-embers {
  position: absolute;
  top: -15%; left: 0; right: 0;
  height: 130%;
  background: var(--tek-emb-url) center 14% / cover no-repeat;
  z-index: 5;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0.1;
  will-change: transform;
}
.low-end .tekijat-embers { display: none; }

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  margin-top: 54px;
  /* Hairlines used to come from the grid's own background showing through
     the gaps (gap + background trick) — but when the team count doesn't
     fill a whole row, the last, item-less grid cell has nothing to cover
     that background, so it read as a solid grey block instead of a thin
     line. Each card draws its own hairline via border instead, so an empty
     cell (no card there at all) is just transparent — same colour as the
     section behind it. */
}
/* Transparent, not the section's own #0A0907: the two colours look identical
   with fx effects off, but opaque cards would fully block the .tekijat-embers
   glow layer sitting behind them (z-index: -1) for the whole grid area. */
.team-card { background: transparent; padding: 34px 28px; border-right: var(--rule-w) solid var(--rule); border-bottom: var(--rule-w) solid var(--rule); }

/* Crest filling the grid's trailing empty cell (see tekijat.php) — the
   animatable inline mark (ktv-mark.php), full white, no dimming/filter
   needed since its strokes are already #fff. */
.team-logo-card { display: flex; align-items: center; justify-content: center; }
.team-logo-mark { width: 84px; height: auto; }

/* Draw-in animation is paused at its (hidden) starting frame until this
   card scrolls into view and the shared .reveal system adds .in — same
   ktv-draw animation the nav/hero copies play immediately on page load,
   just deferred here since the card can be far below the fold. */
.ktv-mark.team-logo-mark path { animation-play-state: paused; }
.team-logo-card.in .ktv-mark.team-logo-mark path { animation-play-state: running; }

.team-role-label {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 14px; font-weight: 500;
}
.team-name {
  font-family: 'linotype-didot', Georgia, serif;
  font-weight: 700;
  font-size: clamp(22px, 2vw, 30px);
  letter-spacing: 0.01em; color: #fff; line-height: 1.12;
}
.team-bio {
  font-size: 14px; line-height: 1.8; color: rgba(255,255,255,0.6);
  font-weight: 300; margin-top: 16px; hyphens: auto;
}
.team-portrait {
  width: 100%; aspect-ratio: 3 / 4; object-fit: cover; display: block;
  margin-bottom: 24px; filter: grayscale(20%) contrast(1.04);
}

/* Rooleissa — set apart from the contributors, no panel, kept small since it's
   only a teaser for now */
/* Rooleissa — given more presence for launch (client): larger heading + text
   and a top hairline so it reads as its own section, still clean until soloists
   are announced (then portraits + CV links come in). */
.soloists-bar {
  background: none;
  border-top: var(--rule-w) solid var(--rule);
  padding-top: 60px;
  margin-top: 96px;
  text-align: center;
}
.rooleissa-label {
  font-size: clamp(18px, 1.9vw, 23px); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold); font-weight: 500;
  margin-bottom: 22px;
}
.rooleissa-text {
  font-size: clamp(16px, 1.5vw, 20px); line-height: 1.7;
  color: rgba(255,255,255,0.72); font-weight: 300;
  max-width: 640px; margin: 0 auto; hyphens: auto;
}
.sol-row { display: flex; gap: 48px; flex-wrap: wrap; justify-content: center; margin-top: 28px; }
.sol-name { font-family: 'linotype-didot', Georgia, serif; font-weight: 700; font-size: clamp(19px, 1.7vw, 24px); color: #fff; line-height: 1.1; }
.sol-role { font-size: 12px; color: rgba(255,255,255,0.5); margin-top: 5px; }

/* ════ Kumppanit ════ */

#kumppanit { background: var(--bg-raise); padding: 88px 0; position: relative; border-top: var(--rule-w) solid var(--rule); }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 72px; align-items: start; }

.kumppanit-h2 {
  font-family: 'linotype-didot', Georgia, serif;
  font-weight: 700;
  font-size: clamp(26px, 2.8vw, 40px);
  letter-spacing: 0.01em; color: #fff; line-height: 1.1;
  margin-bottom: 28px; margin-top: 22px;
}
.kumppanit-body { font-size: clamp(14px, 1.2vw, 16px); line-height: 1.8; color: rgba(255,255,255,0.6); font-weight: 300; margin-bottom: 32px; max-width: 440px; hyphens: auto; }
.kumppanit-body p { margin-bottom: 1em; }
.kumppanit-quote {
  border-left: var(--rule-w) solid var(--ember);
  padding-left: 24px; font-size: 15px; color: rgba(255,255,255,0.6);
  line-height: 1.8; font-style: italic; hyphens: auto;
}

/* The line the client wanted emphasised — a large Didot statement in gold,
   set apart from the smaller ember quote above it. */
.kumppanit-highlight {
  font-family: 'linotype-didot', Georgia, serif;
  font-weight: 400;
  font-size: clamp(23px, 2.7vw, 36px);
  line-height: 1.25;
  color: var(--gold);
  max-width: 460px;
  margin-top: 40px;
  hyphens: auto;
}

.contact-label { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.42); font-weight: 500; margin-bottom: 26px; }
.contact-person { margin-bottom: 30px; }
.contact-person:last-of-type { margin-bottom: 0; }
.contact-name { font-family: 'linotype-didot', Georgia, serif; font-weight: 700; font-size: clamp(24px, 2.4vw, 32px); color: #fff; line-height: 1.1; margin-bottom: 6px; }
.contact-role { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); font-weight: 500; margin-bottom: 14px; }
.contact-links { display: flex; flex-direction: column; gap: 14px; }
.contact-link { font-size: 15px; text-decoration: none; display: flex; align-items: center; gap: 14px; transition: opacity 0.2s; }
.contact-link:hover { opacity: 0.68; }
.contact-link--phone { color: rgba(255,255,255,0.72); }   /* readable: it's a number to call */
.contact-link--email { color: var(--ember); }
.contact-link-dash { width: 16px; height: var(--rule-w); flex-shrink: 0; background: var(--gold); }
.contact-link--email .contact-link-dash { background: var(--ember); }
.contact-org { font-size: 12px; color: rgba(255,255,255,0.5); line-height: 1.8; margin-top: 32px; margin-bottom: 44px; }

.logos-section { border-top: var(--rule-w) solid var(--rule); padding-top: 28px; margin-top: 28px; }
.logos-label { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.5); margin-bottom: 20px; font-weight: 500; }
.logo-grid { display: flex; gap: 34px; flex-wrap: wrap; align-items: center; }
.logo-item { display: inline-flex; align-items: center; }
.logo-item img { height: 66px; width: auto; max-width: 220px; object-fit: contain; opacity: 0.88; transition: opacity 0.2s; }
.logos-rahoittaja .logo-item img { height: 108px; max-width: 300px; }
a.logo-item:hover img { opacity: 1; }
.logo-text { font-size: 13px; color: rgba(255,255,255,0.55); line-height: 1.4; max-width: 220px; }

/* ════ Footer ════ */

/* Gold footer with negative (dark) text */
footer { background: var(--gold); padding: 50px 0; border-top: var(--rule-w) solid rgba(0,0,0,0.18); position: relative; z-index: 50; }
.footer-inner { display: flex; flex-direction: column; gap: 10px; }
/* Wordmark+langs is one row, org+credit is the next — same row structure
   for both so the left/right pairs line up on a shared baseline instead of
   drifting apart from independent column stacking. */
.footer-row { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 24px; }
.footer-wordmark { font-family: 'linotype-didot', Georgia, serif; font-weight: 700; font-size: 18px; letter-spacing: 0.04em; color: #14100a; }
.footer-org { font-size: 12px; color: rgba(20,16,10,0.66); line-height: 1.9; }
.footer-langs { display: flex; gap: 28px; align-items: baseline; }
footer .nav-lang-active { color: #14100a; font-weight: 700; font-size: 16px; }
footer .nav-lang-link { color: rgba(20,16,10,0.55); font-size: 16px; }
footer .nav-lang-link:hover { color: #14100a; }
.footer-credit {
  font-size: 12px; color: rgba(20,16,10,0.66); text-decoration: none;
  border-bottom: var(--rule-w) solid rgba(20,16,10,0.35); padding-bottom: 1px;
  transition: color 0.2s, border-color 0.2s;
}
.footer-credit:hover { color: #14100a; border-color: rgba(20,16,10,0.6); }

/* ════ 404 / error page ════ */

.error-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.error-wrap { text-align: center; padding: 40px 24px; max-width: 540px; }
.error-logo { height: 64px; width: auto; margin: 0 auto 40px; filter: brightness(0) invert(1); opacity: 0.92; }
.error-code {
  font-family: 'linotype-didot-headline', 'linotype-didot', Georgia, serif;
  font-size: clamp(72px, 16vw, 140px); line-height: 1; color: var(--gold);
  letter-spacing: 0.04em; margin-bottom: 12px;
}
.error-headline {
  font-family: 'linotype-didot', Georgia, serif; font-weight: 700;
  font-size: clamp(24px, 3.4vw, 38px); color: #fff; line-height: 1.15; margin-bottom: 20px;
}
.error-text { font-size: 15px; line-height: 1.8; color: rgba(255,255,255,0.64); font-weight: 300; margin: 0 auto 40px; max-width: 420px; }
.error-home {
  display: inline-block; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;
  font-weight: 600; color: var(--gold); text-decoration: none;
  border: var(--rule-w) solid var(--gold); padding: 14px 30px; transition: background 0.25s, color 0.25s;
}
.error-home:hover { background: var(--gold); color: #14100a; }

/* ════ Media / press page ════ */

.media-page { background: var(--bg); }

.media-nav {
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px 56px; border-bottom: var(--rule-w) solid var(--rule);
}
.media-nav .nav-wordmark img { height: 34px; width: auto; display: block; filter: brightness(0) invert(1); }
.media-nav-right { display: flex; align-items: center; gap: 26px; }
.media-back { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.5); text-decoration: none; font-weight: 500; transition: color 0.2s; }
.media-back:hover { color: var(--gold); }

.media-hero {
  position: relative; min-height: 52vh;
  display: flex; align-items: flex-end;
  background: #0A0907 center 40% / cover no-repeat;
  border-bottom: var(--rule-w) solid var(--rule);
}
.media-hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to bottom, rgba(14,11,8,0.5) 0%, transparent 32%, rgba(14,11,8,0.35) 70%, var(--bg) 100%);
}
.media-hero-inner { position: relative; z-index: 1; width: 100%; padding-top: 90px; padding-bottom: 46px; }
.media-hero-title {
  font-family: 'linotype-didot-headline', 'linotype-didot', Georgia, serif;
  font-weight: 400; font-size: clamp(34px, 6vw, 74px); line-height: 1.02;
  color: #fff; letter-spacing: 0.03em; margin-top: 14px;
  text-shadow: 0 2px 22px rgba(14,11,8,0.5);
}

.media-main { padding-top: 72px; padding-bottom: 96px; }
.media-intro {
  font-family: 'linotype-didot', Georgia, serif; font-weight: 400;
  font-size: clamp(20px, 2.4vw, 30px); line-height: 1.4; color: rgba(255,255,255,0.82);
  max-width: 760px; margin-bottom: 40px; hyphens: auto;
}
.media-body { font-size: clamp(15px, 1.3vw, 17px); line-height: 1.8; color: rgba(255,255,255,0.64); font-weight: 300; max-width: 660px; }
.media-body p { margin-bottom: 1em; }

.media-section { margin-top: 72px; border-top: var(--rule-w) solid var(--rule); padding-top: 40px; }
.media-section .section-label { display: inline-block; margin-bottom: 30px; font-size: 12px; }

.pkg-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--rule-w); background: var(--rule); }
.pkg-card { background: var(--bg); padding: 28px 26px; display: flex; flex-direction: column; align-items: flex-start; }
.pkg-name { font-family: 'linotype-didot', Georgia, serif; font-weight: 700; font-size: 20px; color: #fff; margin-bottom: 8px; }
.pkg-desc { font-size: 14px; line-height: 1.7; color: rgba(255,255,255,0.6); font-weight: 300; margin-bottom: 20px; }
.pkg-dl {
  margin-top: auto; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  font-weight: 600; color: var(--gold); text-decoration: none;
  border: var(--rule-w) solid var(--gold); padding: 11px 20px; transition: background 0.25s, color 0.25s;
}
.pkg-dl:hover { background: var(--gold); color: #14100a; }
.pkg-meta { opacity: 0.7; font-weight: 500; }

.media-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.media-shot { position: relative; display: block; overflow: hidden; background: #0A0907; }
.media-shot img { width: 100%; aspect-ratio: 7 / 5; object-fit: cover; display: block; transition: transform 0.4s, opacity 0.2s; }
.media-shot:hover img { transform: scale(1.04); opacity: 0.85; }
.media-shot-dl {
  position: absolute; bottom: 10px; right: 10px; font-size: 10px; letter-spacing: 0.14em;
  text-transform: uppercase; font-weight: 600; color: #14100a; background: var(--gold);
  padding: 6px 11px; opacity: 0; transition: opacity 0.2s;
}
.media-shot:hover .media-shot-dl { opacity: 1; }

.media-contact-body { font-size: 15px; line-height: 1.8; color: rgba(255,255,255,0.72); }

.footer-back { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: #14100a; font-weight: 700; text-decoration: none; border-bottom: 1px solid rgba(20,16,10,0.4); padding-bottom: 2px; }

/* ════ Responsive ════ */

@media (max-width: 980px) {
  .two-col { grid-template-columns: 1fr; gap: 56px; }
}

@media (max-width: 860px) {
  #site-nav { padding: 14px 26px; }    /* match the .sp mobile rail */
  .media-nav { padding: 14px 26px; }
  .media-hero { min-height: 44vh; }
  .sp { padding-left: 26px !important; padding-right: 26px !important; }
  .heat-haze { display: none; }   /* avoid mobile jitter + heavy filter */
  #para-heraldics { display: none; }   /* too subtle to read at this size, not worth the extra image weight */
  .hero-h1-shimmer { display: none; }   /* skip the shimmer filter on weaker mobile GPUs */
  /* Compensate for the heat-haze mirage being off: it's a cheap CSS
     gradient (no filter, no image), so it can afford to carry more
     presence on its own here instead of reading as barely-there. */
  .hero-fire-edge { width: 68%; }
  .hero-fire-edge .flame { filter: brightness(calc(1.5 + var(--flare, 0) * 1.2)); }
  /* keep the static tongues (cheap, no jitter), but pull the black lower so
     the misty scene below the man stays visible — less dead black */
  .hero-flame { bottom: -42%; height: 60%; }
  #site-nav { justify-content: flex-end; }              /* only the hamburger at the top */
  #site-nav.scrolled { justify-content: space-between; }/* logo returns once scrolled */
  .nav-wordmark { display: none; }                      /* hero logo covers branding at the top */
  #site-nav.scrolled .nav-wordmark { display: inline-flex; }
  #para-title-text { top: 11%; }
  .hero-h1 { font-size: clamp(40px, 13vw, 72px); }
  /* Narrow screens can't fit a single long line at a bigger size without
     overflowing — keep it close to the default scale here instead. */
  .hero-h1--lines-1 { font-size: clamp(34px, 10.5vw, 56px); letter-spacing: 0.02em; }
  #para-title-text:has(.hero-h1--lines-1) { top: 14%; }
  .hero-eyebrow { margin-bottom: 24px; }
  .intro-line { padding-top: 76px; }
  .intro-couplet { font-size: clamp(22px, 6.4vw, 31px); }
  #teos { padding: 84px 0 72px; }
  .teos-lead { font-size: clamp(23px, 6.2vw, 32px); }
  /* These are tall portraits — sizing by section height zooms them to a
     fragment on mobile. Size by viewport width so the whole creature reads
     in each bottom corner, and lift opacity so they're not lost in the dark. */
  .teos-heraldics { background-size: 44vw auto, 44vw auto; opacity: 1; }
  .hero-logo {
    display: block; width: 88px; height: auto; margin: 0 auto 26px;
  }
  .sol-row { gap: 30px; }
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .reveal.in { opacity: 1 !important; animation: none !important; filter: none !important; transform: none !important; }
  /* The mark's resting state is the finished logo, so this just skips the draw. */
  .js .ktv-mark path { stroke-dasharray: none; stroke-dashoffset: 0; animation: none; }
  .heat-haze { display: none; }
  .hero-h1-shimmer { display: none; }
  .hero-flame { animation: none; }
  #para-heraldics { animation: none; opacity: 0.85; }
  .hero-fire-edge, .hero-fire-edge .flame { animation: none; }
  .scroll-cue { animation: none; }
  .nav-toggle span:nth-child(2) { animation: none !important; }
}
