/* Ghost Broadcast — design system
   Extracted from 404.html's inline <style>, generalized into reusable
   components. 404.html stays a frozen, self-contained artifact and does
   NOT import this file — this is a parallel copy of the same tokens for
   any other page (currently index.html and design-system.html) to build
   on. If you retune a color or animation here, the change does not
   propagate to 404.html and vice versa; update both by hand if they
   need to stay in sync. */

:root{
  --ink:#0A0809; --ink2:#15100F;
  --blood:#B22418; --oxblood:#4D0F09;
  --bone:#F2ECDE; --bone-dim:#B7AE9E;
  --hair:rgba(242,236,222,.16);
  --display:'Dela Gothic One',sans-serif;
  --serif:'Shippori Mincho',serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--ink); color:var(--bone); font-family:var(--serif);
  -webkit-font-smoothing:antialiased;
}

.visually-hidden{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0) }
a:focus-visible,.btn:focus-visible,button:focus-visible{ outline:2px solid var(--bone); outline-offset:3px }

/* brand mark — station bug: seed dot + jp glyph + wordmark */
.brand{ display:inline-flex; align-items:center; gap:11px;
  font-family:var(--serif); font-weight:700; font-size:12px; letter-spacing:.26em;
  text-transform:uppercase; color:var(--bone) }
.brand .jp{ font-family:var(--display); font-size:15px; letter-spacing:.08em; color:var(--bone) }
.brand .seed{ width:7px; height:7px; border-radius:50%; background:var(--blood);
  box-shadow:0 0 10px rgba(229,32,46,.8); animation:beat 1.6s ease-in-out infinite; flex:none }
@keyframes beat{ 0%,100%{opacity:.45;transform:scale(.85)} 50%{opacity:1;transform:scale(1)} }

.channel{ font-family:var(--serif); font-weight:700; font-size:12px; letter-spacing:.26em;
  text-transform:uppercase; color:var(--bone-dim) }
.channel b{ color:var(--blood); font-weight:700 }

/* eyebrow label, e.g. above a heading */
.eyebrow{ display:inline-flex; align-items:center; gap:11px; font-family:var(--serif);
  font-weight:500; font-size:12px; letter-spacing:.22em; text-transform:uppercase;
  color:var(--bone-dim) }
.eyebrow b{ color:var(--blood); font-weight:700 }

/* hanko seal — small rotated stamp, usually one or two glyphs */
.seal{ display:inline-grid; place-items:center; width:74px; height:74px;
  background:var(--blood); color:var(--bone); font-family:var(--display); font-size:38px;
  border-radius:8px; transform:rotate(-6deg);
  box-shadow:inset 0 0 0 3px rgba(242,236,222,.85), inset 0 0 14px rgba(110,15,22,.7), 0 10px 26px rgba(0,0,0,.5);
  position:relative }
.seal::after{ content:""; position:absolute; inset:0; border-radius:8px;
  background:radial-gradient(circle at 36% 28%, rgba(242,236,222,.22), transparent 55%); mix-blend-mode:screen }

h1{ font-family:var(--display); font-size:clamp(32px,3.7vw,54px); line-height:1.02;
  color:var(--bone); letter-spacing:.005em }
h1 em{ font-style:normal; color:var(--blood) }
.lead{ font-family:var(--serif); font-weight:500; color:var(--bone-dim);
  font-size:15px; line-height:1.85; max-width:40ch }
.lead b{ color:var(--bone); font-weight:700 }

/* technical readout line, e.g. "REQUESTED · /path" */
.req{ font-family:var(--serif); font-weight:500; font-size:12px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--bone-dim);
  border-left:2px solid var(--blood); padding:5px 0 5px 13px; word-break:break-all }
.req span{ color:var(--blood); text-transform:none; letter-spacing:.02em }

.actions{ display:flex; gap:14px; flex-wrap:wrap }
.btn{ font-family:var(--display); font-size:13px; letter-spacing:.04em; text-decoration:none;
  cursor:pointer; padding:15px 24px; border:1px solid var(--blood); color:var(--bone);
  background:var(--blood); border-radius:6px; display:inline-block;
  transition:transform .12s ease, box-shadow .2s ease, background .2s ease }
.btn:hover{ box-shadow:0 10px 30px rgba(229,32,46,.4); transform:translateY(-2px) }
.btn:active{ transform:translateY(0) }
.btn.ghost{ background:transparent; color:var(--bone); border-color:var(--hair) }
.btn.ghost:hover{ border-color:var(--bone); box-shadow:none; background:rgba(242,236,222,.05) }

/* horizontal ticker — a .track of content scrolls right-to-left forever */
.marquee{ overflow:hidden; border-top:1px solid var(--hair); padding-top:12px;
  font-family:var(--serif); font-weight:500; font-size:12px; letter-spacing:.24em;
  color:var(--bone-dim); white-space:nowrap; -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent) }
.marquee .track{ display:inline-block; padding-left:100%; animation:marq 26s linear infinite }
.marquee .jp{ font-family:var(--display); color:var(--bone); margin:0 6px;
  text-shadow:0 0 8px rgba(255,42,109,.55), 0 0 18px rgba(255,42,109,.3) }
.marquee .dot{ color:var(--blood); margin:0 22px }
@keyframes marq{ from{transform:translateX(0)} to{transform:translateX(-100%)} }

/* mistracked RGB guns — constant chromatic split with periodic tape tears.
   markup: <span class="glitch" data-text="404">404</span> — the data-text
   attribute drives the two ghost layers, so any string works, not just "404". */
.glitch{ font-family:var(--display); font-size:clamp(78px,14vw,208px); line-height:.86;
  color:var(--bone); letter-spacing:.01em; position:relative; display:inline-block;
  text-shadow:0 2px 4px rgba(10,8,9,.85), 0 6px 30px rgba(10,8,9,.6), 0 0 50px rgba(242,236,222,.18);
  animation:vhsBob 5.5s steps(1) infinite }
.glitch::before,.glitch::after{ content:attr(data-text); position:absolute; top:0; left:0; width:100%; overflow:hidden; mix-blend-mode:screen; text-shadow:none }
.glitch::before{ color:#ff2a6d; animation:vhsRed 2.3s steps(1) infinite }
.glitch::after{  color:#22f0ea; animation:vhsCyan 2.9s steps(1) infinite }
@keyframes vhsRed{
  0%,100%{ transform:translate(-2.5px,0); clip-path:inset(0 0 0 0) }
  14%{ transform:translate(-5px,1px);  clip-path:inset(16% 0 58% 0) }
  15%{ transform:translate(-2.5px,0);  clip-path:inset(0 0 0 0) }
  44%{ transform:translate(-6px,-1px); clip-path:inset(48% 0 28% 0) }
  45%{ transform:translate(-2.5px,0);  clip-path:inset(0 0 0 0) }
  72%{ transform:translate(-4px,2px);  clip-path:inset(6% 0 80% 0) }
  73%{ transform:translate(-2.5px,0);  clip-path:inset(0 0 0 0) } }
@keyframes vhsCyan{
  0%,100%{ transform:translate(2.5px,0); clip-path:inset(0 0 0 0) }
  22%{ transform:translate(5px,-1px);  clip-path:inset(30% 0 44% 0) }
  23%{ transform:translate(2.5px,0);   clip-path:inset(0 0 0 0) }
  58%{ transform:translate(6px,1px);   clip-path:inset(64% 0 14% 0) }
  59%{ transform:translate(2.5px,0);   clip-path:inset(0 0 0 0) }
  88%{ transform:translate(4px,-2px);  clip-path:inset(10% 0 74% 0) }
  89%{ transform:translate(2.5px,0);   clip-path:inset(0 0 0 0) } }
@keyframes vhsBob{
  0%,38%,100%{ transform:translate(0,0) skewX(0) }
  39%{ transform:translate(-3px,1px) skewX(-7deg) }
  40%{ transform:translate(2px,-1px) skewX(3deg) }
  41%{ transform:translate(0,0) skewX(0) }
  74%{ transform:translate(2px,0) skewX(0) }
  75%{ transform:translate(0,0) skewX(0) } }

/* viewport corner frame. default is component-local (absolute, inside a
   position:relative wrapper); add .bracket.viewport to pin all four to the
   browser window instead, the way 404.html's fixed frame does. */
.bracket{ position:absolute; width:30px; height:30px; pointer-events:none;
  border-color:var(--bone); opacity:.45 }
.bracket.viewport{ position:fixed; z-index:40 }
.bracket.tl{ top:16px; left:16px; border-top:1px solid; border-left:1px solid }
.bracket.tr{ top:16px; right:16px; border-top:1px solid; border-right:1px solid }
.bracket.bl{ bottom:16px; left:16px; border-bottom:1px solid; border-left:1px solid }
.bracket.br{ bottom:16px; right:16px; border-bottom:1px solid; border-right:1px solid }

/* vertical tategaki rail, e.g. a running label along a page edge */
.rail{ writing-mode:vertical-rl;
  font-family:var(--display); font-size:13px; letter-spacing:.28em;
  color:var(--bone); opacity:.85; pointer-events:none; display:flex; align-items:center; gap:18px;
  text-shadow:0 0 8px rgba(24,227,227,.55), 0 0 18px rgba(24,227,227,.3) }
.rail .en{ font-family:var(--serif); font-weight:500; font-size:10px; letter-spacing:.42em;
  text-transform:uppercase; color:var(--bone-dim) }

/* transient confirmation bubble */
.toast{ position:fixed; left:50%; bottom:12%; transform:translate(-50%,12px); z-index:70;
  font-family:var(--display); font-size:13px; letter-spacing:.02em; color:var(--bone);
  background:var(--blood); padding:12px 20px; border-radius:6px; opacity:0; pointer-events:none;
  box-shadow:0 10px 30px rgba(0,0,0,.5); transition:opacity .25s ease, transform .25s ease }
.toast.show{ opacity:1; transform:translate(-50%,0) }

@media (prefers-reduced-motion:reduce){
  .brand .seed,.glitch,.glitch::before,.glitch::after,.marquee .track{ animation:none !important }
  .glitch::before,.glitch::after{ display:none }
}
