/* ==========================================================================
   ternux — shared stylesheet
   Terminal / phosphor-green theme used by the landing page and every
   Jekyll-rendered documentation page.

   Sections:
     1. Tokens
     2. Base + effects layers
     3. Navigation
     4. Landing page
     5. Documentation pages
     6. Syntax highlighting (Rouge)
     7. Footer
     8. Responsive + reduced motion
   ========================================================================== */

/* -- 1. Tokens ------------------------------------------------------------ */
:root{
  --bg:#04140a; --bg2:#061a0d; --ink:#c8ffd8; --dim:#5f8f6e;
  --grn:#00ff41; --grn-d:#00b32d; --amber:#ffb000; --cyan:#00e5ff; --red:#ff4d4d;
  --line:rgba(0,255,65,.22); --panel:rgba(0,20,8,.78); --panel-s:rgba(0,26,11,.92);
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"DejaVu Sans Mono",monospace;
}

/* -- 2. Base + effects ---------------------------------------------------- */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;
  background:var(--bg);           /* painted edge-to-edge, incl. overscroll */
  background-color:#04140a}
body{
  background:var(--bg); color:var(--ink); font-family:var(--mono);
  font-size:16px; line-height:1.65; overflow-x:hidden;
  min-height:100%;
  -webkit-font-smoothing:antialiased;
}
#matrix{position:fixed;inset:0;z-index:0;display:block;opacity:.5;
  /* The canvas is decoration only. Without this it sits above the page
     background and can swallow taps aimed at links near the edges. */
  pointer-events:none}
body.home #matrix{opacity:.16}   /* landing: rain must not fight the copy */
body.doc #matrix{opacity:.18}          /* quieter behind long-form text */
.vignette{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(ellipse at 50% 40%,transparent 35%,rgba(0,0,0,.72) 100%)}
.scan{position:fixed;inset:0;z-index:2;pointer-events:none;opacity:.35;
  background:repeating-linear-gradient(180deg,rgba(0,0,0,0) 0 2px,rgba(0,0,0,.35) 2px 4px)}
.wrap{position:relative;z-index:3;max-width:1080px;margin:0 auto;padding:0 20px}

::selection{background:rgba(0,255,65,.28);color:#eaffef}
a{color:var(--grn)}
:focus-visible{outline:2px solid var(--grn);outline-offset:2px}

.skip{position:absolute;left:-9999px;z-index:60;padding:10px 16px;
  background:var(--grn);color:#02160a;font-weight:700;text-decoration:none}
.skip:focus{left:12px;top:12px}

/* -- 3. Navigation -------------------------------------------------------- */
nav{position:sticky;top:0;z-index:20;backdrop-filter:blur(9px);
  background:rgba(4,20,10,.86);border-bottom:1px solid var(--line)}
.nav-in{max-width:1080px;margin:0 auto;padding:11px 20px;
  display:flex;align-items:center;gap:18px}
.brand{color:var(--grn);font-weight:700;text-decoration:none;letter-spacing:.5px;
  text-shadow:0 0 12px rgba(0,255,65,.55);white-space:nowrap}
.brand .c{animation:blink 1.05s step-end infinite}
.nav-links{margin-left:auto;display:flex;gap:16px;overflow-x:auto;scrollbar-width:none}
.nav-links::-webkit-scrollbar{display:none}
.nav-links a{color:var(--dim);text-decoration:none;font-size:13px;white-space:nowrap;
  padding:3px 0;border-bottom:1px solid transparent;transition:.18s}
.nav-links a:hover,.nav-links a:focus-visible{color:var(--grn);border-bottom-color:var(--grn)}
.nav-links a.active{color:var(--grn);border-bottom-color:var(--grn)}
@keyframes blink{0%,50%{opacity:1}51%,100%{opacity:0}}

/* -- 4. Landing page ------------------------------------------------------ */
header.hero{padding:64px 0 44px;text-align:center}
.logo{color:var(--grn);font-size:clamp(5px,1.72vw,13px);line-height:1.16;
  white-space:pre;display:inline-block;text-shadow:0 0 18px rgba(0,255,65,.5);
  filter:drop-shadow(0 0 3px rgba(0,255,65,.35))}
.hero h1{font-size:clamp(26px,6.5vw,46px);margin:22px 0 10px;color:#eaffef;letter-spacing:1px}
.hero h1 .g{color:var(--grn);text-shadow:0 0 22px rgba(0,255,65,.6)}
.tag{color:var(--dim);font-size:clamp(13px,3.3vw,17px);max-width:640px;margin:0 auto}
.type{min-height:1.7em;margin:24px auto 0;color:var(--grn);
  font-size:clamp(12px,3.1vw,16px);text-align:left;max-width:520px}
.type::after{content:"█";animation:blink 1.05s step-end infinite;margin-left:2px}

.badges{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:26px 0 0}
.badge{border:1px solid var(--line);background:rgba(0,255,65,.05);color:var(--dim);
  font-size:11px;padding:4px 10px;border-radius:2px;letter-spacing:.4px}
.badge b{color:var(--grn);font-weight:600}

.cta{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin:30px 0 0}
.btn{display:inline-block;padding:12px 24px;text-decoration:none;font-weight:700;
  font-size:14px;border:1px solid var(--grn);color:var(--grn);border-radius:2px;
  background:rgba(0,255,65,.07);transition:.18s;letter-spacing:.5px}
.btn:hover,.btn:focus-visible{background:var(--grn);color:#02160a;
  box-shadow:0 0 26px rgba(0,255,65,.5)}
.btn.alt{border-color:var(--line);color:var(--dim);background:transparent}
.btn.alt:hover,.btn.alt:focus-visible{border-color:var(--grn);color:var(--grn);
  background:rgba(0,255,65,.07);box-shadow:none}

section{padding:52px 0;border-top:1px solid var(--line)}
section h2{font-size:clamp(18px,4.4vw,25px);color:var(--grn);margin-bottom:8px;letter-spacing:.5px}
section h2::before{content:"# ";color:var(--dim)}
.sub{color:var(--dim);font-size:14px;margin-bottom:26px}

.term{background:var(--panel);border:1px solid var(--line);border-radius:5px;
  overflow:hidden;box-shadow:0 0 46px rgba(0,255,65,.1)}
.term-bar{display:flex;align-items:center;gap:7px;padding:9px 13px;
  background:rgba(0,255,65,.07);border-bottom:1px solid var(--line)}
.dot{width:11px;height:11px;border-radius:50%;flex:0 0 auto}
.term-title{margin-left:8px;font-size:11.5px;color:var(--dim);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.term-body{padding:16px 15px;font-size:13px;line-height:1.85;overflow-x:auto}
.term-body pre{white-space:pre;font-family:var(--mono)}
.p{color:var(--grn);user-select:none}
.cm{color:#eaffef}
.ot{color:var(--dim)}
.ok{color:var(--grn)}
.wn{color:var(--amber)}
.er{color:var(--red)}
.cy{color:var(--cyan)}

.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(248px,1fr))}
.card{background:var(--panel);border:1px solid var(--line);border-radius:4px;
  padding:20px;transition:.2s}
.card:hover{border-color:var(--grn);transform:translateY(-2px);
  box-shadow:0 6px 30px rgba(0,255,65,.14)}
.card h3{color:var(--grn);font-size:15px;margin-bottom:7px;letter-spacing:.3px}
.card h3 span{color:var(--dim);margin-right:7px}
.card p{font-size:13.5px;color:var(--dim);line-height:1.62}

ol.steps{list-style:none;counter-reset:s;display:grid;gap:12px}
ol.steps li{counter-increment:s;background:var(--panel);border:1px solid var(--line);
  border-left:3px solid var(--grn);border-radius:3px;padding:15px 17px;
  display:flex;gap:14px;align-items:flex-start}
ol.steps li::before{content:counter(s,decimal-leading-zero);color:var(--grn);
  font-weight:700;font-size:15px;flex:0 0 auto;opacity:.8}
ol.steps strong{color:#eaffef;display:block;font-size:14.5px;margin-bottom:2px}
ol.steps span{color:var(--dim);font-size:13px}
ol.steps code{color:var(--cyan)}

.tw{overflow-x:auto;border:1px solid var(--line);border-radius:4px;background:var(--panel)}
.tw table{margin:0;border:none}

.docs{display:grid;gap:11px;grid-template-columns:repeat(auto-fit,minmax(232px,1fr))}
/* Scoped to .docs: a bare `.doc` also matches <body class="doc">, which made
   the page background 78% transparent and let the white canvas show through
   at the edges. Never use an unscoped class that collides with a body class. */
.docs .doc{display:block;text-decoration:none;background:var(--panel);
  border:1px solid var(--line);border-radius:4px;padding:16px 17px;transition:.18s}
.docs .doc:hover,.docs .doc:focus-visible{border-color:var(--grn);background:rgba(0,255,65,.07);
  transform:translateX(3px)}
.docs .doc b{color:var(--grn);font-size:14px;display:block;margin-bottom:3px}
.docs .doc span{color:var(--dim);font-size:12.5px}

.note{border-left:3px solid var(--amber);background:rgba(255,176,0,.07);
  padding:13px 16px;border-radius:0 3px 3px 0;font-size:13.5px;color:var(--dim);margin-top:18px}
.note b{color:var(--amber)}

/* -- 5. Documentation pages ----------------------------------------------- */
.doc-head{padding:34px 0 18px;border-bottom:1px solid var(--line)}
body.doc .wrap{max-width:900px}
.crumb{font-size:12.5px;color:var(--dim);margin-bottom:10px}
.crumb a{color:var(--dim);text-decoration:none}
.crumb a:hover{color:var(--grn)}
.crumb .sep{opacity:.5;margin:0 7px}
.crumb .cur{color:var(--grn)}

.doc-nav{display:flex;flex-wrap:wrap;gap:7px;padding:16px 0 0}
.doc-nav a{font-size:12px;color:var(--dim);text-decoration:none;padding:5px 11px;
  border:1px solid var(--line);border-radius:2px;background:rgba(0,255,65,.04);transition:.16s}
.doc-nav a:hover{color:var(--grn);border-color:var(--grn)}
.doc-nav a.active{color:#02160a;background:var(--grn);border-color:var(--grn);font-weight:700}

.prose table{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
.prose pre{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
.prose code{overflow-wrap:break-word;word-break:break-word}
.prose pre code{overflow-wrap:normal;word-break:normal}
.prose{
  padding:30px 26px 46px;
  max-width:100%;
  /* Long-form text must never sit directly on the animated canvas: the
     glyphs pass behind paragraphs and destroy contrast. A near-opaque
     backdrop keeps the effect visible at the margins while guaranteeing
     the text stays readable. */
  background:linear-gradient(180deg,rgba(4,20,10,.93),rgba(4,20,10,.96));
  border:1px solid var(--line);
  border-radius:5px;
  margin:26px 0 30px;
  box-shadow:0 0 50px rgba(0,0,0,.5);
}
.prose > *:first-child{margin-top:0}
.prose > *:last-child{margin-bottom:0}

.prose h1,.prose h2,.prose h3,.prose h4{
  color:var(--grn);line-height:1.3;letter-spacing:.3px;
  margin:34px 0 12px;scroll-margin-top:70px}
.prose h1{font-size:clamp(23px,5.4vw,33px);color:#eaffef;
  text-shadow:0 0 20px rgba(0,255,65,.28);margin-top:0}
.prose h1::before{content:"$ ";color:var(--grn);opacity:.75}
.prose h2{font-size:clamp(18px,4.2vw,24px);padding-bottom:7px;border-bottom:1px solid var(--line)}
.prose h2::before{content:"## ";color:var(--dim);opacity:.7}
.prose h3{font-size:clamp(15.5px,3.6vw,19px);color:#a9ffc4}
.prose h3::before{content:"### ";color:var(--dim);opacity:.55}
.prose h4{font-size:15px;color:#a9ffc4}

.prose p{margin:0 0 15px;color:var(--ink)}
.prose strong{color:#eaffef}
.prose em{color:var(--cyan);font-style:normal}
.prose a{color:var(--grn);text-decoration:none;border-bottom:1px solid rgba(0,255,65,.35)}
.prose a:hover{background:rgba(0,255,65,.1);border-bottom-color:var(--grn)}

.prose ul,.prose ol{margin:0 0 16px;padding-left:24px}
.prose li{margin:6px 0;color:var(--ink)}
.prose li::marker{color:var(--grn)}
.prose ul ul,.prose ol ol,.prose ul ol,.prose ol ul{margin:6px 0}

.prose hr{border:none;border-top:1px solid var(--line);margin:32px 0}

.prose blockquote{border-left:3px solid var(--amber);background:rgba(255,176,0,.07);
  padding:12px 16px;margin:0 0 16px;border-radius:0 3px 3px 0;color:var(--dim)}
.prose blockquote p{margin:0;color:var(--dim)}
.prose blockquote strong{color:var(--amber)}

/* inline code */
.prose code{font-family:var(--mono);font-size:.88em;color:var(--cyan);
  background:rgba(0,229,255,.09);border:1px solid rgba(0,229,255,.2);
  padding:1px 6px;border-radius:3px;white-space:nowrap}
/* code blocks */
.prose pre{background:var(--panel-s);border:1px solid var(--line);border-left:3px solid var(--grn);
  border-radius:4px;padding:15px 16px;overflow-x:auto;margin:0 0 18px;
  box-shadow:0 0 30px rgba(0,255,65,.07);font-size:13.5px;line-height:1.75}
.prose pre code{background:none;border:none;padding:0;color:var(--ink);
  white-space:pre;font-size:inherit}
.prose div.highlight,.prose figure.highlight{margin:0 0 18px}
.prose div.highlight pre,.prose figure.highlight pre{margin:0}

.prose table{width:100%;border-collapse:collapse;font-size:13.5px;margin:0 0 20px;
  display:block;overflow-x:auto;white-space:nowrap}
.prose th,.prose td{padding:10px 14px;text-align:left;
  border-bottom:1px solid rgba(0,255,65,.12)}
.prose th{color:var(--grn);font-weight:700;background:rgba(0,255,65,.07);
  text-transform:uppercase;font-size:11px;letter-spacing:.9px;white-space:nowrap}
.prose td{color:var(--dim)}
.prose td:first-child{color:#eaffef}
.prose tr:last-child td{border-bottom:none}
.prose table code{white-space:nowrap}

.prose img{max-width:100%;height:auto}

.doc-foot{border-top:1px solid var(--line);padding:22px 0 0;margin-top:10px;
  display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}
.doc-foot a{color:var(--grn);text-decoration:none;font-size:13px}
.doc-foot a:hover{text-decoration:underline}
.top{border:1px solid var(--line);padding:7px 14px;border-radius:2px;
  color:var(--dim)!important;font-size:12px;transition:.16s}
.top:hover{color:var(--grn)!important;border-color:var(--grn);text-decoration:none!important}

/* -- 6. Syntax highlighting (Rouge) --------------------------------------- */
.highlight .c,.highlight .c1,.highlight .cm,.highlight .cs{color:#4f7a5c;font-style:italic}
.highlight .k,.highlight .kd,.highlight .kn,.highlight .kr,.highlight .kt{color:#00ff41;font-weight:600}
.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sd{color:#ffb000}
.highlight .nb,.highlight .nf,.highlight .nx{color:#00e5ff}
.highlight .nv,.highlight .vg,.highlight .vi{color:#a9ffc4}
.highlight .m,.highlight .mi,.highlight .mf{color:#ff8adf}
.highlight .o,.highlight .ow{color:#c8ffd8}
.highlight .p{color:#8fbf9e}
.highlight .err{color:var(--red)}
.highlight .gp{color:var(--grn);user-select:none}

/* -- 7. Footer ------------------------------------------------------------ */
footer{border-top:1px solid var(--line);padding:34px 0 46px;text-align:center;
  color:var(--dim);font-size:12.5px}
footer a{color:var(--grn);text-decoration:none}
footer a:hover{text-decoration:underline}
.fl{display:flex;gap:18px;justify-content:center;flex-wrap:wrap;margin-bottom:14px}

/* -- 8. Responsive + reduced motion --------------------------------------- */
@media (max-width:600px){
  /* The language pill sat flush against the viewport edge. Give the nav a
     little more right padding and let the pill wrap with the links. */
  .nav-in{padding-right:12px}
  .lang-switch{margin-left:auto}
  header.hero{padding:40px 0 30px}
  section{padding:40px 0}
  .term-body{font-size:11.5px;padding:13px 12px}

  /* Reclaim the side gutters. 10px page padding + 12px panel padding gives
     ~22px per side instead of ~46px, which is a real gain in line length
     on a 360px screen. */
  .wrap{padding:0 10px}
  .prose{padding:18px 12px 30px;margin:14px 0 20px;border-radius:5px}
  .prose pre{font-size:12.5px;padding:13px 11px}
  .doc-head{padding:20px 0 14px}

  /* The nav was overflowing and clipping its last item ("github").
     Allow wrapping instead of letting it run off the edge. */
  .nav-in{flex-wrap:wrap;gap:4px 10px;padding:8px 10px}
  .nav-links{display:flex;flex-wrap:wrap;gap:2px 14px;font-size:13px}
  .brand{font-size:15px}
  .doc-nav a{font-size:11.5px;padding:4px 9px}

  /* Tables scroll inside their own bordered box, so it reads as scrollable
     rather than simply cut off at the panel edge. */
  .prose table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;
    border:1px solid var(--line);border-radius:4px}
  .prose table td,.prose table th{min-width:100px}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto!important}
  #matrix{display:none}
}

/* -- 9. Per-page quote ---------------------------------------------------- */
.quote{
  position:relative;
  margin:22px 0 0;
  padding:18px 20px 16px 46px;
  background:linear-gradient(180deg,rgba(0,26,11,.86),rgba(0,20,8,.9));
  border:1px solid var(--line);
  border-left:3px solid var(--grn);
  border-radius:5px;
  box-shadow:0 0 34px rgba(0,255,65,.09);
}
.quote::before{
  content:"\201C";
  position:absolute;left:13px;top:8px;
  font-size:38px;line-height:1;color:var(--grn);opacity:.5;
}
.quote .q-text{
  margin:0;border:none;background:none;padding:0;
  color:#eaffef;font-size:clamp(13.5px,3.2vw,16px);line-height:1.7;
  font-style:normal;letter-spacing:.2px;
  text-shadow:0 0 16px rgba(0,255,65,.22);
  min-height:1.7em;
}
.quote.typing .q-text::after{
  content:"█";color:var(--grn);margin-left:1px;
  animation:blink 1.05s step-end infinite;
}
.quote figcaption{
  margin-top:9px;font-size:12px;color:var(--dim);letter-spacing:.6px;
  opacity:0;transition:opacity .5s ease .1s;
}
.quote.done figcaption{opacity:1}
.quote.typing figcaption{opacity:0}

/* Landing-page variant: centred, no panel. */
.hero .quote{
  background:none;border:none;box-shadow:none;
  padding:0 0 0 30px;margin:26px auto 0;max-width:620px;text-align:left;
}
.hero .quote::before{left:0;top:-4px;font-size:34px}

@media (max-width:600px){
  .quote{padding:15px 15px 13px 38px;margin-top:18px}
  .quote::before{font-size:32px;left:11px}
}

/* -- 9. Bilingual ---------------------------------------------------------- */

/* Self-hosted so Bangla pages make no third-party request. Google Fonts would
   send every visitor's IP to Google and add three blocking round-trips; this
   is one file from the same origin. It is a variable font, so a single file
   covers 400/600/700 — the three Google URLs were byte-identical.
   Subset to the Bengali unicode-range only. */
@font-face{
  font-family:'Noto Sans Bengali';
  font-style:normal;
  font-weight:100 900;
  font-stretch:100%;
  font-display:swap;
  src:url(../fonts/noto-bengali.woff2) format('woff2');
  unicode-range:U+0951-0952,U+0964-0965,U+0980-09FE,U+1CD0,U+1CD2,U+1CD5-1CD6,
    U+1CD8,U+1CE1,U+1CEA,U+1CED,U+1CF2,U+1CF5-1CF7,U+200C-200D,U+20B9,U+25CC,U+A8F1;
}

/* Language switch pill in the nav. Deliberately styled as a control rather
   than another nav link, so it does not read as a section of the site. */
.lang-switch{
  border:1px solid var(--line); border-radius:999px;
  padding:2px 10px; font-size:12px; letter-spacing:.03em;
  color:var(--dim) !important; transition:.16s; white-space:nowrap;
}
.lang-switch:hover,.lang-switch:focus-visible{
  border-color:var(--grn); color:var(--grn) !important;
  background:rgba(0,255,65,.07);
}

/* Bangla needs more line height than Latin: the script has ascenders,
   descenders and the matra bar, which collide at Latin leading. */
html[lang="bn"] body{
  font-family:"Noto Sans Bengali", var(--mono);
  line-height:1.95;
}
html[lang="bn"] .prose p,
html[lang="bn"] .prose li{ line-height:2.05; }

/* Bangla must not be justified. Without hyphenation the browser stretches
   inter-word spacing to fill each line, which in Bengali script produces
   very visible rivers of whitespace between conjuncts. */
html[lang="bn"] .prose,
html[lang="bn"] .prose p,
html[lang="bn"] .prose li,
html[lang="bn"] .quote .q-text{
  text-align:left;
  text-justify:none;
  word-spacing:normal;
}
html[lang="bn"] .prose h1{ line-height:1.5; }
html[lang="bn"] .prose h2,
html[lang="bn"] .prose h3{ line-height:1.6; }
html[lang="bn"] .prose td,
html[lang="bn"] .prose th{ line-height:1.85; }

/* Code, commands and identifiers stay monospace even inside Bangla prose —
   a command rendered in a Bangla UI font is hard to read and easy to mistype. */
html[lang="bn"] code,
html[lang="bn"] pre,
html[lang="bn"] kbd,
html[lang="bn"] .term-body{
  font-family:var(--mono);
  line-height:1.7;
}

/* The heading prefixes ($ ## ###) are ASCII decoration; keep them monospace
   so they align with the English pages. */
html[lang="bn"] .prose h1::before,
html[lang="bn"] .prose h2::before,
html[lang="bn"] .prose h3::before{ font-family:var(--mono); }
