/* harrhys.com · theme.css · cyberpunk look, lighting, splash */
/* ---------- cyberpunk layer ---------- */
/* page background (colour + grid) lives on <html>, the very bottom layer, so the drifting lights (#bgfx) always
   paint above it and Safari still gets a solid colour for overscroll */
html{background:linear-gradient(var(--grid) 1px,transparent 1px) 0 0/32px 32px,linear-gradient(90deg,var(--grid) 1px,transparent 1px) 0 0/32px 32px,var(--paper)}
body{min-height:100vh;background:transparent;overflow-x:clip}
:root[data-theme="dark"] body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:40;background:repeating-linear-gradient(0deg,rgba(255,255,255,.018) 0 1px,transparent 1px 3px)}
::selection{background:var(--blue);color:#000}

/* type */
h1{text-transform:uppercase;letter-spacing:.04em}
:root[data-theme="dark"] h1{text-shadow:0 0 18px var(--glow)}
h2{text-transform:uppercase;letter-spacing:.06em}
.crumb,.scount,.tmenu .mh,.badge,.opt,label.f,.tag label{font-family:"Share Tech Mono",ui-monospace,Consolas,monospace;letter-spacing:.04em}
.crumb,.tmenu .mh{text-transform:uppercase}
.pct,.count,.stat strong{font-family:"Share Tech Mono",ui-monospace,Consolas,monospace;font-weight:400}

/* header + logo */
header.top{background:color-mix(in srgb,var(--paper) 78%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-bottom:1px solid var(--line);box-shadow:0 1px 0 var(--glow)}
.logo{text-transform:uppercase;letter-spacing:.06em}
.logo span{color:var(--blue-ink)}
.logo::after{content:"_";color:var(--sage);animation:blink 1.1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
.tl{border-radius:3px;text-transform:uppercase;letter-spacing:.06em;font-size:.9rem}
.tl.on{background:transparent;color:var(--sage-d);box-shadow:inset 0 -2px 0 var(--sage)}
:root[data-theme="dark"] .tl.on{text-shadow:0 0 10px var(--glow)}
.themebtn{border-radius:3px}

/* sharper surfaces */
.tool,.panel,.stat,.tag,.empty,.win,.out,.pw,.fix,.cmd,.seg,.tmenu,.toast{border-radius:4px}
button,.btn,input[type=text],input[type=search],input[type=number],input[type=date],input[type=datetime-local],textarea,select,.tag input{border-radius:3px}
input[type=date],input[type=datetime-local]{color-scheme:light}:root[data-theme="dark"] input[type=date],:root[data-theme="dark"] input[type=datetime-local]{color-scheme:dark}
.seg button{border-radius:2px}
.badge{border-radius:2px}
.tool .ic,.tmenu .mi{border-radius:3px;font-family:"Share Tech Mono",ui-monospace,Consolas,monospace;font-weight:400;border:1px solid currentColor}
.bitem{border-radius:4px}

/* neon tiles: corner bracket + glow on hover */
.tool,.panel,.stat{position:relative}
.tool::before{content:"";position:absolute;top:-1px;left:-1px;width:18px;height:18px;border-top:2px solid var(--sage);border-left:2px solid var(--sage);transition:width .5s var(--ease),height .5s var(--ease)}
.tool::after{content:"";position:absolute;bottom:-1px;right:-1px;width:18px;height:18px;border-bottom:2px solid var(--blue);border-right:2px solid var(--blue);transition:width .5s var(--ease),height .5s var(--ease)}
.tool:hover::before,.tool:hover::after{width:44px;height:44px}
.tool:hover{border-color:var(--sage);box-shadow:0 0 0 1px var(--sage),0 14px 32px var(--glow)}
:root[data-theme="dark"] .tool:hover{box-shadow:0 0 0 1px var(--sage),0 0 28px var(--glow),0 16px 32px rgba(0,0,0,.5)}
.bitem:hover{box-shadow:inset 3px 0 0 var(--sage),0 10px 24px var(--glow)}
:root[data-theme="dark"] .bitem:hover{box-shadow:inset 3px 0 0 var(--sage),0 0 22px var(--glow)}

/* buttons */
.primary{clip-path:polygon(0 0,calc(100% - 10px) 0,100% 10px,100% 100%,10px 100%,0 calc(100% - 10px));text-transform:uppercase;letter-spacing:.05em;color:#04140B}
.primary:hover{background-color:#5CEB97;color:#04140B}
button:hover,.btn:hover{box-shadow:0 0 0 1px var(--sage)}
.primary:hover,.ghost:hover{box-shadow:none}
.armed{box-shadow:0 0 18px rgba(255,59,92,.45)!important}
input:focus,textarea:focus,select:focus{outline:none;box-shadow:0 0 0 1px var(--sage),0 0 14px var(--glow)}

/* progress + checks */
.mini,.bar,.strength{border-radius:0;height:8px}
.mini span,.bar span{background:linear-gradient(90deg,var(--sage),var(--blue));box-shadow:0 0 10px var(--glow)}
ul.steps input[type=checkbox]{border-radius:3px}
:root[data-theme="dark"] ul.steps input[type=checkbox]:checked{box-shadow:0 0 10px rgba(57,255,159,.45)}
.toast{border:1px solid var(--sage);box-shadow:0 0 22px var(--glow);font-family:"Share Tech Mono",ui-monospace,Consolas,monospace;font-weight:400;letter-spacing:.04em}
:root[data-theme="dark"] .toast{background:var(--card);color:var(--sage-d)}
:root[data-theme="dark"] mark{color:#000}
:root[data-theme="dark"] .qrbox svg{box-shadow:0 0 22px var(--glow)}

/* ---------- lighting ---------- */
@property --spot{syntax:"<number>";inherits:false;initial-value:0}
/* ambient glows drifting behind everything */
/* background fx layer: pinned to the screen, transform-only animation so it stays cheap */
#bgfx{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
/* lava lamp: oval blobs. JS gives each a random size + start point, then keeps sending it
   on slow random rise/sink trips while it grows or shrinks (transform). CSS adds a slow
   stretch+turn (scale/rotate) and a brightness pulse on separate timelines. */
/* each blob sits on its own parallax layer (.pl, moved by lava.js on scroll). No blend modes here: screen/multiply on
   full-screen layers made the browser re-blend the whole background every scroll frame (dropped frames), and plain
   see-through blobs look all but identical */
.pl{position:absolute;inset:0;will-change:transform}.au{position:absolute;left:0;top:0;width:var(--s,45vmax);height:var(--s,45vmax);margin:calc(var(--s,45vmax) / -2) 0 0 calc(var(--s,45vmax) / -2);background:radial-gradient(ellipse 50% 36% at 50% 50%,var(--c),transparent 72%);will-change:transform,opacity}
.a1{--c:rgb(from var(--sage) r g b / .40);animation:morph 28s ease-in-out infinite alternate,pulse2 9s ease-in-out infinite alternate}
.a2{--c:rgb(from var(--blue) r g b / .26);animation:morph 34s ease-in-out -9s infinite alternate-reverse,pulse2 11s ease-in-out -3s infinite alternate}
.a3{--c:rgb(from var(--sage) r g b / .28);animation:morph 24s ease-in-out -5s infinite alternate,pulse2 8s ease-in-out -2s infinite alternate}
.a4{--c:rgb(from var(--blue) r g b / .20);animation:morph 31s ease-in-out -14s infinite alternate-reverse,pulse2 10s ease-in-out -6s infinite alternate}
.a5{--c:rgb(from var(--sage) r g b / .22);animation:morph 37s ease-in-out -3s infinite alternate,pulse2 12s ease-in-out -5s infinite alternate}
.a6{--c:rgb(from var(--blue) r g b / .16);animation:morph 26s ease-in-out -11s infinite alternate-reverse,pulse2 7s ease-in-out -2s infinite alternate}
@keyframes morph{0%{rotate:0deg}100%{rotate:120deg}}
@keyframes pulse2{0%{opacity:.6}100%{opacity:1}}
/* light mode: deeper colour so the blobs actually show on the pale background */
:root:not([data-theme="dark"]) .a1{--c:rgba(31,209,106,.62)}
:root:not([data-theme="dark"]) .a2{--c:rgba(240,205,0,.62)}
:root:not([data-theme="dark"]) .a3{--c:rgba(11,150,70,.45)}
:root:not([data-theme="dark"]) .a4{--c:rgba(245,185,0,.50)}
:root:not([data-theme="dark"]) .a5{--c:rgba(20,184,90,.48)}
:root:not([data-theme="dark"]) .a6{--c:rgba(225,210,0,.48)}
/* cursor spotlight on tiles, panels and rows (position set from JS) */
.tool,.panel,.stat,.bitem{--mx:50%;--my:0%;background-image:radial-gradient(260px circle at var(--mx) var(--my),rgb(from var(--sage) r g b / calc(var(--spot) * .16)),transparent 70%);transition:--spot .4s ease,transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s cubic-bezier(.22,1,.36,1),border-color .3s ease,background-color .35s ease}
.tool:hover,.panel:hover,.stat:hover,.bitem:hover{--spot:1}
.panel:hover,.stat:hover{border-color:color-mix(in srgb,var(--sage) 45%,var(--line))}
/* light sweep travelling along the header line */
header.top{overflow:clip}
/* iPad/iPhone: fully solid header (no transparency/blur) so Safari extends its colour into the status bar
   instead of showing page content scrolling behind it */
@media (max-width:999px){header.top{background:var(--paper);-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none}}
/* iPad/iPhone: header fixed to the top of the screen (Safari 26+ tints its status bar from a solid fixed header);
   the page is pushed down by the header's measured height (--hh, set from JS) so nothing hides under it */
@media (max-width:999px){header.top{position:fixed;top:0;left:0;right:0}body{padding-top:var(--hh,64px)}
  /* Safari draws whatever sits above the page's top edge into the status-bar strip; extend the header's
     solid background upwards so that strip always shows header colour, never scrolled content */
  header.top{overflow-x:clip;overflow-y:visible}
  header.top::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:100vh;background:var(--paper);pointer-events:none}}
/* home greeting typewriter: reserve the line(s) so typing never shifts the page */
.hero h1{min-height:1.05em}
.page-home .hero h1{font-size:clamp(1.7rem,3.05vw,3rem)}
@media (max-width:640px){.hero h1{min-height:2.1em}}
.caret{display:inline-block;width:.45ch;height:.82em;margin-left:.06em;vertical-align:-.02em;background:var(--sage);box-shadow:0 0 10px var(--glow);animation:blink 1s steps(1) infinite}
/* end of the home typewriter: caret flashes and collapses, a return key pops up, gets pressed, fades */
.caret.hit{animation:caretHit .6s cubic-bezier(.3,.7,.4,1) forwards}
.caret.gone{opacity:0;animation:none}
@keyframes caretHit{0%{opacity:1}20%{opacity:1;box-shadow:0 0 22px var(--glow),0 0 4px var(--sage)}100%{opacity:0;transform:scaleX(.15) scaleY(.2)}}
.retkey{display:inline-block;margin-left:.25em;padding:.08em .32em .12em;vertical-align:.25em;font:400 .42em/1 "Share Tech Mono",ui-monospace,monospace;color:var(--sage);border:1px solid var(--sage);border-radius:3px;box-shadow:0 2px 0 var(--sage),0 0 10px var(--glow);animation:retKey 1.1s cubic-bezier(.3,.7,.4,1) forwards;pointer-events:none}
@keyframes retKey{0%{opacity:0;transform:translateY(-.3em) scale(.7)}20%{opacity:1;transform:none}38%{transform:translateY(2px);box-shadow:0 0 0 var(--sage),0 0 18px var(--glow)}52%{transform:none;box-shadow:0 2px 0 var(--sage),0 0 10px var(--glow);opacity:1}100%{opacity:0;transform:translateX(.3em)}}
/* shine sweep across main buttons */
.primary,.primary:hover{background-image:linear-gradient(110deg,transparent 35%,rgba(255,255,255,.6) 50%,transparent 65%);background-size:250% 100%;background-repeat:no-repeat;background-position:130% 0;transition:background-position .8s var(--ease),background-color .25s ease,transform .35s cubic-bezier(.22,1,.36,1)}
.primary:hover{background-position:-30% 0}
:root[data-theme="dark"] .primary{box-shadow:0 0 16px var(--glow)}
:root[data-theme="dark"] .primary:hover{box-shadow:0 0 26px var(--glow)}
/* glowing icons + logo */
:root[data-theme="dark"] .tool:hover .ic{box-shadow:0 0 14px currentColor}
:root[data-theme="dark"] .logo span{text-shadow:0 0 12px rgba(252,238,10,.55)}
:root[data-theme="dark"] .syncdot{box-shadow:0 0 8px currentColor;color:var(--sage)}

/* ---------- splash ---------- */
#splash{position:fixed;inset:0;z-index:100;display:grid;place-items:center;background:radial-gradient(60% 50% at 50% 45%,rgba(43,255,136,.14),transparent 70%),linear-gradient(rgba(43,255,136,.05) 1px,transparent 1px) 0 0/32px 32px,linear-gradient(90deg,rgba(43,255,136,.05) 1px,transparent 1px) 0 0/32px 32px,#050706;color:#E6F2EA;transition:opacity .5s ease,transform .5s ease,filter .5s ease;cursor:pointer}
#splash::after{content:"";position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,rgba(255,255,255,.03) 0 1px,transparent 1px 3px)}
#splash.out{opacity:0;transform:scale(1.04);filter:blur(6px) brightness(1.6);pointer-events:none}
.sp-in{width:min(520px,86vw)}
.sp-logo{position:relative;font:700 clamp(2.6rem,9vw,4.6rem)/1 Rajdhani,"Exo 2",sans-serif;letter-spacing:.08em;color:#E6F2EA;text-shadow:0 0 24px rgba(43,255,136,.55);animation:spIn .7s cubic-bezier(.22,1,.36,1) both}
.sp-logo span{color:#FCEE0A;text-shadow:0 0 24px rgba(252,238,10,.55)}
.sp-logo::before,.sp-logo::after{content:attr(data-t);position:absolute;inset:0;pointer-events:none}
.sp-logo::before{color:#2BFF88;animation:glitchA 1.6s steps(1) infinite;mix-blend-mode:screen}
.sp-logo::after{color:#FCEE0A;animation:glitchB 1.6s steps(1) infinite;mix-blend-mode:screen}
@keyframes spIn{from{opacity:0;letter-spacing:.4em;filter:blur(8px)}to{opacity:1;letter-spacing:.08em;filter:none}}
@keyframes glitchA{0%,100%{clip-path:inset(0 0 100% 0);transform:none}10%{clip-path:inset(10% 0 60% 0);transform:translate(-4px,0)}20%{clip-path:inset(70% 0 5% 0);transform:translate(3px,0)}30%{clip-path:inset(0 0 100% 0)}62%{clip-path:inset(40% 0 35% 0);transform:translate(-3px,0)}66%{clip-path:inset(0 0 100% 0)}}
@keyframes glitchB{0%,100%{clip-path:inset(0 0 100% 0);transform:none}14%{clip-path:inset(55% 0 20% 0);transform:translate(4px,0)}24%{clip-path:inset(5% 0 80% 0);transform:translate(-3px,0)}34%{clip-path:inset(0 0 100% 0)}70%{clip-path:inset(20% 0 60% 0);transform:translate(3px,0)}74%{clip-path:inset(0 0 100% 0)}}
.sp-log{margin:22px 0 14px;min-height:6.4em;font:400 .92rem/1.6 "Share Tech Mono",ui-monospace,Consolas,monospace;color:#7CFFB2}
.sp-log div{white-space:nowrap;overflow:hidden;animation:spType .35s steps(24) both}
.sp-log b{color:#FCEE0A;font-weight:400}
@keyframes spType{from{width:0}to{width:100%}}
.sp-bar{height:3px;background:rgba(43,255,136,.15);overflow:hidden}
.sp-bar span{display:block;height:100%;width:0;background:linear-gradient(90deg,#2BFF88,#FCEE0A);box-shadow:0 0 12px #2BFF88;animation:spBar 1.7s cubic-bezier(.65,0,.35,1) .15s forwards}
@keyframes spBar{to{width:100%}}
.sp-skip{margin-top:12px;font:400 .75rem "Share Tech Mono",ui-monospace,monospace;letter-spacing:.1em;color:#55635A;text-transform:uppercase}
