/* ===========================================================================
   Keystreak - marketing site.

   Colours are lifted from src/renderer/src/theme.ts and the chunky card
   structure is the game's: flat fills, thick dark borders, hard offset
   shadows, nothing perfectly straight.
   ======================================================================== */

/* Silkscreen: the game's own face, for anything the game itself would put on
   screen. It draws no true lowercase - every glyph is a capital - and covers
   U+0020 to U+00FF and nothing else, so copy set in it stays inside Latin-1
   and uses a plain hyphen and a straight quote. */
@font-face {
  font-family: 'Silkscreen';
  src: url('/silkscreen-latin.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: block;
  unicode-range: U+0000-00FF;
}

/* Space Grotesk: everything Silkscreen cannot carry. A geometric grotesque
   with squared-off terminals and a slightly odd 'a' and 'g' - it sits beside
   pixel type without either one apologising. One variable file, 22 KB, covers
   400 through 600. */
@font-face {
  font-family: 'Space Grotesk';
  src: url('/space-grotesk-latin.woff2') format('woff2');
  font-weight: 400 600; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+2013-2014, U+2018-201A, U+201C-201E, U+2026;
}

:root {
  --velvet-light: #3B2F63;
  --velvet: #241C42;
  --velvet-shadow: #171128;

  --panel: #1E1833;
  --panel-inset: #332B4E;
  --panel-edge: #0E0A1B;
  --panel-lip: #4A3F6B;

  --chips: #1FB6A3;
  --chips-edge: #0C6154;
  --chips-ice: #9DEDE2;

  --mult: #F5479B;
  --mult-edge: #94104F;

  --gold: #FFB63D;
  --gold-edge: #9C6512;

  --next: #8B6BFF;
  --next-glow: #C6BBFF;

  --green: #7BD938;
  --green-lit: #9BE860;
  --green-edge: #3F8A15;
  --green-deep: #2E6510;

  --card-face: #F6F3FA;
  --card-edge: #171128;

  --hand-right: #FF7A3D;
  --hand-left: #7B6BFF;

  --text: #F3EFFA;
  --dim: rgba(243, 239, 250, 0.66);
  --dimmer: rgba(243, 239, 250, 0.52);

  --pixel: 'Silkscreen', ui-monospace, 'Courier New', monospace;
  --sans: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  --wrap: 1120px;
  --gap: clamp(64px, 10vw, 128px);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--velvet);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.72;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Silkscreen's 1px counters fill in at 700, so weight never carries hierarchy
   on the pixel side. Space Grotesk does the emphasis instead. */
h1, h2, h3 { font-weight: 400; margin: 0; }
img, video { max-width: 100%; height: auto; display: block; }
a { color: var(--text); text-decoration: none; }
button { font: inherit; }

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 60;
  font-family: var(--pixel); font-size: 12px; letter-spacing: 0.1em;
  color: var(--velvet-shadow); background: var(--green);
  border-radius: 0 0 8px 8px; padding: 12px 18px;
  transition: top 0.15s;
}
.skip:focus { top: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------- the sky */
.sky { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.nebula {
  position: absolute; inset: -20%;
  background:
    radial-gradient(58% 42% at 22% 14%, rgba(139, 107, 255, 0.30), transparent 62%),
    radial-gradient(46% 40% at 82% 26%, rgba(31, 182, 163, 0.14), transparent 66%),
    radial-gradient(64% 48% at 68% 74%, rgba(245, 71, 155, 0.13), transparent 64%),
    radial-gradient(52% 46% at 12% 82%, rgba(59, 47, 99, 0.60), transparent 68%);
  filter: blur(24px);
  animation: drift 68s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-1.5%, -1%, 0) scale(1.04); }
  to   { transform: translate3d(2%, 1.5%, 0) scale(1.10); }
}
.stars { position: absolute; inset: 0; }
.stars::before { content: ''; position: absolute; width: 2px; height: 2px; border-radius: 50%; }
.s1::before {
  box-shadow: 40vw 12vh #fff, 8vw 34vh #fff, 71vw 8vh #fff, 92vw 41vh #fff, 23vw 62vh #fff,
    57vw 77vh #fff, 84vw 91vh #fff, 15vw 88vh #fff, 66vw 29vh #fff, 33vw 45vh #fff,
    5vw 71vh #fff, 96vw 66vh #fff, 48vw 96vh #fff, 78vw 55vh #fff, 27vw 19vh #fff;
  opacity: 0.85;
}
.s2::before {
  box-shadow: 18vw 22vh var(--next-glow), 62vw 47vh var(--chips-ice), 88vw 15vh #fff,
    36vw 83vh var(--next-glow), 74vw 68vh #fff, 11vw 53vh #fff, 52vw 6vh var(--chips-ice),
    97vw 79vh #fff, 44vw 36vh #fff, 29vw 94vh var(--next-glow);
  opacity: 0.5; width: 3px; height: 3px;
}
.s3::before {
  box-shadow: 7vw 9vh #fff, 31vw 27vh #fff, 59vw 18vh #fff, 81vw 37vh #fff, 13vw 44vh #fff,
    46vw 58vh #fff, 69vw 84vh #fff, 90vw 59vh #fff, 21vw 73vh #fff, 55vw 91vh #fff;
  opacity: 0.3; width: 1px; height: 1px;
}
.s1 { animation: rise 150s linear infinite; }
.s2 { animation: rise 95s linear infinite; }
.s3 { animation: rise 220s linear infinite; }
@keyframes rise { to { transform: translateY(-100vh); } }

/* ----------------------------------------------------------------- chrome */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 15px clamp(16px, 4vw, 40px);
  background: rgba(23, 17, 40, 0.76);
  backdrop-filter: blur(12px);
  border-bottom: 2px solid var(--panel-edge);
}
.lockup { display: inline-flex; align-items: center; gap: 0.62em; margin: 0; }
.lockup img { width: auto; height: 1.7em; }
.lockup .wordmark {
  font-family: var(--pixel);
  font-size: 1em;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--text);
  text-shadow: 2px 2px 0 var(--card-edge);
  transform: rotate(-1.5deg);
  white-space: nowrap;
}
.brand { font-size: 18px; }
.lockup.big { font-size: 24px; }
.lockup.big .wordmark { text-shadow: 3px 3px 0 var(--card-edge); }
.topbar nav { display: flex; align-items: center; gap: clamp(14px, 2.6vw, 30px); font-size: 15px; }
.topbar nav a { color: var(--dim); }
.topbar nav a:hover { color: var(--text); }
@media (max-width: 680px) { .topbar nav a:not(.navcta) { display: none; } }

main { max-width: var(--wrap); margin: 0 auto; padding: 0 clamp(16px, 4vw, 32px); }

/* ------------------------------------------------------------------- type */
h1 {
  font-family: var(--pixel);
  font-size: clamp(30px, 6.2vw, 56px);
  line-height: 1.34; letter-spacing: 0.005em;
  margin-top: 24px;
  text-shadow: 0 3px 0 var(--velvet-shadow);
}
h2 {
  font-family: var(--pixel);
  font-size: clamp(20px, 3.2vw, 30px);
  line-height: 1.5;
}
h3 { font-size: 18px; line-height: 1.45; margin-bottom: 12px; letter-spacing: -0.01em; }

/* Every tile heading is Silkscreen - it is a label on a card, which is exactly
   what the game uses this face for. Sized up, because Silkscreen sits small in
   its em box, and given room to breathe since it has no lowercase to fall to. */
.panel h3 {
  font-family: var(--pixel);
  font-size: 17px;
  line-height: 1.55;
  letter-spacing: 0.05em;
  color: var(--text);
  margin-bottom: 16px;
}

.lede { font-size: clamp(16px, 1.75vw, 18px); color: var(--dim); max-width: 33em; margin: 26px auto 0; }
.say  { color: var(--dim); max-width: 40em; margin: 18px 0 0; }
.say.lead { font-size: 17px; margin-top: 14px; }

.band { padding: var(--gap) 0 0; }

/* ------------------------------------------------------ chunky game button
   The game's buttons are a flat fill inside a hard dark edge, sitting on a
   solid shadow with no blur - they read as a physical key you can push down,
   which is why pressing one moves it onto its own shadow. */
.btn, .signup button, .navcta {
  display: inline-block;
  font-family: var(--pixel); font-size: 14px; letter-spacing: 0.12em;
  color: var(--velvet-shadow);
  background: var(--green);
  border: 0;
  border-radius: 9px;
  padding: 15px 24px 14px;
  cursor: pointer;
  box-shadow:
    inset 0 2px 0 var(--green-lit),
    0 5px 0 var(--green-edge),
    0 5px 0 1px var(--card-edge);
  transition: transform 0.07s ease, box-shadow 0.07s ease;
}
.btn:hover, .signup button:hover, .navcta:hover {
  background: var(--green-lit);
  transform: translateY(2px);
  box-shadow: inset 0 2px 0 #B6F088, 0 3px 0 var(--green-edge), 0 3px 0 1px var(--card-edge);
}
.btn:active, .signup button:active, .navcta:active {
  transform: translateY(5px);
  box-shadow: inset 0 2px 0 var(--green-lit), 0 0 0 var(--green-edge), 0 0 0 1px var(--card-edge);
}
.signup button:focus-visible, .navcta:focus-visible { outline: 3px solid var(--next-glow); outline-offset: 3px; }
.signup button[disabled] { opacity: 0.62; cursor: default; transform: none; }
.navcta { color: var(--velvet-shadow) !important; padding: 10px 17px 9px; font-size: 12px; }

/* ------------------------------------------------------------------- hero */
.hero { position: relative; padding: clamp(52px, 9vw, 92px) 0 0; text-align: center; }

/* The game's falling note cards: a cream face in a thick hand-coloured edge,
   the note letter printed at both ends, and a height set by how long the note
   sounds. Coral is the right hand, periwinkle the left. */
.notes { position: absolute; inset: 0 0 auto; height: 620px; overflow: hidden; z-index: -1; }
.notes i {
  position: absolute; left: var(--x); top: -220px;
  width: 42px; height: var(--h);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 5px 0;
  background: var(--card-face);
  border: 4px solid var(--hand-right);
  border-radius: 7px;
  box-shadow: 0 5px 0 rgba(23, 17, 40, 0.5);
  transform: rotate(var(--r));
  animation: fall var(--s) linear infinite; animation-delay: var(--d);
  opacity: 0.9;
}
.notes i b {
  font-family: var(--pixel); font-weight: 400; font-size: 11px;
  color: var(--hand-right); text-align: center; line-height: 1;
}
.notes i.left, .notes i.left b { border-color: var(--hand-left); color: var(--hand-left); }
/* Per-note position, height, timing and tilt. Kept here rather than as style
   attributes on the <i> so the CSP can drop 'unsafe-inline'. */
.notes i:nth-child(1) { --x:2%; --h:150px; --d:0s; --s:13s; --r:-3deg; }
.notes i:nth-child(2) { --x:8%; --h:96px; --d:-4.2s; --s:15s; --r:2deg; }
.notes i:nth-child(3) { --x:14%; --h:190px; --d:-8.6s; --s:12s; --r:-2deg; }
.notes i:nth-child(4) { --x:85%; --h:118px; --d:-2.1s; --s:14s; --r:3deg; }
.notes i:nth-child(5) { --x:91%; --h:172px; --d:-6.4s; --s:12.5s; --r:-2deg; }
.notes i:nth-child(6) { --x:96%; --h:88px; --d:-10s; --s:16s; --r:2deg; }
@keyframes fall {
  0%   { transform: translateY(0) rotate(var(--r)); opacity: 0; }
  10%  { opacity: 0.9; }
  88%  { opacity: 0.9; }
  100% { transform: translateY(900px) rotate(var(--r)); opacity: 0; }
}
@media (max-width: 1080px) { .notes { display: none; } }

.status {
  display: inline-flex; align-items: center; gap: 11px; margin: 0;
  font-family: var(--pixel); font-size: 11px; letter-spacing: 0.2em;
  color: var(--chips-ice);
}
.status b { width: 7px; height: 7px; border-radius: 50%; background: var(--chips); box-shadow: 0 0 10px var(--chips); animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: 0.28; } }

.herovideo {
  position: relative; margin: clamp(44px, 6vw, 68px) 0 0;
  border: 3px solid var(--card-edge); border-radius: 14px;
  box-shadow: 0 10px 0 var(--panel-edge), 0 24px 64px rgba(0, 0, 0, 0.6);
  overflow: hidden; background: var(--velvet-shadow);
  line-height: 0;
}
.herovideo video { width: 100%; height: auto; }
.vcontrols {
  position: absolute; right: 12px; bottom: 12px; z-index: 2;
  display: flex; gap: 8px; line-height: 1;
}
.vbtn {
  font-family: var(--pixel); font-size: 10px; letter-spacing: 0.12em; line-height: 1;
  color: var(--text); background: rgba(23, 17, 40, 0.82);
  border: 2px solid var(--panel-lip); border-radius: 6px;
  padding: 9px 12px 8px; cursor: pointer;
  transition: background 0.15s, opacity 0.18s;
}
.vbtn:hover { background: var(--panel-inset); }
.vbtn:focus-visible { outline: 3px solid var(--next-glow); outline-offset: 2px; }
.vbtn.on { background: var(--green); color: var(--velvet-shadow); border-color: var(--green-edge); }

/* ----------------------------------------------------------------- panels */
.panel {
  background: var(--panel);
  border: 3px solid var(--card-edge);
  border-radius: 10px;
  box-shadow: 0 6px 0 var(--panel-edge);
  padding: 24px 24px 26px;
}
.panel p { margin: 0; color: var(--dim); font-size: 15px; }
.cards3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin: 40px 0 0; }
@media (max-width: 900px) { .cards3 { grid-template-columns: 1fr; } }


/* --------------------------------------------------------- the grade pane
   The five rungs a card climbs. Each is a miniature of the game's card rather
   than a colour swatch: a frame - flat, then metal at the top two - around a
   marbled face, with the nameplate grown out of the bottom rail. The face is
   layered radial gradients standing in for the shader the game draws per song,
   which is why no two of these read as flat fills either.                    */
.grades { margin: 20px 0 0; padding: 22px 24px 24px; }
.grades h3 { margin-bottom: 12px; }
.grades p { margin-bottom: 18px; }

.rungs {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 11px;
}

/* The frame. A gradient underneath the face is what lets the top two rungs
   wear metal rather than a flat line. */
.rungs span {
  display: block; padding: 2px; border-radius: 7px;
  background: #3A3356;
  box-shadow: 0 3px 0 var(--panel-edge);
}
.rungs i {
  display: block; height: 44px; position: relative; overflow: hidden;
  border-radius: 5px 5px 0 0;
}
.rungs b {
  display: block; font-weight: 400;
  font-family: var(--pixel); font-size: 9px; letter-spacing: 0.07em;
  text-align: center; padding: 5px 2px 4px;
  border-radius: 0 0 5px 5px;
  color: var(--velvet-shadow); background: #9C97AE;
}

/* Not played: the song's own image, and a frame that says so quietly. */
.t0 span { background: #2F2A4A; }
.t0 i {
  background:
    radial-gradient(70% 55% at 25% 30%, rgba(90, 74, 140, 0.55), transparent 62%),
    radial-gradient(60% 60% at 78% 68%, rgba(70, 58, 110, 0.5), transparent 60%),
    linear-gradient(150deg, #322A55, #221B40);
}
.t0 b { background: #4A4560; color: rgba(243,239,250,0.55); }

/* Sparking: the same image, brighter, on a flat light frame. */
.t1 span { background: #9C97AE; }
.t1 i {
  background:
    radial-gradient(70% 55% at 30% 26%, rgba(126, 102, 196, 0.6), transparent 62%),
    radial-gradient(65% 60% at 76% 72%, rgba(86, 68, 150, 0.55), transparent 60%),
    linear-gradient(150deg, #453873, #281F49);
}

/* Glowing: saturated violet, an inner highlight rim, a halo. */
.t2 span { background: #F6F3FA; box-shadow: 0 3px 0 var(--panel-edge), 0 0 16px rgba(139,107,255,0.45); }
.t2 i {
  background:
    radial-gradient(70% 55% at 28% 28%, rgba(198, 187, 255, 0.75), transparent 60%),
    radial-gradient(65% 60% at 78% 70%, rgba(122, 92, 235, 0.8), transparent 62%),
    linear-gradient(150deg, #7C5CEB, #3E2F8C);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.35);
}
.t2 b { background: #F6F3FA; }

/* Gilded: gold, a metal frame and plate, and a shine crossing both. */
.t3 span {
  background: linear-gradient(115deg, #8A5A10, #FFB63D 30%, #FFF0C4 48%, #FFB63D 66%, #8A5A10);
  box-shadow: 0 3px 0 var(--panel-edge), 0 0 18px rgba(255,182,61,0.42);
}
.t3 i {
  background:
    radial-gradient(70% 55% at 26% 26%, rgba(255, 240, 196, 0.85), transparent 60%),
    radial-gradient(65% 60% at 80% 72%, rgba(200, 130, 20, 0.8), transparent 62%),
    linear-gradient(150deg, #FFC85C, #9A6512);
}
.t3 b {
  background: linear-gradient(90deg, #8A5A10, #FFB63D 32%, #FFF0C4 50%, #FFB63D 68%, #8A5A10);
}

/* Celestial: a starfield behind an aura, under a sheen, in blue-violet metal. */
.t4 span {
  background: linear-gradient(115deg, #2B2260, #6E5BD8 30%, #DDD6FF 48%, #6E5BD8 66%, #2B2260);
  box-shadow: 0 3px 0 var(--panel-edge), 0 0 20px rgba(139,107,255,0.6);
}
.t4 i {
  background:
    radial-gradient(1.2px 1.2px at 18% 34%, #fff, transparent),
    radial-gradient(1.2px 1.2px at 58% 20%, #C6BBFF, transparent),
    radial-gradient(1.2px 1.2px at 40% 68%, #fff, transparent),
    radial-gradient(1.2px 1.2px at 82% 56%, #fff, transparent),
    radial-gradient(1.2px 1.2px at 68% 82%, #C6BBFF, transparent),
    radial-gradient(75% 60% at 50% 45%, rgba(110, 91, 216, 0.5), transparent 65%),
    linear-gradient(150deg, #2B2260, #140E31);
}
.t4 b {
  background: linear-gradient(90deg, #2B2260, #6E5BD8 32%, #DDD6FF 50%, #6E5BD8 68%, #2B2260);
  color: #1B1440;
}

/* The shine the top two rungs wear, travelling the whole card. */
.t3 span, .t4 span { position: relative; overflow: hidden; }
.t3 span::after, .t4 span::after {
  content: ''; position: absolute; inset: -60%; pointer-events: none;
  background: linear-gradient(75deg, transparent 42%, rgba(255,255,255,0.5) 50%, transparent 58%);
  animation: sweep 4.5s ease-in-out infinite;
}
.t4 span::after { animation-duration: 7s; }

@keyframes sweep { 0%, 100% { transform: translateX(-65%); } 50% { transform: translateX(65%); } }

@media (max-width: 560px) { .rungs { grid-template-columns: repeat(3, 1fr); gap: 9px; } }

/* -------------------------------------------------------------- slideshow */
.slideshow { position: relative; margin: 40px 0 0; }
.viewport {
  overflow: hidden;
  border: 3px solid var(--card-edge); border-radius: 12px;
  box-shadow: 0 6px 0 var(--panel-edge);
  background: var(--velvet-shadow);
}
.track {
  display: flex; margin: 0; padding: 0; list-style: none;
  transition: transform 0.42s cubic-bezier(0.4, 0.9, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) { .track { transition: none; } }
.slide { flex: 0 0 100%; min-width: 0; }
.slide img { width: 100%; }
.slide .cap {
  margin: 0; padding: 15px 18px 16px;
  font-size: 15px; color: var(--dim);
  background: var(--panel); border-top: 3px solid var(--card-edge);
}

.slideshow .nav {
  position: absolute; top: calc(50% - 34px); transform: translateY(-50%);
  display: grid; place-items: center;
  width: 46px; height: 46px;
  color: var(--text); background: rgba(23, 17, 40, 0.82);
  border: 3px solid var(--card-edge); border-radius: 9px;
  box-shadow: 0 4px 0 var(--panel-edge);
  cursor: pointer; transition: transform 0.07s, box-shadow 0.07s, background 0.15s;
}
.slideshow .nav:hover { background: var(--panel-inset); transform: translateY(calc(-50% + 2px)); box-shadow: 0 2px 0 var(--panel-edge); }
.slideshow .nav:focus-visible { outline: 3px solid var(--next-glow); outline-offset: 3px; }
.slideshow .prev { left: 14px; }
.slideshow .next { right: 14px; }
@media (max-width: 620px) { .slideshow .nav { width: 38px; height: 38px; } .slideshow .prev { left: 6px; } .slideshow .next { right: 6px; } }

.dots { display: flex; justify-content: center; gap: 9px; margin-top: 20px; }
.dots button {
  position: relative;
  width: 11px; height: 11px; padding: 0;
  background: var(--panel-inset); border: 2px solid var(--card-edge); border-radius: 3px;
  cursor: pointer; transition: background 0.18s, transform 0.18s;
}
/* An invisible hit area around the 11px dot, 27px tall and reaching halfway
   into the 9px gap on each side, so a tap between two dots goes to the nearer
   one. Nothing is drawn; the dot looks exactly as it did. */
.dots button::after { content: ''; position: absolute; inset: -8px -4px; }
.dots button:hover { background: var(--panel-lip); }
.dots button[aria-selected='true'] { background: var(--gold); transform: scale(1.18); }
.dots button:focus-visible { outline: 3px solid var(--next-glow); outline-offset: 3px; }

/* ----------------------------------------------------------- requirements */
.reqgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin: 40px 0 0; }
@media (max-width: 900px) { .reqgrid { grid-template-columns: 1fr; } }
/* A drawn tick, not a character: the dingbats and the emoji are not in
   Silkscreen and arrive from a stranger's font with a stranger's baseline. Same
   answer the game reaches in Glyph.tsx - stepped on a whole-number grid, so it
   sits beside pixel type instead of next to it. */
.ticks { list-style: none; margin: 0; padding: 0; }
.ticks li { display: flex; align-items: center; gap: 11px; padding: 7px 0; font-size: 16px; }
.ticks svg { flex: none; fill: var(--green); }
.req .ticks + p { margin-top: 16px; }


/* -------------------------------------------------------------- subscribe */
.signup { display: grid; grid-template-columns: 1fr auto; gap: 11px; max-width: 520px; margin: 32px auto 0; }
.signup.big { max-width: 560px; margin-top: 36px; }
.signup .pot { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.signup input[type=email] {
  font-family: var(--sans); font-size: 16px; color: var(--text);
  background: var(--velvet-shadow);
  border: 3px solid var(--panel-edge); border-radius: 9px;
  padding: 15px 16px 14px; min-width: 0;
  box-shadow:
    inset 0 4px 0 rgba(0, 0, 0, 0.55),
    inset 0 -2px 0 rgba(255, 255, 255, 0.045);
  transition: border-color 0.15s;
}
.signup input[type=email]::placeholder { color: var(--dimmer); }
.signup input[type=email]:hover { border-color: var(--panel-lip); }
.signup input[type=email]:focus, .signup input[type=email]:focus-visible {
  outline: none; border-color: var(--green);
}
.formnote { grid-column: 1 / -1; margin: 8px 0 0; font-size: 14px; color: var(--dimmer); }
.formnote.ok { color: var(--green); }
.formnote.bad { color: #FF9AD0; }
@media (max-width: 520px) { .signup { grid-template-columns: 1fr; } }

.subscribeband { text-align: center; padding-bottom: 8px; }
.subscribeband .say { margin-left: auto; margin-right: auto; }

/* ----------------------------------------------------------------- footer */
footer {
  margin-top: clamp(48px, 6vw, 76px); padding: 44px clamp(16px, 4vw, 32px) 52px;
  text-align: center; border-top: 2px solid var(--panel-inset);
}
footer .lockup { margin-bottom: 4px; }
footer p { margin: 0 auto; }
footer .dim { font-family: var(--sans); color: var(--dimmer); font-size: 14px; letter-spacing: 0; margin-top: 12px; }
footer .contact { font-family: var(--sans); font-size: 14px; letter-spacing: 0; color: var(--dimmer); margin-top: 22px; }
footer .contact a { color: var(--chips-ice); border-bottom: 1px solid rgba(157, 237, 226, 0.35); }
footer .contact a:hover { color: #fff; border-bottom-color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .nebula, .stars, .notes i, .status b,
  .t3 span::after, .t4 span::after { animation: none !important; }
}
