/* TWO MINDS — shared site chrome (design tokens, header/menu, cursor, cta, footer).
   Loaded by every page (website/index.php, website/about.php, …) so there's one
   place to edit the header, the footer, or a shared component instead of two.
   Page-specific look (the home page's gate/releases/marquee, About's hero/bio…)
   stays in that page's own <style> block. */

/* The loading-screen look (trembling icon, counting %, progress bar) lives in its
   own file now — it's not just this site's chrome, admin/ and demo/ pull it in too
   (self-contained there, no dependency on this file's design tokens). @import has
   to be the first rule in the sheet (CSS requirement), before anything else here. */
@import url('/static/css/tm-loader.css');

@font-face { font-family: 'Agelast'; src: url('/static/fonts/Agelast/AgelastStyledBold.woff') format('woff'), url('/static/fonts/Agelast/AgelastStyledBold.ttf') format('truetype'); font-weight: 700; font-style: normal; font-display: swap; }

/* ============================================================ THE GATE (shared, partials/gate.php) ============================================================ */
.tm-scanlines {
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  opacity: 0.28;
  background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.35) 0px, rgba(0, 0, 0, 0.35) 1px, transparent 1px, transparent 3px);
}

#tm-gate {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 36px;
  background: var(--bg);
  overflow: hidden;
  transition: opacity 1.1s ease, visibility 1.1s ease;
}
#tm-gate.tm-gone { opacity: 0; visibility: hidden; pointer-events: none; }

.tm-stars { position: absolute; inset: -10%; width: 120%; height: 120%; pointer-events: none; opacity: 0.45; }
.tm-stars--near {
  background-image:
    radial-gradient(1.6px 1.6px at 8% 22%, #fff, transparent 60%),
    radial-gradient(1.2px 1.2px at 32% 68%, #fff, transparent 60%),
    radial-gradient(1.8px 1.8px at 61% 12%, #fff, transparent 60%),
    radial-gradient(1.3px 1.3px at 78% 47%, #fff, transparent 60%),
    radial-gradient(1.5px 1.5px at 92% 80%, #fff, transparent 60%),
    radial-gradient(1.2px 1.2px at 15% 88%, #fff, transparent 60%),
    radial-gradient(1.7px 1.7px at 46% 35%, #fff, transparent 60%);
  animation: tm-stars-drift 90s linear infinite;
}
.tm-stars--far {
  opacity: 0.55;
  background-image:
    radial-gradient(1px 1px at 20% 40%, #fff, transparent 60%),
    radial-gradient(1px 1px at 50% 80%, #fff, transparent 60%),
    radial-gradient(1px 1px at 70% 20%, #fff, transparent 60%),
    radial-gradient(1px 1px at 85% 60%, #fff, transparent 60%),
    radial-gradient(1px 1px at 5% 65%, #fff, transparent 60%);
  animation: tm-stars-drift 150s linear infinite reverse;
}
@keyframes tm-stars-drift { from { transform: translate(0, 0); } to { transform: translate(-4%, 3%); } }

.tm-gate-texture {
  position: absolute;
  inset: -6%;
  overflow: hidden;
  transition: transform 0.4s ease-out;
  pointer-events: none;
}
.tm-gate-texture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(-1, -1);
}

.tm-gate-dim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
}
.tm-gate-dim--l { background: linear-gradient(to right, rgba(2, 2, 6, 0.78) 0%, rgba(2, 2, 6, 0.78) 36%, transparent 62%); }
.tm-gate-dim--r { background: linear-gradient(to left, rgba(2, 2, 6, 0.78) 0%, rgba(2, 2, 6, 0.78) 36%, transparent 62%); }
#tm-gate.tm-focus-blue .tm-gate-dim--r { opacity: 1; }
#tm-gate.tm-focus-red .tm-gate-dim--l { opacity: 1; }

.tm-gate-title {
  position: relative;
  z-index: 2;
  margin: 0;
  font-family: 'Agelast', var(--font);
  font-weight: 700;
  font-size: clamp(2rem, 8vw, 3.6rem);
  letter-spacing: 0.14em;
  text-align: center;
  color: var(--ink);
  filter: drop-shadow(0 0 26px rgba(234, 228, 216, 0.18));
  animation: tm-gate-title-glow 4.5s ease-in-out infinite;
  transition: opacity 0.2s ease;
}
@keyframes tm-gate-title-glow {
  0%, 100% { filter: drop-shadow(0 0 22px rgba(234, 228, 216, 0.14)); }
  50% { filter: drop-shadow(0 0 34px rgba(234, 228, 216, 0.26)); }
}

.tm-orb-scene { position: relative; z-index: 2; perspective: 1000px; }
.tm-orb-wrap { position: relative; width: clamp(170px, 55vw, 360px); height: clamp(170px, 55vw, 360px); transform-style: preserve-3d; }

/* a soft contact shadow beneath the orb, in the scene's own flat ground plane — shifts opposite the tilt so the orb reads as floating above it */
.tm-orb-shadow {
  position: absolute; left: 50%; top: 96%; width: 66%; height: 20%;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.5) 0%, transparent 72%);
  filter: blur(7px);
  transform: translate(-50%, -50%);
  pointer-events: none; z-index: 0;
}

.tm-orb {
  position: absolute;
  inset: 0;
  cursor: pointer;
  filter: drop-shadow(-10px 0 22px rgba(77, 114, 255, 0.3)) drop-shadow(10px 0 22px rgba(196, 76, 103, 0.3));
}

/* a soft highlight that tracks the cursor across the orb's own ripple shape, masked identically to the halves — held slightly forward in the wrap's 3D space so it drifts against the base orb as it tilts */
.tm-orb-glow {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  -webkit-mask-image: url('/static/img/logo/logo_white.png');
  mask-image: url('/static/img/logo/logo_white.png');
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  mix-blend-mode: overlay; opacity: 0; transition: opacity 0.4s ease;
  transform: translateZ(34px);
}
.tm-orb-glow::before {
  content: ''; position: absolute; width: 55%; height: 55%; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.95) 0%, transparent 70%);
  left: var(--gx, 50%); top: var(--gy, 50%); transform: translate(-50%, -50%);
}
.tm-orb-scene:hover .tm-orb-glow { opacity: 1; }

.tm-orb-half {
  position: absolute;
  inset: 0;
  -webkit-mask-image: url('/static/img/logo/logo_white.png');
  mask-image: url('/static/img/logo/logo_white.png');
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;

  mix-blend-mode: overlay;
  transition: filter 0.35s ease, opacity 0.35s ease, transform 0.6s cubic-bezier(.5,0,.3,1);
}
.tm-orb-half--l { clip-path: inset(0 50% 0 0); background: radial-gradient(115% 130% at 80% 15%, #7266ff 0%, var(--blue) 34%, #06061a 90%); }
.tm-orb-half--r { clip-path: inset(0 0 0 50%); background: radial-gradient(115% 130% at 20% 15%, #ff4d6d 0%, var(--red) 34%, #170307 90%); }
.tm-orb-half.tm-hover { filter: brightness(1.18) saturate(1.05); }
.tm-orb-half.tm-dim { opacity: 0.5; filter: brightness(0.8); }
/* touch feedback: a quick, JS-free brightness pop on press instead of the desktop hover/dim/label sequence — that whole sequence used to fire on touchstart right before choose()'s own transition kicked in on release, and the two fought each other */
.tm-orb-half:active { filter: brightness(1.3) saturate(1.15); transition: filter 0.1s ease; }

.tm-orb.tm-choosing-blue .tm-orb-half--l { transform: scale(2.6); opacity: 0; transition-duration: 0.9s; transition-delay: 0.1s; }
.tm-orb.tm-choosing-blue .tm-orb-half--r { transform: scale(0.82); opacity: 0; transition-duration: 0.5s; }
.tm-orb.tm-choosing-red .tm-orb-half--r { transform: scale(2.6); opacity: 0; transition-duration: 0.9s; transition-delay: 0.1s; }
.tm-orb.tm-choosing-red .tm-orb-half--l { transform: scale(0.82); opacity: 0; transition-duration: 0.5s; }

.tm-gate-label {
  position: relative; z-index: 2; min-height: 1.4em;
  font-weight: 600; font-size: clamp(14px, 2vw, 18px); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-dim); transition: color 0.3s ease;
}
.tm-gate-label.tm-is-blue { color: var(--blue); text-shadow: 0 0 16px var(--blue-dim); }
.tm-gate-label.tm-is-red { color: var(--red); text-shadow: 0 0 16px var(--red-dim); }

.tm-gate-genre {
  position: relative; z-index: 2; min-height: 1.2em; margin: 4px 0 0;
  font-weight: 500; font-size: clamp(10px, 1.3vw, 13px); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-dim); opacity: 0; transition: opacity 0.3s ease, color 0.3s ease;
}
.tm-gate-genre.tm-show { opacity: 0.75; }

.tm-gate-label-group { text-align: center; transition: opacity 0.2s ease; }
.tm-gate-genre.tm-is-blue { color: var(--blue); }
.tm-gate-genre.tm-is-red { color: var(--red); }

/* Nested inside #tm-gate itself (partials/gate.php) — position:fixed takes it out of
   the gate's own flex layout, so nesting is purely about lifecycle: no separate
   opacity/transition of its own needed, it fades out for free as part of #tm-gate's
   own opacity transition (site-chrome.css, #tm-gate.tm-gone) when the gate closes,
   and simply isn't there at all once #tm-site (the real content) is what's showing. */
.tm-footer {
  position: fixed;
  left: 0; right: 0; bottom: 14px;
  z-index: 120;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.03em;
  color: rgba(247, 242, 232, 0.35);
  pointer-events: none;
  mix-blend-mode: difference;
}
.tm-footer a { pointer-events: auto; color: rgba(247, 242, 232, 0.55); }

.tm-sound-bar { position: fixed; inset: 0; z-index: 110; pointer-events: none; }
.tm-sound-bar .tm-container { position: relative; height: 100%; }
#tm-sound {
  position: absolute; right: 26px; bottom: 20px; pointer-events: auto;
  background: transparent; border: 1px solid rgba(247, 242, 232, 0.25); color: rgba(247, 242, 232, 0.55);
  font-weight: 500; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 9px 14px; cursor: pointer; transition: all 0.3s ease;
}
#tm-sound:hover { color: var(--ink); border-color: rgba(247, 242, 232, 0.5); }
#tm-sound.tm-hidden { opacity: 0; pointer-events: none; }
#tm-sound.tm-on { color: var(--ink); border-color: var(--blue-dim); }
html.tm-theme-red #tm-sound.tm-on { border-color: var(--red-dim); }

#tm-wash {
  position: fixed; top: 0; left: 0; width: 32px; height: 32px; margin: -16px 0 0 -16px;
  border-radius: 50%; background: radial-gradient(circle, var(--wash-color, var(--blue)), transparent 70%);
  transform: scale(0); opacity: 1; z-index: 300; pointer-events: none; filter: blur(2px);
}
#tm-wash.tm-wash-burst { transition: transform 0.6s cubic-bezier(.2,.8,.2,1), opacity 0.6s ease 0.15s; transform: scale(9); opacity: 0; }
#tm-burst { position: fixed; inset: 0; z-index: 310; pointer-events: none; }
/* a near-instant pop, like a camera flash, layered on top of everything for the first split second of the click — tinted a pale version of whichever side was chosen instead of flat white */
#tm-flash { position: fixed; inset: 0; z-index: 400; pointer-events: none; background: #fff; opacity: 0; }
#tm-flash.tm-flash--blue { background: rgb(219, 227, 255); }
#tm-flash.tm-flash--red { background: rgb(243, 219, 225); }
#tm-flash.tm-flash-go { animation: tm-flash-pop 0.28s ease-out; }
@keyframes tm-flash-pop { 0% { opacity: 0; } 6% { opacity: 0.6; } 100% { opacity: 0; } }
.tm-shock { position: fixed; top: 0; left: 0; width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%; border: 1.5px solid var(--wash-color, var(--blue)); opacity: 0; transform: scale(0); z-index: 305; pointer-events: none; }
.tm-shock.tm-go { transition: transform 0.9s cubic-bezier(.2,.8,.2,1), opacity 0.9s ease; transform: scale(38); opacity: 0; }
@keyframes tm-screen-shake { 0%, 100% { transform: translate(0, 0); } 20% { transform: translate(-3px, 2px); } 40% { transform: translate(3px, -2px); } 60% { transform: translate(-2px, -2px); } 80% { transform: translate(2px, 2px); } }
/* animated on #tm-gate itself, not body — a transform on body makes body the containing block for every
   position:fixed descendant (the gate included), and since body has ~0 natural height at this point
   (#tm-site is still hidden, everything else is fixed/absolute), the gate would collapse to a sliver
   pinned to the top of the page for the ~260ms the shake runs */
#tm-gate.tm-shake, #tm-burst.tm-shake { animation: tm-screen-shake 260ms ease-in-out; }

:root {
  --bg: #050506;
  --ink: white;
  --ink-dim: rgba(247, 242, 232, 0.55);

  --blue: #4d72ff;
  --blue-dim: rgba(77, 114, 255, 0.5);
  --red: #c44c67;
  --red-dim: rgba(196, 76, 103, 0.5);
  --font: 'Poppins', sans-serif;

  --font-mono: 'Inconsolata', monospace;
  --primary: var(--blue);
  --primary-dim: var(--blue-dim);
  --secondary: var(--red);
  --secondary-dim: var(--red-dim);

  /* the "choose a mind" gate on the home page sets html.tm-theme-blue/red once the
     visitor picks a side, which recolors --glitch-color along with it; pages with no
     gate (About) never add that class, so this just stays at its neutral default */
  --glitch-color: rgba(247, 242, 232, 0.75);
}
html.tm-theme-blue { --glitch-color: var(--blue); }
html.tm-theme-red { --primary: var(--red); --primary-dim: var(--red-dim); --secondary: var(--blue); --secondary-dim: var(--blue-dim); --glitch-color: var(--red); }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--ink); font-family: var(--font-mono); }
a { color: inherit; text-decoration: none; }
::selection { background: var(--primary); color: #000; }

.tm-glitch-link { position: relative; display: inline-block; padding: 5px; }
.tm-glitch-link:hover { color: #000; }
.tm-glitch-link:hover::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 3px;
  background-color: var(--glitch-color);
  animation: tm-link-glitch 0.03s cubic-bezier(.25, .46, .45, .94) both 5;
}
@keyframes tm-link-glitch {
  0% { transform: translate(0); }
  20% { transform: translate(-1px, 1px); }
  40% { transform: translate(-1px, -1px); }
  60% { transform: translate(1px, 1px); }
  80% { transform: translate(1px, -1px); }
  100% { transform: translate(0); }
}

.tm-noisy {
  position: fixed;
  inset: 0;
  z-index: 9500;
  pointer-events: none;
  touch-action: none;
  opacity: 0.05;
  background-image: url('/static/img/noisy/noisy-1.png');
  background-position: center;
  background-repeat: repeat;
  background-size: 130px 130px;
  animation: tm-noisy 0.2s steps(1) infinite;
  transition: opacity 0.2s ease;
}
@keyframes tm-noisy {
  0%, 100% { background-image: url('/static/img/noisy/noisy-1.png'); }
  25% { background-image: url('/static/img/noisy/noisy-2.png'); }
  50% { background-image: url('/static/img/noisy/noisy-3.png'); }
  75% { background-image: url('/static/img/noisy/noisy-4.png'); }
}

#tm-cursor-ring {
  position: fixed; top: 0; left: 0;
  width: 30px; height: 30px; margin: -15px 0 0 -15px;
  border-radius: 50%; border: 1.5px solid var(--ink);
  z-index: 700; pointer-events: none; opacity: 0;
  mix-blend-mode: difference;
  transition: opacity 0.3s ease, background 0.2s ease, border-color 0.2s ease;
}
#tm-cursor-ring.tm-on { opacity: 1; }
#tm-cursor-ring.tm-grow, #tm-cursor-ring.tm-press { background: var(--ink); border-color: transparent; }
@media (pointer: coarse) { #tm-cursor-ring { display: none !important; } }

.tm-container { max-width: 1500px; margin: 0 auto; width: 100%; }

/* ============================================================ HEADER + MENU ============================================================ */
/* Every page now has the entry gate in front of it (partials/gate.php) — the header
   starts invisible and only fades in once gate.js reveals #tm-site, same everywhere. */
#tm-site[hidden] { display: none; }
#tm-header { position: fixed; top: 0; left: 0; right: 0; z-index: 200; padding: 18px 26px; mix-blend-mode: difference; opacity: 0; transition: opacity 0.6s ease; }
#tm-header.tm-show { opacity: 1; transition-delay: 0.5s; }
#tm-header.tm-menu-active #tm-reconsider,
#tm-header.tm-menu-active .tm-header-nav { opacity: 0; pointer-events: none; transition: opacity 0.2s ease; }
.tm-header-inner { display: flex; align-items: center; justify-content: space-between; }
.tm-header-right { display: flex; align-items: center; gap: 34px; }

/* Always an <a> now (chrome-header.php) — border/padding/cursor reset is a harmless
   no-op here, kept in case that ever changes back. */
#tm-reconsider {
  position: relative; width: 70px; height: 70px; flex: none; display: block;
  border: none; padding: 0; cursor: pointer;
  background: var(--ink);
  -webkit-mask-image: url('/static/img/logo/logo_white.png');
  mask-image: url('/static/img/logo/logo_white.png');
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  filter: drop-shadow(0 0 8px var(--primary-dim));
  animation: tm-echo-breathe 3.6s ease-in-out infinite;
  transition: transform 0.25s cubic-bezier(.2,.8,.2,1);
}
#tm-reconsider:hover { transform: scale(1.06); }
@keyframes tm-echo-breathe { 0%, 100% { filter: drop-shadow(0 0 6px var(--primary-dim)); } 50% { filter: drop-shadow(0 0 12px var(--primary-dim)); } }

.tm-header-nav { display: flex; align-items: center; gap: 26px; }
.tm-nav-link { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); cursor: default; transition: color 0.25s ease; }
.tm-nav-link:hover { color: var(--ink); }
a.tm-nav-link { cursor: pointer; }
a.tm-nav-link.tm-active { color: var(--ink); }
a.tm-nav-link.tm-active::after { content: ''; display: block; width: 100%; height: 1px; margin-top: 4px; background: var(--primary); }

.tm-hamburger {
  position: relative; z-index: 1; width: 34px; height: 24px; flex: none;
  background: none; border: none; padding: 0; cursor: pointer;
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
}
.tm-hamburger span { display: block; height: 1.5px; width: 100%; background: var(--ink); transition: background 0.25s ease, transform 0.3s cubic-bezier(.2,.8,.2,1), opacity 0.2s ease, width 0.25s ease; }
.tm-hamburger:not(.tm-open):hover span { background: var(--primary); }
.tm-hamburger:not(.tm-open):hover span:nth-child(1) { transform: translateX(-3px); }
.tm-hamburger:not(.tm-open):hover span:nth-child(3) { transform: translateX(3px); width: 70%; align-self: flex-end; }
.tm-hamburger.tm-open span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.tm-hamburger.tm-open span:nth-child(2) { opacity: 0; }
.tm-hamburger.tm-open span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); width: 100%; align-self: auto; }

#tm-menu-overlay {
  position: fixed; inset: 0; z-index: 150;
  display: flex; align-items: center; justify-content: center; gap: clamp(30px, 6vw, 70px);
  background: rgba(0,0,0, 0.94);
  backdrop-filter: blur(8px);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.5s ease, visibility 0.5s ease;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
#tm-menu-overlay.tm-open { opacity: 1; visibility: visible; pointer-events: auto; }

.tm-menu-image { position: relative; flex: none; aspect-ratio: 1 / 1; overflow: hidden; opacity: 0; transform: scale(0.94); transition: opacity 0.6s ease 0.1s, transform 0.6s cubic-bezier(.2,.7,.2,1) 0.1s; }
#tm-menu-overlay.tm-open .tm-menu-image { opacity: 1; transform: scale(1); }
.tm-menu-image img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity 0.25s ease; }

@keyframes tm-image-glitch {
  0%, 100% { transform: translate(0, 0); clip-path: inset(0 0 0 0); }
  20% { transform: translate(-6px, 3px); clip-path: inset(22% 0 48% 0); }
  40% { transform: translate(5px, -4px); clip-path: inset(50% 0 14% 0); }
  60% { transform: translate(-3px, 0); clip-path: inset(8% 0 62% 0); }
  80% { transform: translate(3px, 2px); clip-path: inset(0 0 0 0); }
}
.tm-menu-image img.tm-switching { animation: tm-image-glitch 0.25s steps(1, end); }

.tm-menu-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 0; }
.tm-menu-item {
  display: flex; align-items: baseline; gap: 22px; width: 100%;
  font-weight: 300; font-size: clamp(1.6rem, 5vw, 2.9rem); letter-spacing: 0.01em; color: white;
  cursor: pointer; padding: 15px 6px; border-bottom: 1px solid rgba(255,255,255,0.2);
  opacity: 0; transform: translateY(26px);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(.2,.7,.2,1), color 0.25s ease, border-color 0.25s ease;
}
#tm-menu-overlay.tm-open .tm-menu-item { opacity: 1; transform: translateY(0); }
.tm-menu-item:nth-child(1) { transition-delay: 0.04s; }
.tm-menu-item:nth-child(2) { transition-delay: 0.09s; }
.tm-menu-item:nth-child(3) { transition-delay: 0.14s; }
.tm-menu-item:nth-child(4) { transition-delay: 0.19s; }
.tm-menu-item:nth-child(5) { transition-delay: 0.24s; }
.tm-menu-item:nth-child(6) { transition-delay: 0.29s; }
.tm-menu-item:hover, .tm-menu-item.tm-active { color: var(--ink); border-color: var(--primary-dim); }
.tm-menu-index { font-family: var(--font-mono); font-size: 0.35em; letter-spacing: 0.2em; text-transform: uppercase; color: var(--primary-dim); transition: color 0.25s ease; }
.tm-menu-item:hover .tm-menu-index, .tm-menu-item.tm-active .tm-menu-index { color: var(--primary); }

.tm-menu-content { display: flex; flex-direction: column; align-items: flex-start; }

.tm-menu-socials { position: absolute; right: clamp(20px, 4vw, 48px); bottom: clamp(20px, 4vw, 48px); display: flex; gap: 28px; opacity: 0; transition: opacity 0.5s ease 0.3s; }
#tm-menu-overlay.tm-open .tm-menu-socials { opacity: 1; }
.tm-menu-socials a { font-size: 28px; color: rgba(255, 255, 255, 1); transition: color 0.25s ease; }
.tm-menu-socials a:hover { color: var(--primary); }

.tm-menu-labels { position: absolute; left: clamp(20px, 4vw, 48px); bottom: clamp(20px, 4vw, 48px); display: flex; gap: 24px; opacity: 0; transition: opacity 0.5s ease 0.3s; }
#tm-menu-overlay.tm-open .tm-menu-labels { opacity: 1; }
.tm-menu-labels a { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(255, 255, 255, 0.45); transition: color 0.25s ease; }
.tm-menu-labels a:hover { color: var(--primary); }

@media (max-width: 760px) {
  #tm-menu-overlay { flex-direction: column; justify-content: flex-start; gap: 16px; padding: 50px 24px 40px; }
  .tm-menu-content { order: 1; }
  .tm-menu-socials { order: 2; }
  .tm-menu-labels { order: 3; }
  .tm-menu-image { order: 4; }
  .tm-menu-image { width: 100%; height: auto !important; aspect-ratio: 1 / 1; align-self: center; }
  .tm-menu-socials, .tm-menu-labels { position: static; width: 100%; justify-content: flex-start; flex-wrap: wrap; margin-top: 18px; }
  .tm-menu-content { align-self: stretch; width: 100%; }
  .tm-menu-list { align-items: stretch; align-self: stretch; width: 100%; }
  .tm-menu-item { padding: 12px 4px; gap: 16px; font-size: clamp(1.3rem, 6.5vw, 1.9rem); }
}

.tm-reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.8s ease, transform 0.8s cubic-bezier(.2,.7,.2,1); }
.tm-reveal.tm-in { opacity: 1; transform: translateY(0); }

/* blinking type-cursor "_" suffix — used after any typed/scrambled heading (home's
   "Latest Releases", About's "About") */
.tm-type-cursor { display: inline-block; margin-left: 0.05em; animation: tm-blink 1s steps(1) infinite; }
@keyframes tm-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* ============================================================ CTA (shared component) ============================================================ */
.tm-cta { position: relative; display: inline-block; }
.tm-cta::before { content: ''; position: absolute; inset: 0; border: 1px solid var(--primary); pointer-events: none; opacity: 0; transition: opacity 0.2s ease; }
.tm-cta:hover::before { opacity: 1; animation: tm-cta-gfx2 0.15s cubic-bezier(.24,.45,.44,.93) both infinite, tm-cta-blink 0.5s steps(1, end) infinite; }
.tm-cta__link { position: relative; display: block; padding: 15px 42px; line-height: 1.6em; font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink); -webkit-tap-highlight-color: transparent; }
.tm-cta__link::before { content: ''; position: absolute; inset: 0; border: 1px solid rgba(247, 242, 232, 0.75); pointer-events: none; opacity: 0; transition: opacity 0.2s ease; }
.tm-cta:hover .tm-cta__link::before { opacity: 1; animation: tm-cta-gfx1 0.2s cubic-bezier(.24,.45,.44,.93) both infinite, tm-cta-blink 0.5s steps(1, end) 0.12s infinite; }
.tm-cta:not(.tm-cta--solid) .tm-cta__link::before { opacity: 1; }
@keyframes tm-cta-gfx1 { 0% { transform: translate(0); } 20% { transform: translate(-1px, 1px) skewX(10deg); } 40% { transform: translate(-1px, -1px) skewX(2deg); } 60% { transform: translate(1px, 1px) skewX(15deg); } 80% { transform: translate(1px, -1px) skewX(4deg); } 100% { transform: translate(0); } }
@keyframes tm-cta-gfx2 { 0% { transform: translate(0); } 20% { transform: translate(-1px, 1px) skewX(-10deg); } 40% { transform: translate(-1px, -1px) skewX(-2deg); } 60% { transform: translate(1px, 1px) skewX(-15deg); } 80% { transform: translate(1px, -1px) skewX(-4deg); } 100% { transform: translate(0); } }
@keyframes tm-cta-blink { 0%, 100% { opacity: 1; } 15% { opacity: 0.1; } 25% { opacity: 1; } 40% { opacity: 0.15; } 50% { opacity: 1; } 65% { opacity: 0.1; } 75% { opacity: 1; } }
.tm-cta--solid .tm-cta__link { background: #050506; color: #fff; transition: background 0.15s ease, color 0.15s ease; }
.tm-cta--solid:hover .tm-cta__link { background: transparent; color: var(--primary); }
.tm-cta--solid .tm-cta__link::before { border-color: rgba(5, 5, 6, 0.5); }

/* ============================================================ PAGE OUTLET ============================================================ */
#tm-page-outlet { position: relative; }

/* ============================================================ EVENTS LIST (shared: home's "Recent shows" + dates.php's list view) ============================================================ */
/* One definition so the two lists can never visually drift apart — dates.php's
   list view reuses these exact classes (its own .tm-dt-item wrapper adds the
   list/grid-toggle behavior on top, see dates.php's own <style>). */
.tm-events-list { border-top: 1px solid rgba(247, 242, 232, 0.14); }
.tm-events-row {
  position: relative; display: grid; grid-template-columns: 60px minmax(0, 1fr) auto auto 22px;
  align-items: center; column-gap: 22px;
  padding: 26px 14px; border-bottom: 1px solid rgba(247, 242, 232, 0.14);
  color: var(--ink-dim); text-decoration: none;
  /* opacity/transform timing included here too (not just color/background) — dates.php
     also puts .tm-reveal on this same element for a per-row scroll-in entrance, and
     since both rules set the "transition" shorthand, whichever is declared later in
     the cascade wins outright (no per-property merging) — without this, this rule's
     own color/background-only transition silently ate .tm-reveal's fade/slide,
     leaving the entrance instant and invisible instead of animated. */
  transition: color 0.3s ease, background 0.3s ease, opacity 0.8s ease, transform 0.8s cubic-bezier(.2,.7,.2,1);
}
.tm-events-row::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--primary); transform: scaleY(0); transform-origin: bottom; transition: transform 0.35s cubic-bezier(.2,.8,.2,1);
}
.tm-events-row:hover { color: var(--ink); background: rgba(247, 242, 232, 0.03); }
.tm-events-row:hover::before { transform: scaleY(1); }

.tm-events-index {
  font-family: var(--font-mono); font-weight: 800; font-size: clamp(1.6rem, 2.6vw, 2.1rem); line-height: 1;
  color: transparent; -webkit-text-stroke: 1px var(--primary-dim);
  transition: -webkit-text-stroke-color 0.3s ease;
}
.tm-events-row:hover .tm-events-index { -webkit-text-stroke-color: var(--primary); }
.tm-events-name { font-family: var(--font-mono); font-weight: 700; font-size: clamp(1.05rem, 1.9vw, 1.35rem); color: var(--ink); }
.tm-events-venue { font-size: 13px; opacity: 0.65; white-space: nowrap; }
.tm-events-venue i { color: var(--primary); font-size: 11px; margin-right: 6px; }
.tm-events-date { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.85; white-space: nowrap; }
.tm-events-arrow {
  font-family: var(--font-mono); opacity: 0; transform: translateX(-6px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.tm-events-row:hover .tm-events-arrow { opacity: 1; transform: translateX(0); }

/* floating event photo that follows the cursor while a row is hovered — position/scale are driven entirely from JS */
.tm-events-preview {
  position: fixed; top: 0; left: 0; z-index: 50; pointer-events: none;
  width: 230px; aspect-ratio: 3 / 4; overflow: hidden;
  opacity: 0; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
  transition: opacity 0.3s ease;
}
.tm-events-preview.tm-show { opacity: 1; }
.tm-events-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tm-events-preview::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(5, 5, 6, 0.7) 100%);
}

@media (max-width: 640px) {
  .tm-events-preview { display: none; }
  .tm-events-row { grid-template-columns: 40px 1fr; row-gap: 6px; padding: 20px 8px; }
  .tm-events-index { font-size: 1.3rem; }
  .tm-events-venue, .tm-events-date { grid-column: 2 / 3; opacity: 0.6; }
  .tm-events-arrow { display: none; }
}

/* ============================================================ STUB PAGES (Dates, Studio & Lab, Links, Contact — content to come) ============================================================ */
.tm-stub-page { min-height: 70vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 190px 8vw 140px; text-align: center; }
.tm-stub-eyebrow { font-family: var(--font-mono); font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--primary); margin: 0 0 14px; }
.tm-stub-title { display: flex; align-items: baseline; justify-content: center; font-family: var(--font-mono); font-weight: 700; font-size: clamp(2rem, 6vw, 3.4rem); letter-spacing: -0.01em; margin: 0 0 18px; }
.tm-stub-copy { font-size: 15px; color: var(--ink-dim); max-width: 46ch; }
.tm-stub-contact { margin-top: 30px; display: flex; flex-direction: column; gap: 8px; }
.tm-stub-contact p { margin: 0; font-size: 14px; }
.tm-stub-contact-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-dim); margin-right: 10px; }
.tm-stub-contact a { color: var(--ink); }

/* ============================================================ SITE FOOTER ============================================================ */
/* The "finale" video band and its modal — right above the real footer, on every page
   (partials/chrome-footer.php). */
.tm-finale { position: relative; min-height: 58vh; display: flex; align-items: center; justify-content: center; overflow: hidden; text-align: center; padding: 80px 8vw; }
.tm-finale-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.tm-finale:after {
  position: absolute;
  width: 100%;
  height: calc(100% + 20px);
  top: -20px;
  left: 0;
  bottom: 0;
  right: 0;
  content: "";
  background-size: 3.5px;
  background-image: url("https://latitude-one.com/static/img/textures/back_dots.png");
  mix-blend-mode: overlay;
}
.tm-finale-shade {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(5, 5, 6, 0.55) 0%, rgba(5, 5, 6, 0.2) 34%, rgba(5, 5, 6, 0.3) 66%, rgba(5, 5, 6, 0.85) 100%),
    linear-gradient(90deg, rgba(5, 5, 6, 0.4) 0%, transparent 24%, transparent 76%, rgba(5, 5, 6, 0.4) 100%);
}
.tm-finale-content { position: relative; z-index: 2; max-width: 780px; display: flex; flex-direction: column; align-items: center; }
.tm-finale-eyebrow { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(247, 242, 232, 0.75); margin: 0 0 26px; }
/* same recipe as home's .tm-meet-play — white circle, dark triangle, swaps to the theme color on hover */
.tm-finale-play {
  width: 72px; height: 72px; border-radius: 50%; margin: 0 0 20px;
  border: none; background: #fff; box-shadow: 0 10px 30px rgba(5, 5, 6, 0.4);
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer;
  transition: transform 0.25s cubic-bezier(.2,.8,.2,1), background 0.3s ease;
}
/* transform (magnetic pull + hover scale) is driven from JS */
.tm-finale-content:hover .tm-finale-play { background: var(--primary); }
.tm-finale-play svg { width: 18px; height: 18px; margin-left: 3px; fill: var(--bg); transition: fill 0.3s ease; }
.tm-finale-content:hover .tm-finale-play svg { fill: #fff; }
.tm-finale-play-label { font-family: var(--font-mono); font-weight: 700; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); margin: 0; }
.tm-finale::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; z-index: 2;
  background: linear-gradient(90deg, var(--blue), var(--red));
}
@media (max-width: 640px) {
  .tm-finale { padding: 60px 7vw; min-height: 48vh; }
  .tm-finale-play { width: 60px; height: 60px; }
}

.tm-video-modal { position: fixed; inset: 0; z-index: 620; display: flex; align-items: center; justify-content: center; padding: 30px; opacity: 0; visibility: hidden; transition: opacity 0.35s ease, visibility 0.35s ease; }
.tm-video-modal.tm-open { opacity: 1; visibility: visible; }
.tm-video-modal-backdrop { position: absolute; inset: 0; background: rgba(5, 5, 6, 0.92); backdrop-filter: blur(8px); }
.tm-video-modal-panel { position: relative; z-index: 1; width: 100%; max-width: 960px; aspect-ratio: 16 / 9; background: #000; }
.tm-video-modal-panel iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.tm-video-modal-close {
  position: absolute; top: 14px; right: 14px; z-index: 2; width: 34px; height: 34px; border-radius: 50%;
  background: rgba(5, 5, 6, 0.6); border: none; color: var(--ink); font-size: 20px; line-height: 1; cursor: pointer;
}

/* ============================================================ CONTACT MODAL (shared, partials/contact-modal.php) ============================================================ */
/* A light, self-contained panel (not the dark site chrome) so it reads clearly as
   a dialog floating above whatever page opened it, on top of the same dark
   backdrop+blur the video modal uses. Square corners throughout (panel, photo,
   fields) and a plain "×" close, same crisp/no-radius language as the existing
   .tm-release-modal (home page) rather than a softer rounded card. */
.tm-contact-modal { position: fixed; inset: 0; z-index: 630; display: flex; align-items: center; justify-content: center; padding: 24px; opacity: 0; visibility: hidden; transition: opacity 0.35s ease, visibility 0.35s ease; }
.tm-contact-modal.tm-open { opacity: 1; visibility: visible; }
.tm-contact-modal-backdrop { position: absolute; inset: 0; background: rgba(5, 5, 6, 0.88); backdrop-filter: blur(8px); }
.tm-contact-modal-panel {
  position: relative; z-index: 1; width: 100%; max-width: 900px; max-height: 88vh; overflow-y: auto;
  background: #f7f2e8; box-shadow: 0 30px 80px rgba(5, 5, 6, 0.55);
  display: grid; grid-template-columns: minmax(220px, 320px) minmax(0, 1fr);
}
.tm-contact-modal-close {
  position: absolute; top: 14px; right: 14px; z-index: 2; width: 30px; height: 30px;
  background: none; border: none; color: rgba(5, 5, 6, 0.5); font-size: 22px; line-height: 1; cursor: pointer; transition: color 0.2s ease;
}
.tm-contact-modal-close:hover { color: #050506; }
@media (max-width: 760px) { .tm-contact-modal-panel { grid-template-columns: 1fr; max-width: 480px; } }
@media (max-width: 560px) { .tm-contact-modal { padding: 12px; } }

/* Portrait filling the left column. The column itself (".tm-contact-modal-visual")
   stretches to the full row height — matching the form, whatever height that ends
   up being once "I am a" reveals the rest of the fields — and stays black the
   whole way down, so there's no dead beige gap once the form grows taller than
   the photo. The photo + email overlay together are a sticky inner block, pinned
   near the top of that black column as the panel scrolls, rather than the column
   itself being sticky (which left its own height capped and the gap exposed). */
.tm-contact-modal-visual { position: relative; background: var(--bg); overflow: hidden; }
.tm-contact-modal-visual-sticky { position: sticky; top: 0; height: min(560px, 82vh); overflow: hidden; }
.tm-contact-modal-visual-sticky img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 32% 10%; }
.tm-contact-modal-visual-fade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(5, 5, 6, 0.05) 0%, rgba(5, 5, 6, 0.1) 45%, rgba(5, 5, 6, 0.95) 100%); }
.tm-contact-modal-visual-info { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; padding: 24px 22px; display: flex; flex-direction: column; gap: 16px; }
.tm-contact-visual-label { font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--primary); margin: 0 0 6px; }
.tm-contact-visual-email { display: inline-block; font-family: var(--font-mono); font-size: 14px; font-weight: 700; color: #fff; word-break: break-word; }
@media (max-width: 760px) { .tm-contact-modal-visual-sticky { position: relative; top: 0; height: 200px; } }

.tm-contact-modal-col { position: relative; z-index: 1; padding: 54px 40px 40px; display: flex; flex-direction: column; gap: 24px; }
@media (max-width: 560px) { .tm-contact-modal-col { padding: 46px 24px 30px; } }

.tm-contact-hero { position: relative; z-index: 1; }
.tm-contact-title { display: flex; align-items: baseline; font-family: var(--font-mono); font-weight: 700; font-size: clamp(1.7rem, 4vw, 2.3rem); letter-spacing: -0.01em; margin: 0 0 12px; color: #050506; }
.tm-contact-lede { font-size: 14px; line-height: 1.7; color: rgba(5, 5, 6, 0.6); max-width: 44ch; margin: 0; }

.tm-contact-form { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 18px; text-align: left; }
.tm-contact-field { position: relative; display: flex; flex-direction: column; gap: 6px; }
.tm-contact-field label { font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(5, 5, 6, 0.55); }
.tm-contact-field input, .tm-contact-field textarea, .tm-contact-field select {
  background: rgba(5, 5, 6, 0.03); border: 1px solid #050506; border-radius: 0;
  color: #050506; font-family: var(--font); font-size: 14px; padding: 10px 12px;
  transition: border-color 0.25s ease, background 0.25s ease; resize: vertical;
}
.tm-contact-field input::placeholder, .tm-contact-field textarea::placeholder { color: rgba(5, 5, 6, 0.35); }
.tm-contact-field input:focus, .tm-contact-field textarea:focus, .tm-contact-field select:focus { outline: none; border-color: var(--primary); background: rgba(5, 5, 6, 0.02); }
.tm-contact-field textarea { min-height: 88px; line-height: 1.6; }
.tm-contact-field select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, rgba(5, 5, 6, 0.5) 50%), linear-gradient(135deg, rgba(5, 5, 6, 0.5) 50%, transparent 50%);
  background-position: calc(100% - 16px) center, calc(100% - 11px) center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.tm-contact-field select option { background: #f7f2e8; color: #050506; }

/* Everything past "I am a" stays collapsed until a role is picked — a light bit
   of progressive disclosure rather than dumping the whole form at once. */
.tm-contact-more {
  display: flex; flex-direction: column; gap: 18px;
  max-height: 0; opacity: 0; overflow: hidden; pointer-events: none;
  transition: max-height 0.5s ease, opacity 0.35s ease;
}
.tm-contact-more.tm-open { max-height: 900px; opacity: 1; pointer-events: auto; transition: max-height 0.5s ease, opacity 0.4s ease 0.1s; }

/* The shared glitch CTA (.tm-cta / .tm-cta--solid, above) stretched to fill the
   row instead of its usual inline-sized self. */
.tm-contact-submit-wrap.tm-cta { display: block; width: 100%; margin-top: 2px; }
.tm-contact-submit-wrap .tm-cta__link { width: 100%; box-sizing: border-box; text-align: center; border: none; font-size: 12px; cursor: pointer; }
/* .tm-cta's own glitch jitter (tm-cta-gfx1/2, above) skews the border by its own
   height — barely visible on the small inline pill it was designed for, but this
   button is full width, so that skew reads as several pixels of border sliding
   past the button's own edge (looks like the modal is clipping the animation).
   Same color-blink glitch, translate only, no skew, so it stays inside the button. */
.tm-contact-submit-wrap.tm-cta:hover::before { animation: tm-contact-cta-gfx2 0.15s cubic-bezier(.24,.45,.44,.93) both infinite, tm-cta-blink 0.5s steps(1, end) infinite; }
.tm-contact-submit-wrap.tm-cta:hover .tm-cta__link::before { animation: tm-contact-cta-gfx1 0.2s cubic-bezier(.24,.45,.44,.93) both infinite, tm-cta-blink 0.5s steps(1, end) 0.12s infinite; }
@keyframes tm-contact-cta-gfx1 { 0% { transform: translate(0); } 20% { transform: translate(-1px, 1px); } 40% { transform: translate(-1px, -1px); } 60% { transform: translate(1px, 1px); } 80% { transform: translate(1px, -1px); } 100% { transform: translate(0); } }
@keyframes tm-contact-cta-gfx2 { 0% { transform: translate(0); } 20% { transform: translate(1px, 1px); } 40% { transform: translate(1px, -1px); } 60% { transform: translate(-1px, 1px); } 80% { transform: translate(-1px, -1px); } 100% { transform: translate(0); } }
#tm-contact-submit:disabled { opacity: 0.45; cursor: default; pointer-events: none; }

.tm-contact-response { font-family: var(--font-mono); font-size: 12px; min-height: 1.4em; margin: 0; color: rgba(5, 5, 6, 0.6); }
.tm-contact-response.tm-ok { color: var(--primary); }
.tm-contact-response.tm-err { color: var(--red); }

.tm-outro-footer { position: relative; background: var(--bg); color: var(--ink); overflow: hidden; }
.tm-outro-footer::before {
  content: ''; position: absolute; z-index: 0; inset: 0; pointer-events: none;
  background:
    radial-gradient(45% 55% at 10% 0%, rgba(77, 114, 255, 0.18), transparent 70%),
    radial-gradient(50% 60% at 90% 100%, rgba(196, 76, 103, 0.16), transparent 70%);
}
.tm-outro-footer__top { position: relative; z-index: 1; display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 6vw; padding: 100px 8vw 70px; }
.tm-outro-footer__menu, .tm-outro-footer__notify { border-left: 1px solid rgba(247, 242, 232, 0.14); padding-left: 30px; margin-left: -3vw; }
.tm-outro-footer__mark {
  width: 42px; height: 42px; margin: 0 0 18px; background: var(--ink);
  filter: drop-shadow(0 0 18px rgba(247, 242, 232, 0.18));
  -webkit-mask-image: url('/static/img/logo/logo_white.png'); mask-image: url('/static/img/logo/logo_white.png');
  -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.tm-outro-footer__word { font-family: 'Agelast', var(--font); font-weight: 700; font-size: 1.8rem; letter-spacing: 0.12em; margin: 0 0 16px; color: #fff; }
.tm-outro-footer__tagline { font-size: 16px; font-weight: 600; line-height: 1.6; color: #fff; max-width: 34ch; margin: 0 0 28px; }
.tm-outro-footer__socials { display: flex; gap: 12px; }
.tm-outro-footer__socials a {
  display: flex; align-items: center; justify-content: center; width: 42px; height: 42px;
  border: 1px solid rgba(247, 242, 232, 0.4); border-radius: 50%; color: #fff; font-size: 16px;
  transition: color 0.25s ease, border-color 0.25s ease, background 0.25s ease, transform 0.25s ease;
}
.tm-outro-footer__socials a:hover { color: #fff; background: var(--primary); border-color: var(--primary); transform: translateY(-3px); }
.tm-outro-footer__heading { font-family: var(--font-mono); font-weight: 700; font-size: 13px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--primary); margin: 0 0 22px; }
.tm-outro-footer__menu { display: flex; flex-direction: column; gap: 18px; align-items: flex-start; }
.tm-outro-footer__menu .tm-glitch-link { font-size: 20px; font-weight: 700; color: #fff; padding: 2px 0; }
.tm-outro-footer__menu .tm-glitch-link:hover { color: var(--primary); }
.tm-outro-footer__menu a.tm-glitch-link.tm-active { color: var(--primary); }
.tm-outro-footer__notify-copy { font-size: 16px; font-weight: 600; line-height: 1.55; color: #fff; max-width: 32ch; margin: 0 0 20px; }
.tm-outro-notify-form { display: flex; align-items: center; gap: 10px; border-bottom: 1px solid rgba(247, 242, 232, 0.35); padding-bottom: 10px; transition: border-color 0.25s ease; }
.tm-outro-notify-form:focus-within { border-color: var(--primary); }
.tm-outro-notify-form input[type="email"] { flex: 1; min-width: 0; background: none; border: none; color: #fff; font-family: var(--font-mono); font-weight: 600; font-size: 15px; padding: 6px 0; outline: none; }
.tm-outro-notify-form input[type="email"]::placeholder { color: rgba(247, 242, 232, 0.45); }
.tm-outro-notify-form button { flex: none; display: inline-flex; align-items: center; gap: 6px; background: none; border: none; color: #fff; font-family: var(--font-mono); font-weight: 700; font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; padding: 6px 4px; transition: color 0.25s ease, opacity 0.25s ease, transform 0.25s ease; }
.tm-outro-notify-form button:hover { color: var(--primary); transform: translateX(3px); }
.tm-outro-notify-form button:disabled { opacity: 0.4; cursor: default; transform: none; }
.tm-hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.tm-outro-notify-response { margin: 12px 0 0; font-size: 13px; font-weight: 600; min-height: 1.4em; color: rgba(247, 242, 232, 0.7); }
.tm-outro-notify-response.tm-ok { color: var(--primary); }
.tm-outro-notify-response.tm-err { color: var(--red); }
.tm-outro-footer__bottom { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 14px; padding: 22px 8vw 70px; border-top: 1px solid rgba(247, 242, 232, 0.22); font-size: 13px; font-weight: 600; letter-spacing: 0.04em; color: rgba(247, 242, 232, 0.75); }
.tm-outro-footer__bottom-right { display: flex; align-items: center; gap: 22px; }
.tm-outro-totop { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(247, 242, 232, 0.35); background: none; color: var(--ink); cursor: pointer; padding: 0; transition: border-color 0.25s ease, background 0.25s ease, color 0.25s ease, transform 0.25s ease; }
.tm-outro-totop:hover { background: var(--primary); border-color: var(--primary); color: #fff; transform: translateY(-3px); }

@media (max-width: 860px) {
  .tm-outro-footer__top { grid-template-columns: 1fr 1fr; }
  .tm-outro-footer__top > :first-child { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  #tm-header { padding: 14px 16px; }
  #tm-gate { gap: 22px; padding: 24px 0; }
  .tm-gate-title { font-size: clamp(1.6rem, 9vw, 2.4rem); letter-spacing: 0.09em; }
  #tm-sound { right: 14px; bottom: 14px; padding: 8px 12px; font-size: 10px; }
  .tm-outro-footer__top { grid-template-columns: 1fr; gap: 44px; padding: 70px 7vw 50px; }
  .tm-outro-footer__menu, .tm-outro-footer__notify { border-left: none; padding-left: 0; margin-left: 0; }
  .tm-outro-footer__bottom { flex-direction: column; align-items: flex-start; padding: 20px 7vw 56px; }
}
@media (max-height: 640px) {
  #tm-gate { gap: 12px; }
  .tm-gate-title { font-size: clamp(1.4rem, 7vh, 2.4rem); }
  .tm-orb-wrap { width: clamp(140px, 38vh, 360px); height: clamp(140px, 38vh, 360px); }
}
