/* Codestorm open-registration ban list — styles
   ------------------------------------------------------------------
   Paths here resolve relative to THIS file, not to index.html, so if
   you move this into a css/ subfolder, update the font and artwork
   URLs to ../fonts/ and ../raven.png.
   ------------------------------------------------------------------ */

/* Self-hosted, no third-party requests. Both families are SIL OFL 1.1;
   licences ship in fonts/. Subset to Latin + the symbols this page uses. */
@font-face{
  font-family:"Big Shoulders Display";
  src:url("fonts/big-shoulders-display-var.woff2") format("woff2");
  font-weight:700 900;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"IBM Plex Sans";
  src:url("fonts/ibm-plex-sans-var.woff2") format("woff2");
  font-weight:400 600;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"IBM Plex Mono";
  src:url("fonts/ibm-plex-mono-400.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"IBM Plex Mono";
  src:url("fonts/ibm-plex-mono-600.woff2") format("woff2");
  font-weight:600;font-style:normal;font-display:swap;
}

:root{
  /* palette sampled from the artwork */
  --ink:#08080a;
  --paper:#f1efeb;
  --red:#d81b1d;
  --red-dim:#8e1416;
  --mute:#a09a91;
  /* paper tone of the artwork's edges, used for the endless side field */
  --field-tone:#f7f7f6;
  --line:rgba(241,239,235,.16);
  /* scroll progress, 0 -> 1 over the first 10px */
  --p:0;
  /* the only place the artwork is referenced — swap this file and you're done */
  --bg-src:url('raven.png');
  --focus:0.9s cubic-bezier(.2,.7,.2,1);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  background:var(--ink);
  color:var(--paper);
  font-family:"IBM Plex Sans","Liberation Sans",system-ui,-apple-system,sans-serif;
  font-size:17px;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
}

/* ---------- background stack ---------- */
.bg,.bg-soft,.bg-tone,.scrim,.grain{position:fixed;inset:0;pointer-events:none}

/* 1. the endless horizontal field. The artwork's edges are uniform light
      grain, so this is just its paper tone with a whisper of vignette —
      no generated image needed. Resample --field-tone if you swap artwork. */
.bg-tone{
  z-index:-5;
  background:
    linear-gradient(180deg,rgba(0,0,0,.11) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0) 76%,rgba(0,0,0,.15) 100%),
    var(--field-tone);
}

/* 2. a defocused copy of the same file on identical geometry. The blur
      feathers its own edges into transparency, bridging the sharp copy and
      the field. Derived at runtime — nothing to regenerate. */
.bg-soft{
  z-index:-4;
  background-image:var(--bg-src);
  background-size:auto 106%;
  background-position:50% 50%;
  background-repeat:no-repeat;
  filter:blur(26px) brightness(calc(1 - var(--p) * .1));
  transform:translateZ(0);
  transition:filter var(--focus);
}

/* 3. the artwork itself, height-fitted and never upscaled past 1:1. The mask
      stops are in vh, so the fade tracks the artwork's real edges rather than
      the viewport — at 16:9 it dissolves over roughly 13vh a side. */
.bg{
  z-index:-3;
  background-image:var(--bg-src);
  background-size:auto 106%;
  background-position:50% 50%;
  background-repeat:no-repeat;
  --edge-fade:linear-gradient(90deg,
    transparent calc(50% - 53vh),
    rgba(0,0,0,.12) calc(50% - 51vh),
    rgba(0,0,0,.5)  calc(50% - 46vh),
    #000 calc(50% - 40vh),
    #000 calc(50% + 40vh),
    rgba(0,0,0,.5)  calc(50% + 46vh),
    rgba(0,0,0,.12) calc(50% + 51vh),
    transparent calc(50% + 53vh));
  -webkit-mask-image:var(--edge-fade);
  mask-image:var(--edge-fade);
  filter:blur(calc(var(--p) * 15px)) saturate(calc(1 - var(--p) * .3)) brightness(calc(1 - var(--p) * .1));
  transition:filter var(--focus);
}
.scrim{
  z-index:-2;
  background:
    linear-gradient(180deg,rgba(8,8,10,.62) 0%,rgba(8,8,10,0) 20%,rgba(8,8,10,0) 52%,rgba(8,8,10,.74) 100%),
    rgba(8,8,10,calc(.2 + var(--p) * .72));
  transition:background var(--focus);
}
/* screenprint tooth, echoes the artwork's texture */
.grain{
  z-index:-1;opacity:.05;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- chrome ---------- */
.topbar{
  position:fixed;top:0;left:0;right:0;z-index:20;
  display:flex;align-items:center;gap:1.25rem;
  padding:.85rem clamp(1.1rem,4vw,3rem);
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;
  font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  transition:none;
}
/* backing for the bar fades out downward instead of ending on a hard rule,
   so scrolling content passes under it without a visible cut */
.topbar::before{
  content:"";position:absolute;left:0;right:0;top:0;height:265%;z-index:-1;
  background:linear-gradient(180deg,
    rgba(8,8,10,.9) 0%,rgba(8,8,10,.64) 40%,
    rgba(8,8,10,.24) 72%,rgba(8,8,10,0) 100%);
  opacity:var(--p);transition:opacity var(--focus);pointer-events:none;
}
.mark{display:flex;align-items:center;gap:.55rem;min-width:0;overflow:hidden;white-space:nowrap}
.mark .home{
  color:var(--paper);text-decoration:none;font-weight:600;
  border-bottom:1px solid rgba(216,27,29,.55);padding-bottom:1px;
}
.mark .home:hover,.mark .home:focus-visible{color:var(--red);border-bottom-color:var(--red)}
.mark .sep{color:rgba(241,239,235,.3)}
.mark .here{color:var(--mute);font-weight:400;white-space:nowrap}
/* drop the decorative page label before sacrificing the nav links */
@media (max-width:820px){.mark .sep,.mark .here{display:none}}
.lens{
  width:9px;height:9px;border-radius:50%;background:var(--red);
  box-shadow:0 0 0 3px rgba(216,27,29,.22);
  animation:rec 2.4s ease-in-out infinite;
}
@keyframes rec{50%{opacity:.25;box-shadow:0 0 0 6px rgba(216,27,29,0)}}
.topbar nav{margin-left:auto;display:flex;flex:0 0 auto;gap:clamp(.9rem,1.8vw,1.4rem)}
/* nowrap on every item: multi-word links breaking to two lines next to
   single-word ones looks broken, so the nav is hidden as a whole instead */
.topbar nav a{color:var(--mute);text-decoration:none;white-space:nowrap;transition:color .2s}
.topbar nav a:hover,.topbar nav a:focus-visible{color:var(--paper)}
@media (max-width:600px){.topbar nav{display:none}}

/* ---------- hero ---------- */
.hero{
  min-height:100vh;             /* fallback: svh is unsupported pre-Firefox 101 */
  min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-end;
  /* the top padding is invisible in the normal case, but it guarantees the
     content can never slide under the fixed topbar if it outgrows the hero */
  padding:5.5rem clamp(1.1rem,4vw,3rem) clamp(2.5rem,7vh,5rem);
  position:relative;
}
/* local pool of dark so the hero reads over the white parts of the artwork,
   then hands off to the global scrim as you scroll */
.hero::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(135% 100% at 32% 100%,rgba(8,8,10,.96) 0%,rgba(8,8,10,.79) 38%,rgba(8,8,10,.4) 64%,rgba(8,8,10,0) 88%);
  opacity:calc(1 - var(--p) * .6);transition:opacity var(--focus);pointer-events:none;
}
.hero > *{position:relative}
.eyebrow{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.74rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--red);margin:0 0 1.1rem;
  display:flex;align-items:center;gap:.7rem;
}
.eyebrow::after{content:"";height:1px;flex:1;max-width:170px;background:linear-gradient(90deg,var(--red),transparent)}
h1{
  font-family:"Big Shoulders Display","Archivo Narrow","Liberation Sans Narrow","DejaVu Sans Condensed","Arial Narrow","Helvetica Neue Condensed",sans-serif;
  font-weight:900;font-size:clamp(2.72rem,10vw,7.6rem);line-height:.86;
  letter-spacing:-.005em;text-transform:uppercase;margin:0;overflow-wrap:break-word;
  text-shadow:0 2px 40px rgba(8,8,10,.55);
}
h1 .no{color:var(--red);display:block}
.lede{
  max-width:46ch;margin:1.6rem 0 0;font-size:clamp(1rem,1.25vw,1.15rem);
  color:#ded9d2;text-shadow:0 1px 18px rgba(8,8,10,.7);
}
.hero-alias{
  margin-top:1.9rem;display:flex;flex-wrap:wrap;gap:.7rem;align-items:center;
}
.scrollcue{
  margin-top:clamp(2rem,5vh,3.4rem);
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.7rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--mute);
  opacity:calc(1 - var(--p));transition:opacity .3s;
}
.scrollcue span{display:inline-block;animation:nudge 2.6s ease-in-out infinite}
@keyframes nudge{50%{transform:translateY(5px)}}

/* ---------- layout ---------- */
main{position:relative;z-index:1}
section{padding:clamp(4rem,11vh,8rem) clamp(1.1rem,4vw,3rem)}
.wrap{max-width:1080px;margin:0 auto}
.narrow{max-width:66ch}
.kicker{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.72rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--red);margin:0 0 .9rem;
}
h2{
  font-family:"Big Shoulders Display","Archivo Narrow","Liberation Sans Narrow","DejaVu Sans Condensed","Arial Narrow","Helvetica Neue Condensed",sans-serif;
  font-weight:700;font-size:clamp(2.1rem,5vw,3.5rem);line-height:.95;
  text-transform:uppercase;margin:0 0 1.4rem;letter-spacing:.005em;overflow-wrap:break-word;
}
h3{
  font-family:"IBM Plex Sans",sans-serif;font-weight:600;font-size:1.02rem;
  margin:0 0 .5rem;letter-spacing:.01em;
}
p{margin:0 0 1.1rem}
p:last-child{margin-bottom:0}
.dim{color:#c3bdb4}
strong{font-weight:600;color:#fff}
hr.rule{border:0;height:1px;background:var(--line);margin:0}

/* ---------- the rule ---------- */
.rule-statement{
  font-family:"Big Shoulders Display","Archivo Narrow","Liberation Sans Narrow","DejaVu Sans Condensed","Arial Narrow","Helvetica Neue Condensed",sans-serif;
  font-weight:700;text-transform:uppercase;font-size:clamp(1.5rem,3.6vw,2.6rem);
  line-height:1.06;max-width:22ch;margin:0 0 2rem;
}
.rule-statement em{font-style:normal;color:var(--red)}

/* ---------- verdict table ---------- */
/* The three columns are defined once on the container and inherited by every
   row via subgrid. Previously each row was its own grid, so "Not banned" and
   "Held" produced different column widths and the middle text never lined up. */
.verdicts{
  display:grid;
  grid-template-columns:minmax(11rem,1.15fr) minmax(0,2.2fr) max-content;
  column-gap:1.6rem;border-top:1px solid var(--line);
}
.verdict{
  display:grid;grid-column:1 / -1;grid-template-columns:subgrid;
  column-gap:1.6rem;row-gap:.4rem;align-items:baseline;
  padding:1.15rem 0;border-bottom:1px solid var(--line);
}
/* older engines without subgrid: fixed third column gets the same result */
@supports not (grid-template-columns:subgrid){
  .verdicts{display:block}
  .verdict{grid-template-columns:minmax(11rem,1.15fr) minmax(0,2.2fr) 7.5rem}
}
.verdict code{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.86rem;color:var(--paper);
  letter-spacing:.01em;
}
.verdict .what{color:#c3bdb4;font-size:.95rem}
.tag{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.68rem;letter-spacing:.14em;
  text-transform:uppercase;padding:.32rem .6rem;border:1px solid;white-space:nowrap;
}
.tag.ban{color:#ff5f5f;border-color:rgba(216,27,29,.65);background:rgba(216,27,29,.14)}
.tag.clear{color:#bdb7ae;border-color:var(--line)}
.tag.hold{color:#d9cfa8;border-color:rgba(217,207,168,.35)}
.verdict.is-ban code{color:#ff8a8a}
@media (max-width:680px){
  .verdicts{display:block}
  .verdict{grid-template-columns:1fr auto;gap:.4rem 1rem}
  .verdict .what{grid-column:1 / -1}
}

/* ---------- network ---------- */
.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.cell{background:rgba(8,8,10,.5);padding:1.6rem 1.4rem}
.cell .idx{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.7rem;letter-spacing:.16em;
  color:var(--red);display:block;margin-bottom:.9rem;
}
.cell p{font-size:.95rem;color:#c3bdb4}

.flow{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:clamp(.8rem,3vw,2rem);
  margin-top:2.5rem;
}
.nodes{display:grid;gap:.55rem}
.node{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.78rem;
  border:1px solid var(--line);padding:.6rem .8rem;color:#c3bdb4;
  background:rgba(8,8,10,.45);
}
.node .dot{color:var(--red);margin-right:.5rem}
.arrow{color:var(--red);font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:1.1rem;text-align:center}
.sink{
  border:1px solid rgba(216,27,29,.5);background:rgba(216,27,29,.09);
  padding:1.1rem;font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.8rem;
}
.sink b{display:block;font-weight:600;color:#fff;margin-bottom:.35rem}
@media (max-width:640px){
  .flow{grid-template-columns:1fr;text-align:left}
  .arrow{text-align:left;transform:rotate(90deg);width:1.5rem}
}

/* ---------- steps ---------- */
ol.steps{list-style:none;counter-reset:s;margin:0;padding:0}
ol.steps li{
  counter-increment:s;position:relative;padding:0 0 1.7rem 3.2rem;
  border-left:1px solid var(--line);margin-left:.6rem;
}
ol.steps li:last-child{border-left-color:transparent;padding-bottom:0}
ol.steps li::before{
  content:counter(s,decimal-leading-zero);
  position:absolute;left:-.85rem;top:-.15rem;
  width:1.7rem;height:1.7rem;display:grid;place-items:center;
  background:var(--ink);border:1px solid rgba(216,27,29,.55);color:var(--red);
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.68rem;
}

/* ---------- copy chips ---------- */
.chip{
  display:inline-flex;align-items:center;gap:.6rem;
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.8rem;
  background:rgba(8,8,10,.6);border:1px solid var(--line);color:var(--paper);
  padding:.55rem .7rem;cursor:pointer;text-align:left;
  max-width:100%;overflow-wrap:anywhere;
  transition:border-color .2s,background .2s;
}
.chip:hover,.chip:focus-visible{border-color:rgba(216,27,29,.7);background:rgba(216,27,29,.1)}
.chip .act{flex:0 0 auto;color:var(--mute);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase}
.chip.copied .act{color:var(--red)}
.chip-row{display:flex;flex-direction:column;gap:.6rem;align-items:flex-start;margin-top:1.3rem}

/* bot name in a max-content column, so every command box starts at the same
   indent regardless of which bot's name sits in front of it */
.cmd-list{
  display:grid;grid-template-columns:max-content minmax(0,1fr);
  gap:.6rem 1.1rem;align-items:center;margin-top:1.4rem;
}
.cmd-list .bot{
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.72rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--mute);
  white-space:nowrap;
}
.cmd-list .chip{justify-self:start}
@media (max-width:640px){
  .cmd-list{grid-template-columns:minmax(0,1fr);gap:.3rem}
  .cmd-list .bot{margin-top:.8rem}
  .cmd-list .bot:first-child{margin-top:0}
}

a.link{color:var(--paper);text-decoration:none;border-bottom:1px solid rgba(216,27,29,.6);padding-bottom:1px}
a.link:hover,a.link:focus-visible{color:var(--red)}

.callout{
  border-left:2px solid var(--red);padding:.2rem 0 .2rem 1.2rem;
  color:#c3bdb4;font-size:.95rem;margin:1.6rem 0 0;
}

footer{
  padding:3rem clamp(1.1rem,4vw,3rem) 3.5rem;
  border-top:1px solid var(--line);background:rgba(8,8,10,.72);
  font-family:"IBM Plex Mono","DejaVu Sans Mono","Liberation Mono",ui-monospace,monospace;font-size:.74rem;
  color:var(--mute);letter-spacing:.04em;
}
footer .fwrap{max-width:1080px;margin:0 auto;display:flex;flex-wrap:wrap;gap:1rem 2.5rem}
footer a{color:#c3bdb4}

:focus-visible{outline:2px solid var(--red);outline-offset:3px}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .bg,.bg-soft,.scrim,.topbar{transition:none}
  .lens,.scrollcue span{animation:none}
}