/*
Theme Name: systemd
Theme URI: https://katanyxislabs.com
Description: Standalone CRT terminal theme for KatanyxisLabs.com. Forked from the GPL theme BlankSlate.
Author: Katanyxis Labs
Version: 1.0
Requires PHP: 7.4
License: GNU General Public License v3 or Later
License URI: https://www.gnu.org/licenses/gpl.html
Text Domain: systemd
*/

/* NOTE: no "Template:" line above = this is a STANDALONE theme.
   WordPress will no longer fall back to the blankslate folder,
   so this theme folder must contain ALL template .php files. */

/* download the VT323 pixel/terminal font from Google Fonts.
   @import MUST be the first rule in the file or browsers ignore it */
@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');

/*===================================================================
  RESET (taken from BlankSlate's stylesheet)
  Zeroes out every browser default (margins, paddings, list bullets,
  font sizing) so all spacing on the site comes from OUR rules only.
===================================================================*/
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}html{scroll-behavior:smooth}body{line-height:1}a{text-decoration-skip-ink:auto}a[href^="tel"]{color:inherit;text-decoration:none}button{outline:0}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}q{display:inline;font-style:italic}q:before{content:'"';font-style:normal}q:after{content:'"';font-style:normal}textarea,input[type="text"],input[type="button"],input[type="submit"],input[type="reset"],input[type="search"],input[type="password"]{appearance:none;border-radius:0}input[type="search"]{appearance:textfield}table{border-collapse:collapse;border-spacing:0}th,td{padding:2px}big{font-size:120%}small,sup,sub{font-size:80%}sup{vertical-align:super}sub{vertical-align:sub}dd{margin-left:20px}kbd,tt{font-family:courier;font-size:12px}ins{text-decoration:underline}del,strike,s{text-decoration:line-through}dt{font-weight:bold}address,cite,var{font-style:italic}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}

/* WordPress accessibility helpers: keep screen-reader text and the
   "skip to content" link invisible until focused */
.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important;word-break:normal}
.screen-reader-text:focus{background-color:#f7f7f7;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;clip-path:none;color:#007acc;display:block;font-size:14px;font-size:.875rem;font-weight:700;height:auto;right:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}
.skip-link{left:-9999rem;top:2.5rem;z-index:999999999;text-decoration:underline}
.skip-link:focus{display:block;left:6px;top:7px;font-size:14px;font-weight:600;text-decoration:none;line-height:normal;padding:15px 23px 14px;z-index:100000;right:auto}
.visually-hidden:not(:focus):not(:active), .form-allowed-tags:not(:focus):not(:active){position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px, 1px, 1px, 1px);white-space:nowrap}

/*===================================================================
  CONTROL PANEL — change these values, everything below follows.
  A "CSS variable" is defined once here and reused with var(--name).
===================================================================*/
:root {
  /*—————— background color ——————*/
  --bg-color: #0a0a0a;

  /*—————— main text / phosphor color ——————*/
  --text-color: #33ff33;

  /*—————— dim green used for borders ——————*/
  --border-color: #135c13;

  /*—————— body/paragraph text size ——————*/
  --body-text-size: 18px;

  /*—————— site title (top-left) font size ——————*/
  --site-title-size: 32px;

  /*—————— page/post title font size ——————*/
  --page-title-size: 28px;

  /*—————— header size (top padding / bottom padding) ——————*/
  --header-pad-top: 4px;
  --header-pad-bottom: 10px;

  /*—————— footer size ——————*/
  --footer-pad: 10px;

  /*—————— CRT bezel (the plastic monitor frame around the screen) ——————
     width  = how thick the frame is
     color  = the plastic color (dark grey reads as "monitor case")
     radius = how rounded the screen corners are */
  --bezel-width: 10px;
  --bezel-color: #1a1a1a;
  --bezel-radius: 14px;

  /*—————— scanline color ——————
     currently SOLID WHITE as a visibility test — this will look like
     a white veil once live. For the real CRT look use a low opacity
     (4th number, 0 to 1), e.g.:
       white lines: rgba(255, 255, 255, 0.06)
       green lines: rgba(51, 255, 51, 0.08)   */
  --scanline-color: rgba(22, 102, 22, 0.065);

  /*—————— scanline size ——————
     gap = dark space between lines, thickness = the line itself */
  --scanline-gap: 2px;
  --scanline-thickness: 1px;

  /*—————— scanline speed ——————
     time for the lines to crawl down by one full line.
     SMALLER = FASTER. 0.15s is subtle; try 1s to clearly see it */
  --scanline-speed: 0.15s;

  /*—————— scanline flicker speed ——————
     length of one full flicker cycle */
  --flicker-speed: 4s;
}

/*===================================================================
  GENERAL RULES
===================================================================*/

/*—————— page background + base text style ——————*/
body {
  background-color: var(--bg-color);
  color: var(--text-color);
  font-family: 'VT323', 'Courier New', monospace;
  font-size: var(--body-text-size);
  line-height: 1.4;
  text-shadow: 0 0 4px rgba(51, 255, 51, 0.6); /* phosphor glow */
  /* breathing room, sized so content clears the bezel frame; the
     extra bottom padding keeps content from hiding under the
     fixed status bar */
  padding: calc(var(--bezel-width) + 4px)
           calc(var(--bezel-width) + 18px)
           calc(var(--bezel-width) + 44px);
  /* body is the scrolling element (see html rule below), which puts
     the scrollbar inside the bezel frame */
  height: 100%;
  overflow-y: auto;
  scroll-behavior: smooth;
  scrollbar-color: var(--border-color) #050505; /* thumb / track */
}

/*—————— links: green underline, invert on hover ——————
   phosphor trail: lighting up is instant, but fading back takes
   half a second — like phosphor persistence on a real tube */
a {
  color: var(--text-color);
  text-decoration: underline;
  transition: background-color 0.5s ease-out, color 0.5s ease-out;
}
a:hover {
  background-color: var(--text-color);
  color: var(--bg-color);
  text-shadow: none;
  transition: none; /* instant on, slow off */
}

/*—————— headings: green, "> " prompt prefix on h1/h2 ——————*/
h1, h2, h3, h4, h5, h6 { color: var(--text-color); margin: 1em 0 0.5em; }
h1::before, h2::before { content: "> "; }

/*—————— heading sizes ——————
   the reset flattened every heading to body-text size (20px).
   This gives headings typed in the page/post editor a real size
   ladder again. (Site title and post titles have their own more
   specific rules, so these don't affect them.) */
h1 { font-size: 34px; }
h2 { font-size: 28px; }
h3 { font-size: 24px; }
h4, h5, h6 { font-size: 21px; }

/*—————— images never overflow their container ——————*/
img { max-width: 100%; height: auto; }

/*—————— behind the "screen": pure black ——————
   overflow: hidden here + overflow-y: auto on body below moves the
   scrollbar from the window edge onto the BODY — so it renders
   INSIDE the bezel frame instead of outside it */
html {
  background: #000;
  height: 100%;
  overflow: hidden;
}

/*—————— selected/highlighted text inverts, like a terminal ——————*/
::selection { background: var(--text-color); color: var(--bg-color); text-shadow: none; }

/*—————— horizontal rules become dashed terminal dividers ——————*/
hr { border: none; border-top: 1px dashed var(--border-color); margin: 16px 0; }

/*—————— tables (e.g. the calendar block): green grid on black.
   Kills the white default header cells WordPress ships ——————*/
table { border-collapse: collapse; }
th, td {
  border: 1px solid var(--border-color);
  padding: 4px 8px;
  text-align: center;
  background: transparent;
  color: var(--text-color);
}
th, .wp-block-calendar th { background: rgba(51, 255, 51, 0.08); }

/*—————— calendar glow control ——————
   WordPress always gives the calendar table id="wp-calendar", so we
   target that directly (an #id rule outranks everything else).
   Every cell: glow OFF, text dimmed to the grid green.
   Caption (month/year), post days (they contain links), and today:
   full brightness + glow. Borders and spacing untouched */
#wp-calendar th,
#wp-calendar td {
  color: var(--border-color);
  text-shadow: none;
}

#wp-calendar caption,
#wp-calendar td a,
#wp-calendar #today {
  color: var(--text-color);
  text-shadow: 0 0 4px rgba(51, 255, 51, 0.6);
}

/* today's weekday column header — a small script in functions.php
   finds today's column and adds this class to its <th> */
#wp-calendar th.today-weekday {
  color: var(--text-color);
  text-shadow: 0 0 4px rgba(51, 255, 51, 0.6);
}

/*===================================================================
  SCANLINE RULES
  One invisible layer pinned over the whole screen (position: fixed),
  filled with repeating horizontal stripes. Clicks pass through it.
===================================================================*/

/*—————— the scanline layer itself ——————*/
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  /* stripe pattern: gap of nothing, then one thin colored line, repeat */
  background: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent var(--scanline-gap),
    var(--scanline-color) var(--scanline-gap),
    var(--scanline-color) calc(var(--scanline-gap) + var(--scanline-thickness))
  );
  /* two animations at once: crawl downward + brightness flicker */
  animation:
    scanline-scroll var(--scanline-speed) linear infinite,
    scanline-flicker var(--flicker-speed) infinite;
}

/*—————— scanline movement ——————
   slides the pattern down by exactly one line-repeat, then loops.
   Because the shift equals the pattern size, the loop is seamless */
@keyframes scanline-scroll {
  from { background-position-y: 0; }
  to   { background-position-y: calc(var(--scanline-gap) + var(--scanline-thickness)); }
}

/*—————— scanline flicker ——————
   irregular little dips in opacity, like an unstable tube.
   Lower the dip values (0.7, 0.85...) for a harsher flicker */
@keyframes scanline-flicker {
  0%, 100% { opacity: 1; }
  7%       { opacity: 0.7; }
  8%       { opacity: 1; }
  36%      { opacity: 0.85; }
  38%      { opacity: 1; }
  61%      { opacity: 0.65; }
  62%      { opacity: 1; }
  87%      { opacity: 0.9; }
  89%      { opacity: 1; }
}

/*—————— CRT bezel + curved-glass screen edges ——————
   one fixed overlay does three jobs:
   1. the BORDER is the plastic monitor frame (bezel variables above)
   2. the first inset shadow is the dark falloff of the curved glass
      (260px = how far it reaches in, 0.39 = how dark, 0 to 1)
   3. the second inset shadow is a faint green rim where the phosphor
      light catches the inside edge of the glass */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9998; /* sits just under the scanlines */
  border: var(--bezel-width) solid var(--bezel-color);
  border-radius: var(--bezel-radius);
  box-shadow:
    inset 0 0 260px 80px rgba(0, 0, 0, 0.39),
    inset 0 0 18px rgba(51, 255, 51, 0.1);
}

/*===================================================================
  HEADER RULES
===================================================================*/

/*—————— header block: hugs the top, dim line underneath ——————*/
#header {
  padding: var(--header-pad-top) 0 var(--header-pad-bottom);
  border-bottom: 1px solid var(--border-color);
}

/*—————— site title: big, no underline, no extra margin ——————*/
#site-title,
#site-title h1 { margin: 0; font-size: var(--site-title-size); }
#site-title a { text-decoration: none; }

/*—————— blinking cursor after the site title ——————
   the cursor is now a REAL <span class="title-cursor"> printed by the
   child theme's own header.php (template override) — not a CSS trick */
.title-cursor {
  display: inline-block;
  width: 0.4em;
  height: 0.85em;
  margin-left: 6px;
  background: var(--text-color);
  animation: blink 1s steps(1) infinite;
}

/*—————— kill ALL old pseudo-element cursors ——————
   every past version drew the cursor with ::after rules like these.
   If any stale copy is still injected (Customizer Additional CSS,
   LiteSpeed UCSS/critical CSS), this permanently disables them */
#site-title::after,
.site-title::after,
#site-title a::after { content: none !important; }

/*—————— cursor blink animation ——————*/
@keyframes blink { 50% { opacity: 0; } }

/*—————— tagline: right under the title, slightly dim ——————*/
#site-description { margin: 0 0 8px; opacity: 0.8; }

/*—————— nav menu: one horizontal row, "> " before each link ——————*/
#menu ul { display: flex; flex-wrap: wrap; gap: 4px 24px; margin: 0; }
#menu a { text-decoration: none; }
#menu a::before { content: "> "; }

/*—————— search row: input + button side by side, "$" prompt ——————*/
#search { margin-top: 6px; }
#search form { display: flex; gap: 6px; align-items: center; }
#search form::before { content: "$"; }

/*—————— header links: no leftover hover background ——————*/
header a { background: transparent; }

/*===================================================================
  CONTENT RULES
===================================================================*/

/*—————— each post/page sits in its own dim green box ——————
   the faint background wash makes boxes read as "panels" instead of
   just outlines; the hover glow makes the post list feel alive */
#content article {
  border: 1px solid var(--border-color);
  padding: 14px 18px;
  margin: 16px 0;
  background: rgba(51, 255, 51, 0.03);
}
#content article:hover {
  border-color: var(--text-color);
  box-shadow: 0 0 12px rgba(51, 255, 51, 0.25);
}

/*—————— post/page titles: bigger, flush with top of the box ——————*/
.entry-title { font-size: var(--page-title-size); }
#content article .entry-title { margin-top: 0; }

/*—————— post title bar ——————
   the title becomes a "window title bar": it bleeds out to the box
   edges (negative margins cancel the box padding), gets its own
   green-tinted strip, and a line separating it from the body text.
   Makes each post read like a terminal window ——————*/
.blog #content article .entry-title,
.archive #content article .entry-title,
.search #content article .entry-title,
.single #content article .entry-title {
  margin: -14px -18px 10px; /* pull out to the box edges */
  padding: 6px 18px;
  background: rgba(51, 255, 51, 0.07);
  border-bottom: 1px solid var(--border-color);
}

/*—————— post footer (Categories / Comments line) ——————
   dashed divider above it so it reads as the box's status line */
#content article .entry-footer {
  border-top: 1px dashed var(--border-color);
  margin-top: 10px;
  padding-top: 6px;
  font-size: 16px;
  opacity: 0.7;
}

/*—————— hide the title on PAGES ——————
   WordPress forces every page to have a title, but we don't want it
   shown. On static pages the <body> tag gets a "page" class, so this
   hides the title there only — blog posts keep their titles */
.page .entry-title { display: none; }

/*—————— "author | date" line: smaller and dimmer ——————*/
.entry-meta { font-size: 16px; opacity: 0.6; }

/*—————— "Edit This" link (only visible to logged-in you) ——————*/
.post-edit-link { font-size: 16px; opacity: 0.6; }

/*—————— embed cards ——————
   functions.php converts embeds of our OWN pages into these cards
   (div.embed-card) automatically — nothing to set in the editor.
   Same panel look as the post list ——————*/
.embed-card {
  border: 1px solid var(--border-color);
  background: rgba(51, 255, 51, 0.03);
  padding: 14px 18px;
  margin: 16px 0;
}
.embed-card:hover {
  border-color: var(--text-color);
  box-shadow: 0 0 12px rgba(51, 255, 51, 0.25);
}

/* card heading = title bar strip, stretched to the box edges
   (negative margins must mirror the card padding above) */
.embed-card .embed-card-title {
  margin: -14px -18px 10px;
  padding: 6px 18px;
  background: rgba(51, 255, 51, 0.07);
  border-bottom: 1px solid var(--border-color);
}

/* the link reads as a command: "$ open Page Title" */
.embed-card a { text-decoration: none; }
.embed-card a::before { content: "$ "; }
.embed-card a:hover { text-decoration: underline; }

/*—————— projects page: directory listing ——————
   functions.php adds the page slug to the <body> classes, so the
   projects page automatically gets class "page-projects". Any
   bulleted List block on that page renders like `ls -l` output:
     drwxr-xr-x  guest  ArchThinkCluster/
   Links keep working; plain-text items (unstarted projects) get the
   same row prefix ——————*/
.page-projects #content ul {
  list-style: none;
  margin: 0.5em 0;
  padding: 0;
}
.page-projects #content ul li { padding: 2px 0; }

/* the fake permissions/owner columns before each row.
   white-space: pre keeps the double spaces for column alignment.
   "katanyxis" is decorative text — change it to anything */
.page-projects #content ul li::before {
  content: "drwxr-xr-x  katanyxis  ";
  white-space: pre;
  opacity: 0.55;
}

/* project links look like directory names: no underline, trailing / */
.page-projects #content ul li a { text-decoration: none; }
.page-projects #content ul li a::after { content: "/"; }

/*—————— 404 kernel panic page ——————
   404.php prints a fake crash dump on a bare page (no site header
   or footer). EVERYTHING on the page flickers like a dying tube —
   the animation sits on the whole article so all text inherits it */
.error-404 {
  padding: 20px 0;
  animation: scanline-flicker 2s infinite; /* reuse existing keyframes */
}

/* the crash dump: keep line breaks, wrap long lines on phones */
.error-404 .panic-dump {
  font-family: inherit;      /* keep the VT323 terminal font */
  white-space: pre-wrap;
  line-height: 1.35;
  margin: 0 0 20px;
}

/* the 404 headline */
.error-404 .panic-title { font-size: var(--page-title-size); }

/* the "cd ~/" escape hatch: bigger, boxed, command-style prompt */
.error-404 .panic-actions a {
  display: inline-block;
  border: 1px solid var(--text-color);
  padding: 4px 14px;
  font-size: 22px;
  text-decoration: none;
}
.error-404 .panic-actions a::before { content: "$ "; }

/*===================================================================
  FORM RULES (search box, buttons)
===================================================================*/

/*—————— text/search boxes: black, green text, green border ——————*/
input[type="search"], input[type="text"] {
  background: var(--bg-color);
  color: var(--text-color);
  border: 1px solid var(--text-color);
  font-family: inherit;
  font-size: inherit;
  padding: 2px 6px;
  caret-color: var(--text-color); /* green typing cursor */
}

/*—————— focused box: green glow instead of blue outline ——————*/
input[type="search"]:focus, input[type="text"]:focus {
  outline: none;
  box-shadow: 0 0 6px rgba(51, 255, 51, 0.8);
}

/*—————— buttons: black/green box, invert on hover ——————*/
input[type="submit"], button {
  background: var(--bg-color);
  color: var(--text-color);
  border: 1px solid var(--text-color);
  font-family: inherit;
  font-size: inherit;
  padding: 2px 10px;
  cursor: pointer;
}
input[type="submit"]:hover, button:hover {
  background: var(--text-color);
  color: var(--bg-color);
  text-shadow: none;
}

/*===================================================================
  BOOT SCREEN RULES
  Front-page-only overlay (see header.php): solid black layer that
  prints fake startup lines, then fades out. It sits UNDER the bezel
  and scanlines so the CRT effects stay on top of it.
===================================================================*/
#boot-screen {
  position: fixed;
  inset: 0;
  z-index: 9990;
  background: #000;
  padding: calc(var(--bezel-width) + 24px);
  transition: opacity 0.6s; /* the fade-out */
}

/* the fade is triggered by adding this class when boot completes */
#boot-screen.boot-done { opacity: 0; pointer-events: none; }

/* the boot text itself: terminal font, tight lines */
#boot-lines {
  font-family: inherit;
  white-space: pre-wrap;
  line-height: 1.35;
}

/* the skip hint: small and dim, pinned above the status bar */
#boot-skip {
  position: absolute;
  bottom: calc(var(--bezel-width) + 34px);
  right: calc(var(--bezel-width) + 24px);
  font-size: 15px;
  opacity: 0.5;
}

/*===================================================================
  MOUSE TRAIL RULES
  footer.php drops one of these wherever the mouse moves; each one is
  a ghost arrow-cursor that glows and fades, like phosphor
  persistence chasing the pointer.
  KNOBS:
    width/height       = arrow size
    drop-shadow(...)   = glow color + reach
    background (below) = arrow body color
    trail-fade time    = how long a ghost lingers
===================================================================*/
.mouse-trail {
  position: fixed;
  width: 12px;
  height: 16px;
  opacity: 0.55;               /* ghost transparency: 0 = invisible, 1 = solid */
  pointer-events: none;
  z-index: 9996;
  /* the glow: drop-shadow follows the arrow outline (a box-shadow
     would get clipped off by the arrow shaping below) */
  filter: drop-shadow(0 0 2px rgba(255, 51, 211, 0.651));
  animation: trail-fade 0.1s ease-out forwards; /* decay time */
}

/* the arrow itself: a colored layer cut into a pointer shape.
   clip-path connects the listed corner points into a polygon */
.mouse-trail::before {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background: var(--text-color); /* arrow body color */
  clip-path: polygon(0 0, 0 82%, 24% 64%, 38% 95%, 50% 89%, 36% 60%, 62% 60%);
}

/* each ghost fades and shrinks away on its own */
@keyframes trail-fade {
  to { opacity: 0; transform: scale(0.2); }
}

/*===================================================================
  FOOTER RULES
===================================================================*/

/*—————— footer: terminal status bar ——————
   a thin strip pinned to the bottom of the screen, tucked just
   inside the bezel frame. Left side: shell prompt. Right side:
   live clock + copyright (see footer.php) */
#footer {
  position: fixed;
  left: var(--bezel-width);
  right: var(--bezel-width);
  bottom: var(--bezel-width);
  z-index: 9997;              /* under the bezel + scanlines */
  display: flex;
  justify-content: space-between; /* prompt left, clock right */
  gap: 12px;
  padding: 3px 14px;
  font-size: 16px;
  background: #050505;        /* solid, so content scrolls behind it */
  border-top: 1px solid var(--border-color);
}

/*===================================================================
  MOBILE RULES
  Adjustments for phones / narrow screens (768px wide and under).
  A "@media" block only applies when the screen matches its
  condition — everything above stays as-is on desktop.
===================================================================*/
@media (max-width: 768px) {

  /* thinner monitor frame — 10px eats too much of a small screen */
  :root {
    --bezel-width: 6px;
    --bezel-radius: 10px;
    --site-title-size: 26px;
    --page-title-size: 24px;
  }

  /* gentler glass-edge shading: the desktop 260px reach would
     darken half the screen on a phone */
  body::before {
    box-shadow:
      inset 0 0 70px 12px rgba(0, 0, 0, 0.39),
      inset 0 0 10px rgba(51, 255, 51, 0.1);
  }

  /* tighter side padding so text gets the width it needs */
  body {
    padding: calc(var(--bezel-width) + 4px)
             calc(var(--bezel-width) + 8px)
             calc(var(--bezel-width) + 40px);
  }

  /* nav menu: tighter gaps between links when they wrap */
  #menu ul { gap: 2px 14px; }

  /* status bar: smaller text; drop the shell prompt so the clock
     and copyright fit on one narrow line */
  #footer { font-size: 14px; padding: 2px 10px; }
  #footer .status-left { display: none; }

  /* calendar: smaller cells so all 7 columns fit */
  th, td { padding: 2px 4px; }
}
