From bedfe1aa02beda50d78f7a54c18d63ce93e4e79d Mon Sep 17 00:00:00 2001 From: thomashamburg Date: Fri, 31 Oct 2025 14:26:17 +0100 Subject: [PATCH] hateoas example1 --- hypermedia/1-example/datastar.js | 9 + hypermedia/1-example/datastar.js.map | 7 + hypermedia/1-example/deleted-record1.html | 1 + hypermedia/1-example/deleted-record2.html | 1 + hypermedia/1-example/deleted-record3.html | 1 + hypermedia/1-example/display-record1.html | 40 + hypermedia/1-example/display-record2.html | 40 + hypermedia/1-example/display-record3.html | 40 + hypermedia/1-example/edit-record1.html | 40 + hypermedia/1-example/edit-record2.html | 40 + hypermedia/1-example/edit-record3.html | 40 + hypermedia/1-example/index.html | 23 + hypermedia/1-example/pico.blue.css | 2802 +++++++++++++++ hypermedia/pico.blue.css | 2802 +++++++++++++++ lcars_v4/embed/create_state_db.sql | 32 + lcars_v4/embed/crew.json | 95 + lcars_v4/embed/messages.json | 1066 ++++++ lcars_v4/eventbus/eventbus.go | 310 ++ lcars_v4/experiments.go | 102 + lcars_v4/frontend/assets/Antonio-Bold.woff | Bin 0 -> 21984 bytes lcars_v4/frontend/assets/Antonio-Bold.woff2 | Bin 0 -> 16600 bytes lcars_v4/frontend/assets/Antonio-Regular.woff | Bin 0 -> 21844 bytes .../frontend/assets/Antonio-Regular.woff2 | Bin 0 -> 16440 bytes lcars_v4/frontend/assets/alert.png | Bin 0 -> 129738 bytes lcars_v4/frontend/assets/beep1.mp3 | Bin 0 -> 4641 bytes lcars_v4/frontend/assets/beep2.mp3 | Bin 0 -> 4641 bytes lcars_v4/frontend/assets/beep3.mp3 | Bin 0 -> 13857 bytes lcars_v4/frontend/assets/beep4.mp3 | Bin 0 -> 28449 bytes lcars_v4/frontend/assets/classic.css | 3011 +++++++++++++++++ lcars_v4/frontend/assets/lcars.js | 51 + lcars_v4/frontend/assets/lower-decks-padd.css | 1885 +++++++++++ lcars_v4/frontend/assets/lower-decks.css | 1856 ++++++++++ lcars_v4/frontend/assets/nemesis-blue.css | 2830 ++++++++++++++++ lcars_v4/frontend/crew/index.html | 231 ++ lcars_v4/frontend/index.html | 232 ++ lcars_v4/frontend/tinyserver.go | 39 + lcars_v4/go.mod | 18 + lcars_v4/go.sum | 49 + lcars_v4/interval/interval.go | 94 + lcars_v4/main.go | 221 ++ lcars_v4/notes.txt | 2 + lcars_v4/server/server.go | 105 + lcars_v4/server/taskengine.go | 118 + lcars_v4/sqlite/database.go | 440 +++ lcars_v4/state/events.go | 2 + 45 files changed, 18675 insertions(+) create mode 100644 hypermedia/1-example/datastar.js create mode 100644 hypermedia/1-example/datastar.js.map create mode 100644 hypermedia/1-example/deleted-record1.html create mode 100644 hypermedia/1-example/deleted-record2.html create mode 100644 hypermedia/1-example/deleted-record3.html create mode 100644 hypermedia/1-example/display-record1.html create mode 100644 hypermedia/1-example/display-record2.html create mode 100644 hypermedia/1-example/display-record3.html create mode 100644 hypermedia/1-example/edit-record1.html create mode 100644 hypermedia/1-example/edit-record2.html create mode 100644 hypermedia/1-example/edit-record3.html create mode 100644 hypermedia/1-example/index.html create mode 100644 hypermedia/1-example/pico.blue.css create mode 100644 hypermedia/pico.blue.css create mode 100644 lcars_v4/embed/create_state_db.sql create mode 100644 lcars_v4/embed/crew.json create mode 100644 lcars_v4/embed/messages.json create mode 100644 lcars_v4/eventbus/eventbus.go create mode 100644 lcars_v4/experiments.go create mode 100644 lcars_v4/frontend/assets/Antonio-Bold.woff create mode 100644 lcars_v4/frontend/assets/Antonio-Bold.woff2 create mode 100644 lcars_v4/frontend/assets/Antonio-Regular.woff create mode 100644 lcars_v4/frontend/assets/Antonio-Regular.woff2 create mode 100644 lcars_v4/frontend/assets/alert.png create mode 100644 lcars_v4/frontend/assets/beep1.mp3 create mode 100644 lcars_v4/frontend/assets/beep2.mp3 create mode 100644 lcars_v4/frontend/assets/beep3.mp3 create mode 100644 lcars_v4/frontend/assets/beep4.mp3 create mode 100644 lcars_v4/frontend/assets/classic.css create mode 100644 lcars_v4/frontend/assets/lcars.js create mode 100644 lcars_v4/frontend/assets/lower-decks-padd.css create mode 100644 lcars_v4/frontend/assets/lower-decks.css create mode 100644 lcars_v4/frontend/assets/nemesis-blue.css create mode 100644 lcars_v4/frontend/crew/index.html create mode 100644 lcars_v4/frontend/index.html create mode 100644 lcars_v4/frontend/tinyserver.go create mode 100644 lcars_v4/go.mod create mode 100644 lcars_v4/go.sum create mode 100644 lcars_v4/interval/interval.go create mode 100644 lcars_v4/main.go create mode 100644 lcars_v4/notes.txt create mode 100644 lcars_v4/server/server.go create mode 100644 lcars_v4/server/taskengine.go create mode 100644 lcars_v4/sqlite/database.go create mode 100644 lcars_v4/state/events.go diff --git a/hypermedia/1-example/datastar.js b/hypermedia/1-example/datastar.js new file mode 100644 index 0000000..be57e9d --- /dev/null +++ b/hypermedia/1-example/datastar.js @@ -0,0 +1,9 @@ +// Datastar v1.0.0-RC.6 +var nt=/🖕JS_DS🚀/.source,De=nt.slice(0,5),Ve=nt.slice(4),q="datastar-fetch",z="datastar-signal-patch";var de=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([a-z])([0-9]+)/gi,"$1-$2").replace(/([0-9]+)([a-z])/gi,"$1-$2").toLowerCase();var rt=e=>de(e).replace(/-/g,"_");var re=e=>{try{return JSON.parse(e)}catch{return Function(`return (${e})`)()}},st={camel:e=>e.replace(/-[a-z]/g,t=>t[1].toUpperCase()),snake:e=>e.replace(/-/g,"_"),pascal:e=>e[0].toUpperCase()+st.camel(e.slice(1))},R=(e,t,n="camel")=>{for(let r of t.get("case")||[n])e=st[r]?.(e)||e;return e},Q=e=>`data-${e}`;var _=Object.hasOwn??Object.prototype.hasOwnProperty.call;var se=e=>e!==null&&typeof e=="object"&&(Object.getPrototypeOf(e)===Object.prototype||Object.getPrototypeOf(e)===null),it=e=>{for(let t in e)if(_(e,t))return!1;return!0},Z=(e,t)=>{for(let n in e){let r=e[n];se(r)||Array.isArray(r)?Z(r,t):e[n]=t(r)}},Te=e=>{let t={};for(let[n,r]of e){let s=n.split("."),i=s.pop(),a=s.reduce((o,c)=>o[c]??={},t);a[i]=r}return t};var Ae=[],Ie=[],Fe=0,Re=0,$e=0,qe,G,we=0,w=()=>{Fe++},M=()=>{--Fe||(ct(),Y())},V=e=>{qe=G,G=e},I=()=>{G=qe,qe=void 0},me=e=>It.bind(0,{previousValue:e,t:e,e:1}),Ge=Symbol("computed"),Ne=e=>{let t=$t.bind(0,{e:17,getter:e});return t[Ge]=1,t},E=e=>{let t={d:e,e:2};G&&Be(t,G),V(t),w();try{t.d()}finally{M(),I()}return dt.bind(0,t)},ct=()=>{for(;Re<$e;){let e=Ie[Re];Ie[Re++]=void 0,ut(e,e.e&=-65)}Re=0,$e=0},ot=e=>"getter"in e?lt(e):ft(e,e.t),lt=e=>{V(e),mt(e);try{let t=e.t;return t!==(e.t=e.getter(t))}finally{I(),pt(e)}},ft=(e,t)=>(e.e=1,e.previousValue!==(e.previousValue=t)),je=e=>{let t=e.e;if(!(t&64)){e.e=t|64;let n=e.r;n?je(n.o):Ie[$e++]=e}},ut=(e,t)=>{if(t&16||t&32&>(e.s,e)){V(e),mt(e),w();try{e.d()}finally{M(),I(),pt(e)}return}t&32&&(e.e=t&-33);let n=e.s;for(;n;){let r=n.c,s=r.e;s&64&&ut(r,r.e=s&-65),n=n.i}},It=(e,...t)=>{if(t.length){if(e.t!==(e.t=t[0])){e.e=17;let r=e.r;return r&&(qt(r),Fe||ct()),!0}return!1}let n=e.t;if(e.e&16&&ft(e,n)){let r=e.r;r&&Le(r)}return G&&Be(e,G),n},$t=e=>{let t=e.e;if(t&16||t&32&>(e.s,e)){if(lt(e)){let n=e.r;n&&Le(n)}}else t&32&&(e.e=t&-33);return G&&Be(e,G),e.t},dt=e=>{let t=e.s;for(;t;)t=xe(t,e);let n=e.r;n&&xe(n),e.e=0},Be=(e,t)=>{let n=t.a;if(n&&n.c===e)return;let r=n?n.i:t.s;if(r&&r.c===e){r.m=we,t.a=r;return}let s=e.p;if(s&&s.m===we&&s.o===t)return;let i=t.a=e.p={m:we,c:e,o:t,l:n,i:r,f:s};r&&(r.l=i),n?n.i=i:t.s=i,s?s.n=i:e.r=i},xe=(e,t=e.o)=>{let n=e.c,r=e.l,s=e.i,i=e.n,a=e.f;if(s?s.l=r:t.a=r,r?r.i=s:t.s=s,i?i.f=a:n.p=a,a)a.n=i;else if(!(n.r=i))if("getter"in n){let o=n.s;if(o){n.e=17;do o=xe(o,n);while(o)}}else"previousValue"in n||dt(n);return s},qt=e=>{let t=e.n,n;e:for(;;){let r=e.o,s=r.e;if(s&60?s&12?s&4?!(s&48)&&Gt(e,r)?(r.e=s|40,s&=1):s=0:r.e=s&-9|32:s=0:r.e=s|32,s&2&&je(r),s&1){let i=r.r;if(i){let a=(e=i).n;a&&(n={t,u:n},t=a);continue}}if(e=t){t=e.n;continue}for(;n;)if(e=n.t,n=n.u,e){t=e.n;continue e}break}},mt=e=>{we++,e.a=void 0,e.e=e.e&-57|4},pt=e=>{let t=e.a,n=t?t.i:e.s;for(;n;)n=xe(n,e);e.e&=-5},gt=(e,t)=>{let n,r=0,s=!1;e:for(;;){let i=e.c,a=i.e;if(t.e&16)s=!0;else if((a&17)===17){if(ot(i)){let o=i.r;o.n&&Le(o),s=!0}}else if((a&33)===33){(e.n||e.f)&&(n={t:e,u:n}),e=i.s,t=i,++r;continue}if(!s){let o=e.i;if(o){e=o;continue}}for(;r--;){let o=t.r,c=o.n;if(c?(e=n.t,n=n.u):e=o,s){if(ot(t)){c&&Le(o),t=e.o;continue}s=!1}else t.e&=-33;if(t=e.o,e.i){e=e.i;continue e}}return s}},Le=e=>{do{let t=e.o,n=t.e;(n&48)===32&&(t.e=n|16,n&2&&je(t))}while(e=e.n)},Gt=(e,t)=>{let n=t.a;for(;n;){if(n===e)return!0;n=n.l}return!1},ie=e=>{let t=X,n=e.split(".");for(let r of n){if(t==null||!_(t,r))return;t=t[r]}return t},Me=(e,t="")=>{let n=Array.isArray(e);if(n||se(e)){let r=n?[]:{};for(let i in e)r[i]=me(Me(e[i],`${t+i}.`));let s=me(0);return new Proxy(r,{get(i,a){if(!(a==="toJSON"&&!_(r,a)))return n&&a in Array.prototype?(s(),r[a]):typeof a=="symbol"?r[a]:((!_(r,a)||r[a]()==null)&&(r[a]=me(""),Y(t+a,""),s(s()+1)),r[a]())},set(i,a,o){let c=t+a;if(n&&a==="length"){let l=r[a]-o;if(r[a]=o,l>0){let f={};for(let d=o;d{if(e!==void 0&&t!==void 0&&Ae.push([e,t]),!Fe&&Ae.length){let n=Te(Ae);Ae.length=0,document.dispatchEvent(new CustomEvent(z,{detail:n}))}},C=(e,{ifMissing:t}={})=>{w();for(let n in e)e[n]==null?t||delete X[n]:ht(e[n],n,X,"",t);M()},S=(e,t)=>C(Te(e),t),ht=(e,t,n,r,s)=>{if(se(e)){_(n,t)&&(se(n[t])||Array.isArray(n[t]))||(n[t]={});for(let i in e)e[i]==null?s||delete n[t][i]:ht(e[i],i,n[t],`${r+t}.`,s)}else s&&_(n,t)||(n[t]=e)},at=e=>typeof e=="string"?RegExp(e.replace(/^\/|\/$/g,"")):e,D=({include:e=/.*/,exclude:t=/(?!)/}={},n=X)=>{let r=at(e),s=at(t),i=[],a=[[n,""]];for(;a.length;){let[o,c]=a.pop();for(let l in o){let f=c+l;se(o[l])?a.push([o[l],`${f}.`]):r.test(f)&&!s.test(f)&&i.push([f,ie(f)])}}return Te(i)},X=Me({});var W=e=>e instanceof HTMLElement||e instanceof SVGElement||e instanceof MathMLElement;var jt="https://data-star.dev/errors",pe=(e,t,n={})=>{Object.assign(n,e);let r=new Error,s=rt(t),i=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),a=JSON.stringify(n,null,2);return r.message=`${t} +More info: ${jt}/${s}?${i} +Context: ${a}`,r},Oe=new Map,vt=new Map,bt=new Map,Et=new Proxy({},{get:(e,t)=>Oe.get(t)?.apply,has:(e,t)=>Oe.has(t),ownKeys:()=>Reflect.ownKeys(Oe),set:()=>!1,deleteProperty:()=>!1}),ge=new Map,Ce=[],We=new Set,p=e=>{Ce.push(e),Ce.length===1&&setTimeout(()=>{for(let t of Ce)We.add(t.name),vt.set(t.name,t);Ce.length=0,Jt(),We.clear()})},O=e=>{Oe.set(e.name,e)};document.addEventListener(q,e=>{let t=bt.get(e.detail.type);t&&t.apply({error:pe.bind(0,{plugin:{type:"watcher",name:t.name},element:{id:e.target.id,tag:e.target.tagName}})},e.detail.argsRaw)});var he=e=>{bt.set(e.name,e)},yt=e=>{for(let t of e){let n=ge.get(t);if(ge.delete(t)){for(let r of n.values())r();n.clear()}}},St=Q("ignore"),Bt=`[${St}]`,Tt=e=>e.hasAttribute(`${St}__self`)||!!e.closest(Bt),Pe=(e,t)=>{for(let n of e)if(!Tt(n))for(let r in n.dataset)At(n,r.replace(/[A-Z]/g,"-$&").toLowerCase(),n.dataset[r],t)},Wt=e=>{for(let{target:t,type:n,attributeName:r,addedNodes:s,removedNodes:i}of e)if(n==="childList"){for(let a of i)W(a)&&(yt([a]),yt(a.querySelectorAll("*")));for(let a of s)W(a)&&(Pe([a]),Pe(a.querySelectorAll("*")))}else if(n==="attributes"&&r.startsWith("data-")&&W(t)&&!Tt(t)){let a=r.slice(5),o=t.getAttribute(r);if(o===null){let c=ge.get(t);c&&(c.get(a)?.(),c.delete(a))}else At(t,a,o)}},Ut=new MutationObserver(Wt),Jt=(e=document.documentElement)=>{W(e)&&Pe([e],!0),Pe(e.querySelectorAll("*"),!0),Ut.observe(e,{subtree:!0,childList:!0,attributes:!0})},At=(e,t,n,r)=>{{let s=t,[i,...a]=s.split("__"),[o,c]=i.split(/:(.+)/),l=vt.get(o);if((!r||We.has(o))&&l){let f={el:e,rawKey:s,mods:new Map,error:pe.bind(0,{plugin:{type:"attribute",name:l.name},element:{id:e.id,tag:e.tagName},expression:{rawKey:s,key:c,value:n}}),key:c,value:n,rx:void 0},d=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.key)||"allowed",x=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.value)||"allowed";if(c){if(d==="denied")throw f.error("KeyNotAllowed")}else if(d==="must")throw f.error("KeyRequired");if(n){if(x==="denied")throw f.error("ValueNotAllowed")}else if(x==="must")throw f.error("ValueRequired");if(d==="exclusive"||x==="exclusive"){if(c&&n)throw f.error("KeyAndValueProvided");if(!c&&!n)throw f.error("KeyOrValueRequired")}if(n){let m;f.rx=(...h)=>(m||(m=Kt(n,{returnsValue:l.returnsValue,argNames:l.argNames})),m(e,...h))}for(let m of a){let[h,...v]=m.split(".");f.mods.set(h,new Set(v))}let u=l.apply(f);if(u){let m=ge.get(e);m?m.get(s)?.():(m=new Map,ge.set(e,m)),m.set(s,u)}}}},Kt=(e,{returnsValue:t=!1,argNames:n=[]}={})=>{let r="";if(t){let o=/(\/(\\\/|[^/])*\/|"(\\"|[^"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;){]*)\s*\)\s*\(\s*\)|[^;])+/gm,c=e.trim().match(o);if(c){let l=c.length-1,f=c[l].trim();f.startsWith("return")||(c[l]=`return (${f});`),r=c.join(`; +`)}}else r=e.trim();let s=new Map,i=RegExp(`(?:${De})(.*?)(?:${Ve})`,"gm"),a=0;for(let o of r.matchAll(i)){let c=o[1],l=`__escaped${a++}`;s.set(l,c),r=r.replace(De+c+Ve,l)}r=r.replace(/\$\['([a-zA-Z_$\d][\w$]*)'\]/g,"$$$1").replace(/\$([a-zA-Z_\d]\w*(?:[.-]\w+)*)/g,(o,c)=>c.split(".").reduce((l,f)=>`${l}['${f}']`,"$")).replace(/\[(\$[a-zA-Z_\d]\w*)\]/g,(o,c)=>`[$['${c.slice(1)}']]`),r=r.replaceAll(/@(\w+)\(/g,'__action("$1",evt,');for(let[o,c]of s)r=r.replace(o,c);try{let o=Function("el","$","__action","evt",...n,r);return(c,...l)=>{let f=(d,x,...u)=>{let m=pe.bind(0,{plugin:{type:"action",name:d},element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e}}),h=Et[d];if(h)return h({el:c,evt:x,error:m},...u);throw m("UndefinedAction")};try{return o(c,X,f,void 0,...l)}catch(d){throw console.error(d),pe({element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e},error:d.message},"ExecuteExpression")}}}catch(o){throw console.error(o),pe({expression:{fnContent:r,value:e},error:o.message},"GenerateExpression")}};var P=new Map,ae=new Set,oe=new Map,ye=new Set,ce=document.createElement("div");ce.hidden=!0;var ve=Q("ignore-morph"),zt=`[${ve}]`,Ke=(e,t,n="outer")=>{if(W(e)&&W(t)&&e.hasAttribute(ve)&&t.hasAttribute(ve)||e.parentElement?.closest(zt))return;let r=document.createElement("div");r.append(t),document.body.insertAdjacentElement("afterend",ce);let s=e.querySelectorAll("[id]");for(let{id:o,tagName:c}of s)oe.has(o)?ye.add(o):oe.set(o,c);e instanceof Element&&e.id&&(oe.has(e.id)?ye.add(e.id):oe.set(e.id,e.tagName)),ae.clear();let i=r.querySelectorAll("[id]");for(let{id:o,tagName:c}of i)ae.has(o)?ye.add(o):oe.get(o)===c&&ae.add(o);for(let o of ye)ae.delete(o);oe.clear(),ye.clear(),P.clear();let a=n==="outer"?e.parentElement:e;wt(a,s),wt(r,i),Mt(a,r,n==="outer"?e:null,e.nextSibling),ce.remove()},Mt=(e,t,n=null,r=null)=>{e instanceof HTMLTemplateElement&&t instanceof HTMLTemplateElement&&(e=e.content,t=t.content),n??=e.firstChild;for(let s of t.childNodes){if(n&&n!==r){let i=Qt(s,n,r);if(i){if(i!==n){let a=n;for(;a&&a!==i;){let o=a;a=a.nextSibling,Je(o)}}Ue(i,s),n=i.nextSibling;continue}}if(s instanceof Element&&ae.has(s.id)){let i=document.getElementById(s.id),a=i;for(;a=a.parentNode;){let o=P.get(a);o&&(o.delete(s.id),o.size||P.delete(a))}xt(e,i,n),Ue(i,s),n=i.nextSibling;continue}if(P.has(s)){let i=document.createElement(s.tagName);e.insertBefore(i,n),Ue(i,s),n=i.nextSibling}else{let i=document.importNode(s,!0);e.insertBefore(i,n),n=i.nextSibling}}for(;n&&n!==r;){let s=n;n=n.nextSibling,Je(s)}},Qt=(e,t,n)=>{let r=null,s=e.nextSibling,i=0,a=0,o=P.get(e)?.size||0,c=t;for(;c&&c!==n;){if(Rt(c,e)){let l=!1,f=P.get(c),d=P.get(e);if(d&&f){for(let x of f)if(d.has(x)){l=!0;break}}if(l)return c;if(!r&&!P.has(c)){if(!o)return c;r=c}}if(a+=P.get(c)?.size||0,a>o)break;r===null&&s&&Rt(c,s)&&(i++,s=s.nextSibling,i>=2&&(r=void 0)),c=c.nextSibling}return r||null},Rt=(e,t)=>e.nodeType===t.nodeType&&e.tagName===t.tagName&&(!e.id||e.id===t.id),Je=e=>{P.has(e)?xt(ce,e,null):e.parentNode?.removeChild(e)},xt=Je.call.bind(ce.moveBefore??ce.insertBefore),Zt=Q("preserve-attr"),Ue=(e,t)=>{let n=t.nodeType;if(n===1){let r=e,s=t;if(r.hasAttribute(ve)&&s.hasAttribute(ve))return e;r instanceof HTMLInputElement&&s instanceof HTMLInputElement&&s.type!=="file"?s.getAttribute("value")!==r.getAttribute("value")&&(r.value=s.getAttribute("value")??""):r instanceof HTMLTextAreaElement&&s instanceof HTMLTextAreaElement&&(s.value!==r.value&&(r.value=s.value),r.firstChild&&r.firstChild.nodeValue!==s.value&&(r.firstChild.nodeValue=s.value));let i=(t.getAttribute(Zt)??"").split(" ");for(let{name:a,value:o}of s.attributes)r.getAttribute(a)!==o&&!i.includes(a)&&r.setAttribute(a,o);for(let a=r.attributes.length-1;a>=0;a--){let{name:o}=r.attributes[a];!s.hasAttribute(o)&&!i.includes(o)&&r.removeAttribute(o)}r.isEqualNode(s)||Mt(r,s)}return(n===8||n===3)&&e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e},wt=(e,t)=>{for(let n of t)if(ae.has(n.id)){let r=n;for(;r&&r!==e;){let s=P.get(r);s||(s=new Set,P.set(r,s)),s.add(n.id),r=r.parentElement}}};O({name:"peek",apply(e,t){V();try{return t()}finally{I()}}});O({name:"setAll",apply(e,t,n){V();let r=D(n);Z(r,()=>t),C(r),I()}});O({name:"toggleAll",apply(e,t){V();let n=D(t);Z(n,r=>!r),C(n),I()}});var He=new WeakMap,be=(e,t)=>O({name:e,apply:async({el:n,evt:r,error:s},i,{selector:a,headers:o,contentType:c="json",filterSignals:{include:l=/.*/,exclude:f=/(^|\.)_/}={},openWhenHidden:d=!1,retryInterval:x=1e3,retryScaler:u=2,retryMaxWaitMs:m=3e4,retryMaxCount:h=10,requestCancellation:v="auto"}={})=>{let L=v instanceof AbortController?v:new AbortController,A=v==="disabled";if(!A){let T=He.get(n);T&&(T.abort(),await Promise.resolve())}!A&&!(v instanceof AbortController)&&He.set(n,L);try{let T=new MutationObserver(j=>{for(let H of j)for(let B of H.removedNodes)B===n&&(L.abort(),K())});n.parentNode&&T.observe(n.parentNode,{childList:!0});let K=()=>{T.disconnect()};try{if(!i?.length)throw s("FetchNoUrlProvided",{action:O});let j={Accept:"text/event-stream, text/html, application/json","Datastar-Request":!0};c==="json"&&(j["Content-Type"]="application/json");let H=Object.assign({},j,o),B={method:t,headers:H,openWhenHidden:d,retryInterval:x,retryScaler:u,retryMaxWaitMs:m,retryMaxCount:h,signal:L.signal,onopen:async g=>{g.status>=400&&ee(Yt,n,{status:g.status.toString()})},onmessage:g=>{if(!g.event.startsWith("datastar"))return;let $=g.event,b={};for(let N of g.data.split(` +`)){let y=N.indexOf(" "),k=N.slice(0,y),ue=N.slice(y+1);(b[k]||=[]).push(ue)}let F=Object.fromEntries(Object.entries(b).map(([N,y])=>[N,y.join(` +`)]));ee($,n,F)},onerror:g=>{if(Lt(g))throw g("FetchExpectedTextEventStream",{url:i});g&&(console.error(g.message),ee(Xt,n,{message:g.message}))}},fe=new URL(i,document.baseURI),ne=new URLSearchParams(fe.search);if(c==="json"){let g=JSON.stringify(D({include:l,exclude:f}));t==="GET"?ne.set("datastar",g):B.body=g}else if(c==="form"){let g=a?document.querySelector(a):n.closest("form");if(!g)throw s("FetchFormNotFound",{action:O,selector:a});if(!g.checkValidity()){g.reportValidity(),K();return}let $=new FormData(g),b=n;if(n===g&&r instanceof SubmitEvent)b=r.submitter;else{let y=k=>k.preventDefault();g.addEventListener("submit",y),K=()=>{g.removeEventListener("submit",y),T.disconnect()}}if(b instanceof HTMLButtonElement){let y=b.getAttribute("name");y&&$.append(y,b.value)}let F=g.getAttribute("enctype")==="multipart/form-data";F||(H["Content-Type"]="application/x-www-form-urlencoded");let N=new URLSearchParams($);if(t==="GET")for(let[y,k]of N)ne.append(y,k);else F?B.body=$:B.body=N}else throw s("FetchInvalidContentType",{action:O,contentType:c});ee(ze,n,{}),fe.search=ne.toString();try{await on(fe.toString(),n,B)}catch(g){if(!Lt(g))throw s("FetchFailed",{method:t,url:i,error:g.message})}}finally{ee(Qe,n,{}),K()}}finally{He.get(n)===L&&He.delete(n)}}});be("delete","DELETE");be("get","GET");be("patch","PATCH");be("post","POST");be("put","PUT");var ze="started",Qe="finished",Yt="error",Xt="retrying",en="retries-failed",ee=(e,t,n)=>document.dispatchEvent(new CustomEvent(q,{detail:{type:e,el:t,argsRaw:n}})),Lt=e=>`${e}`.includes("text/event-stream"),tn=async(e,t)=>{let n=e.getReader(),r=await n.read();for(;!r.done;)t(r.value),r=await n.read()},nn=e=>{let t,n,r,s=!1;return i=>{t?t=sn(t,i):(t=i,n=0,r=-1);let a=t.length,o=0;for(;n{let r=Ft(),s=new TextDecoder;return(i,a)=>{if(!i.length)n?.(r),r=Ft();else if(a>0){let o=s.decode(i.subarray(0,a)),c=a+(i[a+1]===32?2:1),l=s.decode(i.subarray(c));switch(o){case"data":r.data=r.data?`${r.data} +${l}`:l;break;case"event":r.event=l;break;case"id":e(r.id=l);break;case"retry":{let f=+l;Number.isNaN(f)||t(r.retry=f);break}}}}},sn=(e,t)=>{let n=new Uint8Array(e.length+t.length);return n.set(e),n.set(t,e.length),n},Ft=()=>({data:"",event:"",id:"",retry:void 0}),on=(e,t,{signal:n,headers:r,onopen:s,onmessage:i,onclose:a,onerror:o,openWhenHidden:c,fetch:l,retryInterval:f=1e3,retryScaler:d=2,retryMaxWaitMs:x=3e4,retryMaxCount:u=10,overrides:m,...h})=>new Promise((v,L)=>{let A={...r},T,K=()=>{T.abort(),document.hidden||$()};c||document.addEventListener("visibilitychange",K);let j=0,H=()=>{document.removeEventListener("visibilitychange",K),clearTimeout(j),T.abort()};n?.addEventListener("abort",()=>{H(),v()});let B=l||window.fetch,fe=s||(()=>{}),ne=0,g=f,$=async()=>{T=new AbortController;try{let b=await B(e,{...h,headers:A,signal:T.signal});ne=0,f=g,await fe(b);let F=async(y,k,ue,Ee,...Vt)=>{let tt={[ue]:await k.text()};for(let ke of Vt){let _e=k.headers.get(`datastar-${de(ke)}`);if(Ee){let Se=Ee[ke];Se&&(_e=typeof Se=="string"?Se:JSON.stringify(Se))}_e&&(tt[ke]=_e)}ee(y,t,tt),H(),v()},N=b.headers.get("Content-Type");if(N?.includes("text/html"))return await F("datastar-patch-elements",b,"elements",m,"selector","mode","useViewTransition");if(N?.includes("application/json"))return await F("datastar-patch-signals",b,"signals",m,"onlyIfMissing");if(N?.includes("text/javascript")){let y=document.createElement("script"),k=b.headers.get("datastar-script-attributes");if(k)for(let[ue,Ee]of Object.entries(JSON.parse(k)))y.setAttribute(ue,Ee);y.textContent=await b.text(),document.head.appendChild(y),H();return}await tn(b.body,nn(rn(y=>{y?A["last-event-id"]=y:delete A["last-event-id"]},y=>{g=f=y},i))),a?.(),H(),v()}catch(b){if(!T.signal.aborted)try{let F=o?.(b)||f;clearTimeout(j),j=setTimeout($,F),f=Math.min(f*d,x),++ne>=u?(ee(en,t,{}),H(),L("Max retries reached.")):console.error(`Datastar failed to reach ${e.toString()} retrying in ${F}ms.`)}catch(F){H(),L(F)}}};$()});p({name:"attr",requirement:{value:"must"},returnsValue:!0,apply({el:e,key:t,rx:n}){let r=(o,c)=>{c===""||c===!0?e.setAttribute(o,""):c===!1||c==null?e.removeAttribute(o):typeof c=="string"?e.setAttribute(o,c):e.setAttribute(o,JSON.stringify(c))},s=t?()=>{i.disconnect();let o=n();r(t,o),i.observe(e,{attributeFilter:[t]})}:()=>{i.disconnect();let o=n(),c=Object.keys(o);for(let l of c)r(l,o[l]);i.observe(e,{attributeFilter:c})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a()}}});var an=/^data:(?[^;]+);base64,(?.*)$/,Nt=Symbol("empty"),Ct=Q("bind");p({name:"bind",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r,error:s}){let i=t!=null?R(t,n):r,a=(u,m)=>m==="number"?+u.value:u.value,o=u=>{e.value=`${u}`};if(e instanceof HTMLInputElement)switch(e.type){case"range":case"number":a=(u,m)=>m==="string"?u.value:+u.value;break;case"checkbox":a=(u,m)=>u.value!=="on"?m==="boolean"?u.checked:u.checked?u.value:"":m==="string"?u.checked?u.value:"":u.checked,o=u=>{e.checked=typeof u=="string"?u===e.value:u};break;case"radio":e.getAttribute("name")?.length||e.setAttribute("name",i),a=(u,m)=>u.checked?m==="number"?+u.value:u.value:Nt,o=u=>{e.checked=u===(typeof u=="number"?+e.value:e.value)};break;case"file":{let u=()=>{let m=[...e.files||[]],h=[];Promise.all(m.map(v=>new Promise(L=>{let A=new FileReader;A.onload=()=>{if(typeof A.result!="string")throw s("InvalidFileResultType",{resultType:typeof A.result});let T=A.result.match(an);if(!T?.groups)throw s("InvalidDataUri",{result:A.result});h.push({name:v.name,contents:T.groups.contents,mime:T.groups.mime})},A.onloadend=()=>L(),A.readAsDataURL(v)}))).then(()=>{S([[i,h]])})};return e.addEventListener("change",u),e.addEventListener("input",u),()=>{e.removeEventListener("change",u),e.removeEventListener("input",u)}}}else if(e instanceof HTMLSelectElement){if(e.multiple){let u=new Map;a=m=>[...m.selectedOptions].map(h=>{let v=u.get(h.value);return v==="string"||v==null?h.value:+h.value}),o=m=>{for(let h of e.options)m.includes(h.value)?(u.set(h.value,"string"),h.selected=!0):m.includes(+h.value)?(u.set(h.value,"number"),h.selected=!0):h.selected=!1}}}else e instanceof HTMLTextAreaElement||(a=u=>"value"in u?u.value:u.getAttribute("value"),o=u=>{"value"in e?e.value=u:e.setAttribute("value",u)});let c=ie(i),l=typeof c,f=i;if(Array.isArray(c)&&!(e instanceof HTMLSelectElement&&e.multiple)){let u=t||r,m=document.querySelectorAll(`[${Ct}\\:${CSS.escape(u)}],[${Ct}="${CSS.escape(u)}"]`),h=[],v=0;for(let L of m){if(h.push([`${f}.${v}`,a(L,"none")]),e===L)break;v++}S(h,{ifMissing:!0}),f=`${f}.${v}`}else S([[f,a(e,l)]],{ifMissing:!0});let d=()=>{let u=ie(f);if(u!=null){let m=a(e,typeof u);m!==Nt&&S([[f,m]])}};e.addEventListener("input",d),e.addEventListener("change",d);let x=E(()=>{o(ie(f))});return()=>{x(),e.removeEventListener("input",d),e.removeEventListener("change",d)}}});p({name:"class",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,mods:n,rx:r}){e&&(e=R(e,n,"kebab"));let s=()=>{i.disconnect();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);if(o[c])for(let f of l)t.classList.contains(f)||t.classList.add(f);else for(let f of l)t.classList.contains(f)&&t.classList.remove(f)}i.observe(t,{attributeFilter:["class"]})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);for(let f of l)t.classList.remove(f)}}}});p({name:"computed",requirement:{value:"must"},returnsValue:!0,apply({key:e,mods:t,rx:n,error:r}){if(e)S([[R(e,t),Ne(n)]]);else{let s=Object.assign({},n());Z(s,i=>{if(typeof i=="function")return Ne(i);throw r("ComputedExpectedFunction")}),C(s)}}});p({name:"effect",requirement:{key:"denied",value:"must"},apply:({rx:e})=>E(e)});p({name:"indicator",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,!1]]);let i=a=>{let{type:o,el:c}=a.detail;if(c===e)switch(o){case ze:S([[s,!0]]);break;case Qe:S([[s,!1]]);break}};return document.addEventListener(q,i),()=>{S([[s,!1]]),document.removeEventListener(q,i)}}});p({name:"json-signals",requirement:{key:"denied"},apply({el:e,value:t,mods:n}){let r=n.has("terse")?0:2,s={};t&&(s=re(t));let i=()=>{a.disconnect(),e.textContent=JSON.stringify(D(s),null,r),a.observe(e,{childList:!0,characterData:!0,subtree:!0})},a=new MutationObserver(i),o=E(i);return()=>{a.disconnect(),o()}}});var U=e=>{if(!e||e.size<=0)return 0;for(let t of e){if(t.endsWith("ms"))return+t.replace("ms","");if(t.endsWith("s"))return+t.replace("s","")*1e3;try{return Number.parseFloat(t)}catch{}}return 0},te=(e,t,n=!1)=>e?e.has(t.toLowerCase()):n;var Ze=(e,t)=>(...n)=>{setTimeout(()=>{e(...n)},t)},cn=(e,t,n=!1,r=!0)=>{let s=0;return(...i)=>{s&&clearTimeout(s),n&&!s&&e(...i),s=setTimeout(()=>{r&&e(...i),s&&clearTimeout(s),s=0},t)}},ln=(e,t,n=!0,r=!1)=>{let s=!1;return(...i)=>{s||(n&&e(...i),s=!0,setTimeout(()=>{r&&e(...i),s=!1},t))}},le=(e,t)=>{let n=t.get("delay");if(n){let i=U(n);e=Ze(e,i)}let r=t.get("debounce");if(r){let i=U(r),a=te(r,"leading",!1),o=!te(r,"notrailing",!1);e=cn(e,i,a,o)}let s=t.get("throttle");if(s){let i=U(s),a=!te(s,"noleading",!1),o=te(s,"trailing",!1);e=ln(e,i,a,o)}return e};var Ye=!!document.startViewTransition,J=(e,t)=>{if(t.has("viewtransition")&&Ye){let n=e;e=(...r)=>document.startViewTransition(()=>n(...r))}return e};p({name:"on",requirement:"must",argNames:["evt"],apply({el:e,key:t,mods:n,rx:r}){let s=e;n.has("window")&&(s=window);let i=c=>{c&&(n.has("prevent")&&c.preventDefault(),n.has("stop")&&c.stopPropagation()),w(),r(c),M()};i=J(i,n),i=le(i,n);let a={capture:n.has("capture"),passive:n.has("passive"),once:n.has("once")};if(n.has("outside")){s=document;let c=i;i=l=>{e.contains(l?.target)||c(l)}}let o=R(t,n,"kebab");if((o===q||o===z)&&(s=document),e instanceof HTMLFormElement&&o==="submit"){let c=i;i=l=>{l?.preventDefault(),c(l)}}return s.addEventListener(o,i,a),()=>{s.removeEventListener(o,i)}}});var Xe=new WeakSet;p({name:"on-intersect",requirement:{key:"denied",value:"must"},apply({el:e,mods:t,rx:n}){let r=()=>{w(),n(),M()};r=J(r,t),r=le(r,t);let s={threshold:0};t.has("full")?s.threshold=1:t.has("half")&&(s.threshold=.5);let i=new IntersectionObserver(a=>{for(let o of a)o.isIntersecting&&(r(),i&&Xe.has(e)&&i.disconnect())},s);return i.observe(e),t.has("once")&&Xe.add(e),()=>{t.has("once")||Xe.delete(e),i&&(i.disconnect(),i=null)}}});p({name:"on-interval",requirement:{key:"denied",value:"must"},apply({mods:e,rx:t}){let n=()=>{w(),t(),M()};n=J(n,e);let r=1e3,s=e.get("duration");s&&(r=U(s),te(s,"leading",!1)&&n());let i=setInterval(n,r);return()=>{clearInterval(i)}}});p({name:"init",requirement:{key:"denied",value:"must"},apply({rx:e,mods:t}){let n=()=>{w(),e(),M()};n=J(n,t);let r=0,s=t.get("delay");s&&(r=U(s),r>0&&(n=Ze(n,r))),n()}});p({name:"on-signal-patch",requirement:{value:"must"},argNames:["patch"],returnsValue:!0,apply({el:e,key:t,mods:n,rx:r,error:s}){if(t&&t!=="filter")throw s("KeyNotAllowed");let i=e.getAttribute("data-on-signal-patch-filter"),a={};i&&(a=re(i));let o=le(c=>{let l=D(a,c.detail);it(l)||(w(),r(l),M())},n);return document.addEventListener(z,o),()=>{document.removeEventListener(z,o)}}});p({name:"ref",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,e]])}});var Ot="none",Pt="display";p({name:"show",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),t()?e.style.display===Ot&&e.style.removeProperty(Pt):e.style.setProperty(Pt,Ot),r.observe(e,{attributeFilter:["style"]})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});p({name:"signals",returnsValue:!0,apply({key:e,mods:t,rx:n}){let r=t.has("ifmissing");if(e)e=R(e,t),S([[e,n?.()]],{ifMissing:r});else{let s=Object.assign({},n?.());C(s,{ifMissing:r})}}});p({name:"style",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,rx:n}){let{style:r}=t,s=new Map,i=(l,f)=>{let d=s.get(l);!f&&f!==0?d!==void 0&&(d?r.setProperty(l,d):r.removeProperty(l)):(d===void 0&&s.set(l,r.getPropertyValue(l)),r.setProperty(l,String(f)))},a=()=>{if(o.disconnect(),e)i(e,n());else{let l=n();for(let[f,d]of s)f in l||(d?r.setProperty(f,d):r.removeProperty(f));for(let f in l)i(de(f),l[f])}o.observe(t,{attributeFilter:["style"]})},o=new MutationObserver(a),c=E(a);return()=>{o.disconnect(),c();for(let[l,f]of s)f?r.setProperty(l,f):r.removeProperty(l)}}});p({name:"text",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),e.textContent=`${t()}`,r.observe(e,{childList:!0,characterData:!0,subtree:!0})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});he({name:"datastar-patch-elements",apply(e,{elements:t="",selector:n="",mode:r="outer",useViewTransition:s}){switch(r){case"remove":case"outer":case"inner":case"replace":case"prepend":case"append":case"before":case"after":break;default:throw e.error("PatchElementsInvalidMode",{mode:r})}if(!n&&r!=="outer"&&r!=="replace")throw e.error("PatchElementsExpectedSelector");let i={mode:r,selector:n,elements:t,useViewTransition:s?.trim()==="true"};Ye&&s?document.startViewTransition(()=>Ht(e,i)):Ht(e,i)}});var Ht=({error:e},{elements:t,selector:n,mode:r})=>{let s=t.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,""),i=/<\/html>/.test(s),a=/<\/head>/.test(s),o=/<\/body>/.test(s),c=new DOMParser().parseFromString(i||a||o?t:``,"text/html"),l=document.createDocumentFragment();if(i?l.appendChild(c.documentElement):a&&o?(l.appendChild(c.head),l.appendChild(c.body)):a?l.appendChild(c.head):o?l.appendChild(c.body):l=c.querySelector("template").content,!n&&(r==="outer"||r==="replace"))for(let f of l.children){let d;if(f instanceof HTMLHtmlElement)d=document.documentElement;else if(f instanceof HTMLBodyElement)d=document.body;else if(f instanceof HTMLHeadElement)d=document.head;else if(d=document.getElementById(f.id),!d){console.warn(e("PatchElementsNoTargetsFound"),{element:{id:f.id}});continue}_t(r,f,[d])}else{let f=document.querySelectorAll(n);if(!f.length){console.warn(e("PatchElementsNoTargetsFound"),{selector:n});return}_t(r,l,f)}},et=new WeakSet;for(let e of document.querySelectorAll("script"))et.add(e);var Dt=e=>{let t=e instanceof HTMLScriptElement?[e]:e.querySelectorAll("script");for(let n of t)if(!et.has(n)){let r=document.createElement("script");for(let{name:s,value:i}of n.attributes)r.setAttribute(s,i);r.text=n.text,n.replaceWith(r),et.add(r)}},kt=(e,t,n)=>{for(let r of e){let s=t.cloneNode(!0);Dt(s),r[n](s)}},_t=(e,t,n)=>{switch(e){case"remove":for(let r of n)r.remove();break;case"outer":case"inner":for(let r of n)Ke(r,t.cloneNode(!0),e),Dt(r);break;case"replace":kt(n,t,"replaceWith");break;case"prepend":case"append":case"before":case"after":kt(n,t,e)}};he({name:"datastar-patch-signals",apply({error:e},{signals:t,onlyIfMissing:n}){if(t){let r=n?.trim()==="true";C(re(t),{ifMissing:r})}else throw e("PatchSignalsExpectedSignals")}});export{O as action,Et as actions,p as attribute,w as beginBatch,Ne as computed,E as effect,M as endBatch,D as filtered,ie as getPath,C as mergePatch,S as mergePaths,Ke as morph,X as root,me as signal,V as startPeeking,I as stopPeeking,he as watcher}; +//# sourceMappingURL=datastar.js.map diff --git a/hypermedia/1-example/datastar.js.map b/hypermedia/1-example/datastar.js.map new file mode 100644 index 0000000..f82819f --- /dev/null +++ b/hypermedia/1-example/datastar.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../library/src/engine/consts.ts", "../library/src/utils/text.ts", "../library/src/utils/polyfills.ts", "../library/src/utils/paths.ts", "../library/src/engine/signals.ts", "../library/src/utils/dom.ts", "../library/src/engine/engine.ts", "../library/src/engine/morph.ts", "../library/src/plugins/actions/peek.ts", "../library/src/plugins/actions/setAll.ts", "../library/src/plugins/actions/toggleAll.ts", "../library/src/plugins/actions/fetch.ts", "../library/src/plugins/attributes/attr.ts", "../library/src/plugins/attributes/bind.ts", "../library/src/plugins/attributes/class.ts", "../library/src/plugins/attributes/computed.ts", "../library/src/plugins/attributes/effect.ts", "../library/src/plugins/attributes/indicator.ts", "../library/src/plugins/attributes/jsonSignals.ts", "../library/src/utils/tags.ts", "../library/src/utils/timing.ts", "../library/src/utils/view-transitions.ts", "../library/src/plugins/attributes/on.ts", "../library/src/plugins/attributes/onIntersect.ts", "../library/src/plugins/attributes/onInterval.ts", "../library/src/plugins/attributes/init.ts", "../library/src/plugins/attributes/onSignalPatch.ts", "../library/src/plugins/attributes/ref.ts", "../library/src/plugins/attributes/show.ts", "../library/src/plugins/attributes/signals.ts", "../library/src/plugins/attributes/style.ts", "../library/src/plugins/attributes/text.ts", "../library/src/plugins/watchers/patchElements.ts", "../library/src/plugins/watchers/patchSignals.ts"], + "sourcesContent": ["const lol = /\uD83D\uDD95JS_DS\uD83D\uDE80/.source\nexport const DSP = lol.slice(0, 5)\nexport const DSS = lol.slice(4)\nexport const DATASTAR_FETCH_EVENT = 'datastar-fetch'\nexport const DATASTAR_SIGNAL_PATCH_EVENT = 'datastar-signal-patch'\n", "import type { Modifiers } from '@engine/types'\n\nexport const kebab = (str: string): string =>\n str\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([a-z])([0-9]+)/gi, '$1-$2')\n .replace(/([0-9]+)([a-z])/gi, '$1-$2')\n .toLowerCase()\n\nexport const camel = (str: string): string =>\n kebab(str).replace(/-./g, (x) => x[1].toUpperCase())\n\nexport const snake = (str: string): string => kebab(str).replace(/-/g, '_')\n\nexport const pascal = (str: string): string =>\n camel(str).replace(/(^.|(?<=\\.).)/g, (x) => x[0].toUpperCase())\n\nexport const jsStrToObject = (raw: string) => {\n try {\n return JSON.parse(raw)\n } catch {\n // If JSON parsing fails, try to evaluate as a JavaScript object\n // This is less safe and should be used with caution\n return Function(`return (${raw})`)()\n }\n}\n\nconst caseFns: Record string> = {\n camel: (str) => str.replace(/-[a-z]/g, (x) => x[1].toUpperCase()),\n snake: (str) => str.replace(/-/g, '_'),\n pascal: (str) => str[0].toUpperCase() + caseFns.camel(str.slice(1)),\n}\n\nexport const modifyCasing = (\n str: string,\n mods: Modifiers,\n defaultCase = 'camel',\n): string => {\n for (const c of mods.get('case') || [defaultCase]) {\n str = caseFns[c]?.(str) || str\n }\n return str\n}\n\nexport const aliasify = (name: string) =>\n ALIAS ? `data-${ALIAS}-${name}` : `data-${name}`\n", "export const hasOwn: (obj: object, prop: PropertyKey) => boolean =\n // @ts-expect-error\n Object.hasOwn ?? Object.prototype.hasOwnProperty.call\n", "import type { Paths } from '@engine/types'\nimport { hasOwn } from '@utils/polyfills'\n\nexport const isPojo = (obj: any): obj is Record =>\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n\nexport const isEmpty = (obj: Record): boolean => {\n for (const prop in obj) {\n if (hasOwn(obj, prop)) {\n return false\n }\n }\n return true\n}\n\nexport const updateLeaves = (\n obj: Record,\n fn: (oldValue: any) => any,\n) => {\n for (const key in obj) {\n const val = obj[key]\n if (isPojo(val) || Array.isArray(val)) {\n updateLeaves(val, fn)\n } else {\n obj[key] = fn(val)\n }\n }\n}\n\nexport const pathToObj = (paths: Paths): Record => {\n const result: Record = {}\n for (const [path, value] of paths) {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const obj = keys.reduce((acc, key) => (acc[key] ??= {}), result)\n obj[lastKey] = value\n }\n return result\n}\n", "import { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport type {\n Computed,\n Effect,\n JSONPatch,\n MergePatchArgs,\n Paths,\n Signal,\n SignalFilterOptions,\n} from '@engine/types'\nimport { isPojo, pathToObj } from '@utils/paths'\nimport { hasOwn } from '@utils/polyfills'\n\ninterface ReactiveNode {\n deps_?: Link\n depsTail_?: Link\n subs_?: Link\n subsTail_?: Link\n flags_: ReactiveFlags\n}\n\ninterface Link {\n version_: number\n dep_: ReactiveNode\n sub_: ReactiveNode\n prevSub_?: Link\n nextSub_?: Link\n prevDep_?: Link\n nextDep_?: Link\n}\n\ninterface Stack {\n value_: T\n prev_?: Stack\n}\n\nenum ReactiveFlags {\n None = 0,\n Mutable = 1 << 0,\n Watching = 1 << 1,\n RecursedCheck = 1 << 2,\n Recursed = 1 << 3,\n Dirty = 1 << 4,\n Pending = 1 << 5,\n}\n\nenum EffectFlags {\n Queued = 1 << 6,\n}\n\ninterface AlienEffect extends ReactiveNode {\n fn_(): void\n}\n\ninterface AlienComputed extends ReactiveNode {\n value_?: T\n getter(previousValue?: T): T\n}\n\ninterface AlienSignal extends ReactiveNode {\n previousValue: T\n value_: T\n}\n\nconst currentPatch: Paths = []\nconst queuedEffects: (AlienEffect | undefined)[] = []\nlet batchDepth = 0\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet prevSub: ReactiveNode | undefined\nlet activeSub: ReactiveNode | undefined\nlet version = 0\n\nexport const beginBatch = (): void => {\n batchDepth++\n}\n\nexport const endBatch = (): void => {\n if (!--batchDepth) {\n flush()\n dispatch()\n }\n}\n\nexport const startPeeking = (sub?: ReactiveNode): void => {\n prevSub = activeSub\n activeSub = sub\n}\n\nexport const stopPeeking = (): void => {\n activeSub = prevSub\n prevSub = undefined\n}\n\nexport const signal = (initialValue?: T): Signal => {\n return signalOper.bind(0, {\n previousValue: initialValue,\n value_: initialValue,\n flags_: 1 satisfies ReactiveFlags.Mutable,\n }) as Signal\n}\n\nconst computedSymbol = Symbol('computed')\nexport const computed = (getter: (previousValue?: T) => T): Computed => {\n const c = computedOper.bind(0, {\n flags_: 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty,\n getter,\n }) as Computed\n // @ts-expect-error\n c[computedSymbol] = 1\n return c\n}\n\nexport const effect = (fn: () => void): Effect => {\n const e: AlienEffect = {\n fn_: fn,\n flags_: 2 satisfies ReactiveFlags.Watching,\n }\n if (activeSub) {\n link(e, activeSub)\n }\n startPeeking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n }\n return effectOper.bind(0, e)\n}\n\nconst flush = () => {\n while (notifyIndex < queuedEffectsLength) {\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n run(effect, (effect.flags_ &= ~EffectFlags.Queued))\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\nconst update = (signal: AlienSignal | AlienComputed): boolean => {\n if ('getter' in signal) {\n return updateComputed(signal)\n }\n return updateSignal(signal, signal.value_)\n}\n\nconst updateComputed = (c: AlienComputed): boolean => {\n startPeeking(c)\n startTracking(c)\n try {\n const oldValue = c.value_\n return oldValue !== (c.value_ = c.getter(oldValue))\n } finally {\n stopPeeking()\n endTracking(c)\n }\n}\n\nconst updateSignal = (s: AlienSignal, value: T): boolean => {\n s.flags_ = 1 satisfies ReactiveFlags.Mutable\n return s.previousValue !== (s.previousValue = value)\n}\n\nconst notify = (e: AlienEffect): void => {\n const flags = e.flags_\n if (!(flags & EffectFlags.Queued)) {\n e.flags_ = flags | EffectFlags.Queued\n const subs = e.subs_\n if (subs) {\n notify(subs.sub_ as AlienEffect)\n } else {\n queuedEffects[queuedEffectsLength++] = e\n }\n }\n}\n\nconst run = (e: AlienEffect, flags: ReactiveFlags): void => {\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(e.deps_!, e))\n ) {\n startPeeking(e)\n startTracking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n endTracking(e)\n }\n return\n }\n if (flags & (32 satisfies ReactiveFlags.Pending)) {\n e.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n let link = e.deps_\n while (link) {\n const dep = link.dep_\n const depFlags = dep.flags_\n if (depFlags & EffectFlags.Queued) {\n run(dep as AlienEffect, (dep.flags_ = depFlags & ~EffectFlags.Queued))\n }\n link = link.nextDep_\n }\n}\n\nconst signalOper = (s: AlienSignal, ...value: [T]): T | boolean => {\n if (value.length) {\n if (s.value_ !== (s.value_ = value[0])) {\n s.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n const subs = s.subs_\n if (subs) {\n propagate(subs)\n if (!batchDepth) {\n flush()\n }\n }\n return true\n }\n return false\n }\n const currentValue = s.value_\n if (s.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n if (updateSignal(s, currentValue)) {\n const subs_ = s.subs_\n if (subs_) {\n shallowPropagate(subs_)\n }\n }\n }\n if (activeSub) {\n link(s, activeSub)\n }\n return currentValue\n}\n\nconst computedOper = (c: AlienComputed): T => {\n const flags = c.flags_\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(c.deps_!, c))\n ) {\n if (updateComputed(c)) {\n const subs = c.subs_\n if (subs) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & (32 satisfies ReactiveFlags.Pending)) {\n c.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n if (activeSub) {\n link(c, activeSub)\n }\n return c.value_!\n}\n\nconst effectOper = (e: AlienEffect): void => {\n let dep = e.deps_\n while (dep) {\n dep = unlink(dep, e)\n }\n const sub = e.subs_\n if (sub) {\n unlink(sub)\n }\n e.flags_ = 0 satisfies ReactiveFlags.None\n}\n\nconst link = (dep: ReactiveNode, sub: ReactiveNode): void => {\n const prevDep = sub.depsTail_\n if (prevDep && prevDep.dep_ === dep) {\n return\n }\n const nextDep = prevDep ? prevDep.nextDep_ : sub.deps_\n if (nextDep && nextDep.dep_ === dep) {\n nextDep.version_ = version\n sub.depsTail_ = nextDep\n return\n }\n const prevSub = dep.subsTail_\n if (prevSub && prevSub.version_ === version && prevSub.sub_ === sub) {\n return\n }\n const newLink =\n (sub.depsTail_ =\n dep.subsTail_ =\n {\n version_: version,\n dep_: dep,\n sub_: sub,\n prevDep_: prevDep,\n nextDep_: nextDep,\n prevSub_: prevSub,\n })\n if (nextDep) {\n nextDep.prevDep_ = newLink\n }\n if (prevDep) {\n prevDep.nextDep_ = newLink\n } else {\n sub.deps_ = newLink\n }\n if (prevSub) {\n prevSub.nextSub_ = newLink\n } else {\n dep.subs_ = newLink\n }\n}\n\nconst unlink = (link: Link, sub = link.sub_): Link | undefined => {\n const dep_ = link.dep_\n const prevDep_ = link.prevDep_\n const nextDep_ = link.nextDep_\n const nextSub_ = link.nextSub_\n const prevSub_ = link.prevSub_\n if (nextDep_) {\n nextDep_.prevDep_ = prevDep_\n } else {\n sub.depsTail_ = prevDep_\n }\n if (prevDep_) {\n prevDep_.nextDep_ = nextDep_\n } else {\n sub.deps_ = nextDep_\n }\n if (nextSub_) {\n nextSub_.prevSub_ = prevSub_\n } else {\n dep_.subsTail_ = prevSub_\n }\n if (prevSub_) {\n prevSub_.nextSub_ = nextSub_\n } else if (!(dep_.subs_ = nextSub_)) {\n if ('getter' in dep_) {\n let toRemove = dep_.deps_\n if (toRemove) {\n dep_.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n do {\n toRemove = unlink(toRemove, dep_)\n } while (toRemove)\n }\n } else if (!('previousValue' in dep_)) {\n effectOper(dep_ as AlienEffect)\n }\n }\n return nextDep_\n}\n\nconst propagate = (link: Link): void => {\n let next = link.nextSub_\n let stack: Stack | undefined\n\n top: while (true) {\n const sub = link.sub_\n\n let flags = sub.flags_\n\n if (\n !(\n flags &\n (60 as\n | ReactiveFlags.RecursedCheck\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)\n )\n ) {\n sub.flags_ = flags | (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (12 as ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))\n ) {\n flags = 0 satisfies ReactiveFlags.None\n } else if (!(flags & (4 satisfies ReactiveFlags.RecursedCheck))) {\n sub.flags_ =\n (flags & ~(8 satisfies ReactiveFlags.Recursed)) |\n (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (48 as ReactiveFlags.Dirty | ReactiveFlags.Pending)) &&\n isValidLink(link, sub)\n ) {\n sub.flags_ =\n flags | (40 as ReactiveFlags.Recursed | ReactiveFlags.Pending)\n flags &= 1 satisfies ReactiveFlags.Mutable\n } else {\n flags = 0 satisfies ReactiveFlags.None\n }\n\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n\n if (flags & (1 satisfies ReactiveFlags.Mutable)) {\n const subSubs = sub.subs_\n if (subSubs) {\n const nextSub = (link = subSubs).nextSub_\n if (nextSub) {\n stack = { value_: next, prev_: stack }\n next = nextSub\n }\n continue\n }\n }\n\n if ((link = next!)) {\n next = link.nextSub_\n continue\n }\n\n while (stack) {\n link = stack.value_!\n stack = stack.prev_\n if (link) {\n next = link.nextSub_\n continue top\n }\n }\n\n break\n }\n}\n\nconst startTracking = (sub: ReactiveNode): void => {\n version++\n sub.depsTail_ = undefined\n sub.flags_ =\n (sub.flags_ &\n ~(56 as\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)) |\n (4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst endTracking = (sub: ReactiveNode): void => {\n const depsTail_ = sub.depsTail_\n let toRemove = depsTail_ ? depsTail_.nextDep_ : sub.deps_\n while (toRemove) {\n toRemove = unlink(toRemove, sub)\n }\n sub.flags_ &= ~(4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst checkDirty = (link: Link, sub: ReactiveNode): boolean => {\n let stack: Stack | undefined\n let checkDepth = 0\n let dirty = false\n\n top: while (true) {\n const dep = link.dep_\n const flags = dep.flags_\n\n if (sub.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n dirty = true\n } else if (\n (flags & (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===\n (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)\n ) {\n if (update(dep as AlienSignal | AlienComputed)) {\n const subs = dep.subs_!\n if (subs.nextSub_) {\n shallowPropagate(subs)\n }\n dirty = true\n }\n } else if (\n (flags & (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===\n (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)\n ) {\n if (link.nextSub_ || link.prevSub_) {\n stack = { value_: link, prev_: stack }\n }\n link = dep.deps_!\n sub = dep\n ++checkDepth\n continue\n }\n\n if (!dirty) {\n const nextDep = link.nextDep_\n if (nextDep) {\n link = nextDep\n continue\n }\n }\n\n while (checkDepth--) {\n const firstSub = sub.subs_!\n const hasMultipleSubs = firstSub.nextSub_\n if (hasMultipleSubs) {\n link = stack!.value_\n stack = stack!.prev_\n } else {\n link = firstSub\n }\n if (dirty) {\n if (update(sub as AlienSignal | AlienComputed)) {\n if (hasMultipleSubs) {\n shallowPropagate(firstSub)\n }\n sub = link.sub_\n continue\n }\n dirty = false\n } else {\n sub.flags_ &= ~(32 satisfies ReactiveFlags.Pending)\n }\n sub = link.sub_\n if (link.nextDep_) {\n link = link.nextDep_\n continue top\n }\n }\n\n return dirty\n }\n}\n\nconst shallowPropagate = (link: Link): void => {\n do {\n const sub = link.sub_\n const flags = sub.flags_\n if (\n (flags & (48 as ReactiveFlags.Pending | ReactiveFlags.Dirty)) ===\n (32 satisfies ReactiveFlags.Pending)\n ) {\n sub.flags_ = flags | (16 satisfies ReactiveFlags.Dirty)\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n }\n } while ((link = link.nextSub_!))\n}\n\nconst isValidLink = (checkLink: Link, sub: ReactiveNode): boolean => {\n let link = sub.depsTail_\n while (link) {\n if (link === checkLink) {\n return true\n }\n link = link.prevDep_\n }\n return false\n}\n\nexport const getPath = (path: string): T | undefined => {\n let result = root\n const split = path.split('.')\n for (const path of split) {\n if (result == null || !hasOwn(result, path)) {\n return\n }\n result = result[path]\n }\n return result as T\n}\n\nconst deep = (value: any, prefix = ''): any => {\n const isArr = Array.isArray(value)\n if (isArr || isPojo(value)) {\n const deepObj = (isArr ? [] : {}) as Record>\n for (const key in value) {\n deepObj[key] = signal(\n deep((value as Record>)[key], `${prefix + key}.`),\n )\n }\n const keys = signal(0)\n return new Proxy(deepObj, {\n get(_, prop: string) {\n // JSON.stringify calls `.toJSON()` directly instead of checking if it exists on the object\n // so we have to check if `toJSON` is being called and prevent a signal from automatically\n // being made so JSON.stringify can fallback to the default stringify\n if (!(prop === 'toJSON' && !hasOwn(deepObj, prop))) {\n // special case for when prop is an array function because every array function needs to\n // be reactive to when the keys change\n if (isArr && prop in Array.prototype) {\n keys()\n return deepObj[prop]\n }\n // if prop is a symbol just return the symbol because we don't want to make up that theres\n // an iterator symbol on an object or not\n if (typeof prop === 'symbol') {\n return deepObj[prop]\n }\n // if obj doesnt have prop OR prop is null or undefined then create a signal and default\n // to an empty string\n if (!hasOwn(deepObj, prop) || deepObj[prop]() == null) {\n deepObj[prop] = signal('')\n dispatch(prefix + prop, '')\n keys(keys() + 1)\n }\n return deepObj[prop]()\n }\n },\n set(_, prop: string, newValue) {\n const path = prefix + prop\n // special case for when setting length so we can make a diff patch\n if (isArr && prop === 'length') {\n const diff = (deepObj[prop] as unknown as number) - newValue\n deepObj[prop] = newValue\n // manually make a diff patch for now, shouldnt have to do this when object diffing is\n // implemented. see https://github.com/starfederation/datastar-dev/issues/274\n if (diff > 0) {\n const patch: Record = {}\n for (let i = newValue; i < deepObj[prop]; i++) {\n patch[i] = null\n }\n dispatch(prefix.slice(0, -1), patch)\n keys(keys() + 1)\n }\n } else if (hasOwn(deepObj, prop)) {\n if (newValue == null) {\n delete deepObj[prop]\n // if newValue is a computed set the computed directly instead of wrapping in signal\n } else if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n // if prop changed after setting it then dispatch\n } else if (deepObj[prop](deep(newValue, `${path}.`))) {\n dispatch(path, newValue)\n }\n // if newValue is null or undefined then noop\n } else if (newValue != null) {\n // if newValue is a computed set the computed directly instead of wrapping in signal\n if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n } else {\n deepObj[prop] = signal(deep(newValue, `${path}.`))\n dispatch(path, newValue)\n }\n keys(keys() + 1)\n }\n\n return true\n },\n deleteProperty(_, prop: string) {\n delete deepObj[prop]\n keys(keys() + 1)\n return true\n },\n ownKeys() {\n keys()\n return Reflect.ownKeys(deepObj)\n },\n has(_, prop) {\n keys()\n return prop in deepObj\n },\n })\n }\n return value\n}\n\nconst dispatch = (path?: string, value?: any) => {\n if (path !== undefined && value !== undefined) {\n currentPatch.push([path, value])\n }\n if (!batchDepth && currentPatch.length) {\n const detail = pathToObj(currentPatch)\n currentPatch.length = 0\n document.dispatchEvent(\n new CustomEvent(DATASTAR_SIGNAL_PATCH_EVENT, {\n detail,\n }),\n )\n }\n}\n\nexport const mergePatch = (\n patch: JSONPatch,\n { ifMissing }: MergePatchArgs = {},\n): void => {\n beginBatch()\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete root[key]\n }\n } else {\n mergeInner(patch[key], key, root, '', ifMissing)\n }\n }\n endBatch()\n}\n\nexport const mergePaths = (paths: Paths, options?: MergePatchArgs): void =>\n mergePatch(pathToObj(paths), options)\n\nconst mergeInner = (\n patch: any,\n target: string,\n targetParent: Record,\n prefix: string,\n ifMissing: boolean | undefined,\n): void => {\n if (isPojo(patch)) {\n if (\n !(\n hasOwn(targetParent, target) &&\n (isPojo(targetParent[target]) || Array.isArray(targetParent[target]))\n )\n ) {\n targetParent[target] = {}\n }\n\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete targetParent[target][key]\n }\n } else {\n mergeInner(\n patch[key],\n key,\n targetParent[target],\n `${prefix + target}.`,\n ifMissing,\n )\n }\n }\n } else if (!(ifMissing && hasOwn(targetParent, target))) {\n targetParent[target] = patch\n }\n}\n\nconst toRegExp = (val: string | RegExp): RegExp =>\n typeof val === 'string' ? RegExp(val.replace(/^\\/|\\/$/g, '')) : val\n\n/**\n * Filters the root store based on an include and exclude RegExp\n *\n * @returns The filtered object\n */\nexport const filtered = (\n { include = /.*/, exclude = /(?!)/ }: SignalFilterOptions = {},\n obj: JSONPatch = root,\n): Record => {\n const includeRe = toRegExp(include)\n const excludeRe = toRegExp(exclude)\n const paths: Paths = []\n const stack: [any, string][] = [[obj, '']]\n\n while (stack.length) {\n const [node, prefix] = stack.pop()!\n\n for (const key in node) {\n const path = prefix + key\n if (isPojo(node[key])) {\n stack.push([node[key], `${path}.`])\n } else if (includeRe.test(path) && !excludeRe.test(path)) {\n paths.push([path, getPath(path)])\n }\n }\n }\n\n return pathToObj(paths)\n}\n\nexport const root: Record = deep({})\n", "import type { HTMLOrSVG } from '@engine/types'\n\nexport const isHTMLOrSVG = (el: Node): el is HTMLOrSVG =>\n el instanceof HTMLElement ||\n el instanceof SVGElement ||\n el instanceof MathMLElement\n", "import { DATASTAR_FETCH_EVENT, DSP, DSS } from '@engine/consts'\nimport { snake } from '@utils/text'\nimport { root } from '@engine/signals'\nimport type {\n ActionPlugin,\n ActionContext,\n AttributeContext,\n AttributePlugin,\n DatastarFetchEvent,\n HTMLOrSVG,\n Requirement,\n WatcherPlugin,\n} from '@engine/types'\nimport { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst url = 'https://data-star.dev/errors'\n\nconst error = (\n ctx: Record,\n reason: string,\n metadata: Record = {},\n) => {\n Object.assign(metadata, ctx)\n const e = new Error()\n const r = snake(reason)\n const q = new URLSearchParams({\n metadata: JSON.stringify(metadata),\n }).toString()\n const c = JSON.stringify(metadata, null, 2)\n e.message = `${reason}\\nMore info: ${url}/${r}?${q}\\nContext: ${c}`\n return e\n}\n\nconst actionPlugins: Map = new Map()\nconst attributePlugins: Map = new Map()\nconst watcherPlugins: Map = new Map()\n\nexport const actions: Record<\n string,\n (ctx: ActionContext, ...args: any[]) => any\n> = new Proxy(\n {},\n {\n get: (_, prop: string) => actionPlugins.get(prop)?.apply,\n has: (_, prop: string) => actionPlugins.has(prop),\n ownKeys: () => Reflect.ownKeys(actionPlugins),\n set: () => false,\n deleteProperty: () => false,\n },\n)\n\n// Map of cleanups keyed by element and attribute name\nconst removals = new Map void>>()\n\nconst queuedAttributes: AttributePlugin[] = []\nconst queuedAttributeNames = new Set()\nexport const attribute = (\n plugin: AttributePlugin,\n): void => {\n queuedAttributes.push(plugin as unknown as AttributePlugin)\n\n if (queuedAttributes.length === 1) {\n setTimeout(() => {\n for (const attribute of queuedAttributes) {\n queuedAttributeNames.add(attribute.name)\n attributePlugins.set(attribute.name, attribute)\n }\n queuedAttributes.length = 0\n apply()\n queuedAttributeNames.clear()\n })\n }\n}\n\nexport const action = (plugin: ActionPlugin): void => {\n actionPlugins.set(plugin.name, plugin)\n}\n\ndocument.addEventListener(DATASTAR_FETCH_EVENT, ((\n evt: CustomEvent,\n) => {\n const plugin = watcherPlugins.get(evt.detail.type)\n if (plugin) {\n plugin.apply(\n {\n error: error.bind(0, {\n plugin: { type: 'watcher', name: plugin.name },\n element: {\n id: (evt.target as Element).id,\n tag: (evt.target as Element).tagName,\n },\n }),\n },\n evt.detail.argsRaw,\n )\n }\n}) as EventListener)\n\nexport const watcher = (plugin: WatcherPlugin): void => {\n watcherPlugins.set(plugin.name, plugin)\n}\n\nconst cleanupEls = (els: Iterable): void => {\n for (const el of els) {\n const cleanups = removals.get(el)\n // If removals has el, delete it and run all cleanup functions\n if (removals.delete(el)) {\n for (const cleanup of cleanups!.values()) {\n cleanup()\n }\n cleanups!.clear()\n }\n }\n}\n\nconst aliasedIgnore = aliasify('ignore')\nconst aliasedIgnoreAttr = `[${aliasedIgnore}]`\nconst shouldIgnore = (el: HTMLOrSVG) =>\n el.hasAttribute(`${aliasedIgnore}__self`) || !!el.closest(aliasedIgnoreAttr)\n\nconst applyEls = (els: Iterable, onlyNew?: boolean): void => {\n for (const el of els) {\n if (!shouldIgnore(el)) {\n for (const key in el.dataset) {\n applyAttributePlugin(\n el,\n key.replace(/[A-Z]/g, '-$&').toLowerCase(),\n el.dataset[key]!,\n onlyNew,\n )\n }\n }\n }\n}\n\nconst observe = (mutations: MutationRecord[]) => {\n for (const {\n target,\n type,\n attributeName,\n addedNodes,\n removedNodes,\n } of mutations) {\n if (type === 'childList') {\n for (const node of removedNodes) {\n if (isHTMLOrSVG(node)) {\n cleanupEls([node])\n cleanupEls(node.querySelectorAll('*'))\n }\n }\n\n for (const node of addedNodes) {\n if (isHTMLOrSVG(node)) {\n applyEls([node])\n applyEls(node.querySelectorAll('*'))\n }\n }\n } else if (\n type === 'attributes' &&\n attributeName!.startsWith('data-') &&\n isHTMLOrSVG(target) &&\n !shouldIgnore(target)\n ) {\n // skip over 'data-'\n const key = attributeName!.slice(5)\n const value = target.getAttribute(attributeName!)\n if (value === null) {\n const cleanups = removals.get(target)\n if (cleanups) {\n cleanups.get(key)?.()\n cleanups.delete(key)\n }\n } else {\n applyAttributePlugin(target, key, value)\n }\n }\n }\n}\n\n// TODO: mutation observer per root so applying to web component doesnt overwrite main observer\nconst mutationObserver = new MutationObserver(observe)\n\nexport const apply = (\n root: HTMLOrSVG | ShadowRoot = document.documentElement,\n): void => {\n if (isHTMLOrSVG(root)) {\n applyEls([root], true)\n }\n applyEls(root.querySelectorAll('*'), true)\n\n mutationObserver.observe(root, {\n subtree: true,\n childList: true,\n attributes: true,\n })\n}\n\nconst applyAttributePlugin = (\n el: HTMLOrSVG,\n attrKey: string,\n value: string,\n onlyNew?: boolean,\n): void => {\n if (!ALIAS || attrKey.startsWith(`${ALIAS}-`)) {\n const rawKey = ALIAS ? attrKey.slice(ALIAS.length + 1) : attrKey\n const [namePart, ...rawModifiers] = rawKey.split('__')\n const [pluginName, key] = namePart.split(/:(.+)/)\n const plugin = attributePlugins.get(pluginName)\n if ((!onlyNew || queuedAttributeNames.has(pluginName)) && plugin) {\n const ctx = {\n el,\n rawKey,\n mods: new Map(),\n error: error.bind(0, {\n plugin: { type: 'attribute', name: plugin.name },\n element: { id: el.id, tag: el.tagName },\n expression: { rawKey, key, value },\n }),\n key,\n value,\n rx: undefined,\n } as AttributeContext\n\n const keyReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.key)) ||\n 'allowed'\n const valueReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.value)) ||\n 'allowed'\n\n if (key) {\n if (keyReq === 'denied') {\n throw ctx.error('KeyNotAllowed')\n }\n } else if (keyReq === 'must') {\n throw ctx.error('KeyRequired')\n }\n\n if (value) {\n if (valueReq === 'denied') {\n throw ctx.error('ValueNotAllowed')\n }\n } else if (valueReq === 'must') {\n throw ctx.error('ValueRequired')\n }\n\n if (keyReq === 'exclusive' || valueReq === 'exclusive') {\n if (key && value) {\n throw ctx.error('KeyAndValueProvided')\n }\n if (!key && !value) {\n throw ctx.error('KeyOrValueRequired')\n }\n }\n\n if (value) {\n let cachedRx: GenRxFn\n ctx.rx = (...args: any[]) => {\n if (!cachedRx) {\n cachedRx = genRx(value, {\n returnsValue: plugin.returnsValue,\n argNames: plugin.argNames,\n })\n }\n return cachedRx(el, ...args)\n }\n }\n\n for (const rawMod of rawModifiers) {\n const [label, ...mod] = rawMod.split('.')\n ctx.mods.set(label, new Set(mod))\n }\n\n const cleanup = plugin.apply(ctx)\n if (cleanup) {\n let cleanups = removals.get(el)\n if (cleanups) {\n cleanups.get(rawKey)?.()\n } else {\n cleanups = new Map()\n removals.set(el, cleanups)\n }\n cleanups.set(rawKey, cleanup)\n }\n }\n }\n}\n\ntype GenRxOptions = {\n returnsValue?: boolean\n argNames?: string[]\n}\n\ntype GenRxFn = (el: HTMLOrSVG, ...args: any[]) => T\n\nconst genRx = (\n value: string,\n { returnsValue = false, argNames = [] }: GenRxOptions = {},\n): GenRxFn => {\n let expr = ''\n if (returnsValue) {\n // This regex allows Datastar expressions to support nested\n // regex and strings that contain ; without breaking.\n //\n // Each of these regex defines a block type we want to match\n // (importantly we ignore the content within these blocks):\n //\n // regex \\/(\\\\\\/|[^\\/])*\\/\n // double quotes \"(\\\\\"|[^\\\"])*\"\n // single quotes '(\\\\'|[^'])*'\n // ticks `(\\\\`|[^`])*`\n // iife \\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;)\\{]*)\\s*\\)\\s*\\(\\s*\\)\n //\n // The iife support is (intentionally) limited. It only supports\n // function and arrow syntax with no arguments, and no nested IIFEs.\n //\n // We also want to match the non delimiter part of statements\n // note we only support ; statement delimiters:\n //\n // [^;]\n //\n const statementRe =\n /(\\/(\\\\\\/|[^/])*\\/|\"(\\\\\"|[^\"])*\"|'(\\\\'|[^'])*'|`(\\\\`|[^`])*`|\\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;){]*)\\s*\\)\\s*\\(\\s*\\)|[^;])+/gm\n const statements = value.trim().match(statementRe)\n if (statements) {\n const lastIdx = statements.length - 1\n const last = statements[lastIdx].trim()\n if (!last.startsWith('return')) {\n statements[lastIdx] = `return (${last});`\n }\n expr = statements.join(';\\n')\n }\n } else {\n expr = value.trim()\n }\n\n // Ignore any escaped values\n const escaped = new Map()\n const escapeRe = RegExp(`(?:${DSP})(.*?)(?:${DSS})`, 'gm')\n let counter = 0\n for (const match of expr.matchAll(escapeRe)) {\n const k = match[1]\n const v = `__escaped${counter++}`\n escaped.set(v, k)\n expr = expr.replace(DSP + k + DSS, v)\n }\n\n // Replace signal references with bracket notation\n // Examples:\n // $count -> $['count']\n // $count-- -> $['count']--\n // $foo.bar -> $['foo']['bar']\n // $foo-bar -> $['foo-bar']\n // $foo.bar-baz -> $['foo']['bar-baz']\n // $foo-$bar -> $['foo']-$['bar']\n // $arr[$index] -> $['arr'][$['index']]\n // $['foo'] -> $['foo']\n // $foo[obj.bar] -> $['foo'][obj.bar]\n // $foo['bar.baz'] -> $['foo']['bar.baz']\n // $123 -> $['123']\n // $foo.0.name -> $['foo']['0']['name']\n\n expr = expr\n // $['x'] -> $x (normalize existing bracket notation)\n .replace(/\\$\\['([a-zA-Z_$\\d][\\w$]*)'\\]/g, '$$$1')\n // $x -> $['x'] (including dots and hyphens)\n .replace(/\\$([a-zA-Z_\\d]\\w*(?:[.-]\\w+)*)/g, (_, signalName) =>\n signalName\n .split('.')\n .reduce((acc: string, part: string) => `${acc}['${part}']`, '$'),\n )\n // [$x] -> [$['x']] ($ inside brackets)\n .replace(\n /\\[(\\$[a-zA-Z_\\d]\\w*)\\]/g,\n (_, varName) => `[$['${varName.slice(1)}']]`,\n )\n\n expr = expr.replaceAll(/@(\\w+)\\(/g, '__action(\"$1\",evt,')\n\n // Replace any escaped values\n for (const [k, v] of escaped) {\n expr = expr.replace(k, v)\n }\n\n try {\n const fn = Function('el', '$', '__action', 'evt', ...argNames, expr)\n return (el: HTMLOrSVG, ...args: any[]) => {\n const action = (name: string, evt: Event | undefined, ...args: any[]) => {\n const err = error.bind(0, {\n plugin: { type: 'action', name },\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n })\n const fn = actions[name]\n if (fn) {\n return fn(\n {\n el,\n evt,\n error: err,\n },\n ...args,\n )\n }\n throw err('UndefinedAction')\n }\n try {\n return fn(el, root, action, undefined, ...args)\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'ExecuteExpression',\n )\n }\n }\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'GenerateExpression',\n )\n }\n}\n", "import { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst ctxIdMap = new Map>()\nconst ctxPersistentIds = new Set()\nconst oldIdTagNameMap = new Map()\nconst duplicateIds = new Set()\nconst ctxPantry = document.createElement('div')\nctxPantry.hidden = true\n\nconst aliasedIgnoreMorph = aliasify('ignore-morph')\nconst aliasedIgnoreMorphAttr = `[${aliasedIgnoreMorph}]`\nexport const morph = (\n oldElt: Element | ShadowRoot,\n newContent: DocumentFragment | Element,\n mode: 'outer' | 'inner' = 'outer',\n): void => {\n if (\n (isHTMLOrSVG(oldElt) &&\n isHTMLOrSVG(newContent) &&\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newContent.hasAttribute(aliasedIgnoreMorph)) ||\n oldElt.parentElement?.closest(aliasedIgnoreMorphAttr)\n ) {\n return\n }\n\n const normalizedElt = document.createElement('div')\n normalizedElt.append(newContent)\n document.body.insertAdjacentElement('afterend', ctxPantry)\n\n // Computes the set of IDs that persist between the two contents excluding duplicates\n const oldIdElements = oldElt.querySelectorAll('[id]')\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id)\n } else {\n oldIdTagNameMap.set(id, tagName)\n }\n }\n if (oldElt instanceof Element && oldElt.id) {\n if (oldIdTagNameMap.has(oldElt.id)) {\n duplicateIds.add(oldElt.id)\n } else {\n oldIdTagNameMap.set(oldElt.id, oldElt.tagName)\n }\n }\n\n ctxPersistentIds.clear()\n const newIdElements = normalizedElt.querySelectorAll('[id]')\n for (const { id, tagName } of newIdElements) {\n if (ctxPersistentIds.has(id)) {\n duplicateIds.add(id)\n } else if (oldIdTagNameMap.get(id) === tagName) {\n ctxPersistentIds.add(id)\n }\n }\n\n for (const id of duplicateIds) {\n ctxPersistentIds.delete(id)\n }\n\n oldIdTagNameMap.clear()\n duplicateIds.clear()\n ctxIdMap.clear()\n\n const parent = mode === 'outer' ? oldElt.parentElement! : oldElt\n populateIdMapWithTree(parent, oldIdElements)\n populateIdMapWithTree(normalizedElt, newIdElements)\n\n morphChildren(\n parent,\n normalizedElt,\n mode === 'outer' ? oldElt : null,\n oldElt.nextSibling,\n )\n\n ctxPantry.remove()\n}\n\n// This is the core algorithm for matching up children.\n// The idea is to use ID sets to try to match up nodes as faithfully as possible.\n// We greedily match, which allows us to keep the algorithm fast,\n// but by using ID sets, we are able to better match up with content deeper in the DOM.\nconst morphChildren = (\n oldParent: Element | ShadowRoot, // the old content that we are merging the new content into\n newParent: Element, // the parent element of the new content\n insertionPoint: Node | null = null, // the point in the DOM we start morphing at (defaults to first child)\n endPoint: Node | null = null, // the point in the DOM we stop morphing at (defaults to after last child)\n): void => {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // we can pretend the DocumentElement is an Element\n oldParent = oldParent.content as unknown as Element\n newParent = newParent.content as unknown as Element\n }\n insertionPoint ??= oldParent.firstChild\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint !== endPoint) {\n const bestMatch = findBestMatch(newChild, insertionPoint, endPoint)\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n let cursor: Node | null = insertionPoint\n // Remove nodes between the start and end nodes\n while (cursor && cursor !== bestMatch) {\n const tempNode = cursor\n cursor = cursor.nextSibling\n removeNode(tempNode)\n }\n }\n morphNode(bestMatch, newChild)\n insertionPoint = bestMatch.nextSibling\n continue\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctxPersistentIds.has(newChild.id)) {\n // move it and all its children here and morph, will always be found\n // Search for an element by ID within the document and pantry, and move it using moveBefore.\n const movedChild = document.getElementById(newChild.id) as Element\n\n // Removes an element from its ancestors' ID maps.\n // This is needed when an element is moved from the \"future\" via `moveBeforeId`.\n // Otherwise, its erstwhile ancestors could be mistakenly moved to the pantry rather than being deleted,\n // preventing their removal hooks from being called.\n let current = movedChild\n while ((current = current.parentNode as Element)) {\n const idSet = ctxIdMap.get(current)\n if (idSet) {\n idSet.delete(newChild.id)\n if (!idSet.size) {\n ctxIdMap.delete(current)\n }\n }\n }\n\n moveBefore(oldParent, movedChild, insertionPoint)\n morphNode(movedChild, newChild)\n insertionPoint = movedChild.nextSibling\n continue\n }\n\n // This performs the action of inserting a new node while handling situations where the node contains\n // elements with persistent IDs and possible state info we can still preserve by moving in and then morphing\n if (ctxIdMap.has(newChild)) {\n // node has children with IDs with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n (newChild as Element).tagName,\n )\n oldParent.insertBefore(newEmptyChild, insertionPoint)\n morphNode(newEmptyChild, newChild)\n insertionPoint = newEmptyChild.nextSibling\n } else {\n // optimization: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true) // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint)\n insertionPoint = newClonedChild.nextSibling\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint !== endPoint) {\n const tempNode = insertionPoint\n insertionPoint = insertionPoint.nextSibling\n removeNode(tempNode)\n }\n}\n\n// Scans forward from the startPoint to the endPoint looking for a match for the node.\n// It looks for an id set match first, then a soft match.\n// We abort soft matching if we find two future soft matches, to reduce churn.\nconst findBestMatch = (\n node: Node,\n startPoint: Node | null,\n endPoint: Node | null,\n): Node | null => {\n let bestMatch: Node | null | undefined = null\n let nextSibling = node.nextSibling\n let siblingSoftMatchCount = 0\n let displaceMatchCount = 0\n\n // Max ID matches we are willing to displace in our search\n const nodeMatchCount = ctxIdMap.get(node)?.size || 0\n\n let cursor = startPoint\n while (cursor && cursor !== endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n let isIdSetMatch = false\n const oldSet = ctxIdMap.get(cursor)\n const newSet = ctxIdMap.get(node)\n\n if (newSet && oldSet) {\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n isIdSetMatch = true\n break\n }\n }\n }\n\n if (isIdSetMatch) {\n return cursor // found an id set match, we're done!\n }\n\n // we haven\u2019t yet saved a soft match fallback\n // the current soft match will hard match something else in the future, leave it\n if (!bestMatch && !ctxIdMap.has(cursor)) {\n // optimization: if node can't id set match, we can just return the soft match immediately\n if (!nodeMatchCount) {\n return cursor\n }\n // save this as the fallback if we get through the loop without finding a hard match\n bestMatch = cursor\n }\n }\n\n // check for IDs we may be displaced when matching\n displaceMatchCount += ctxIdMap.get(cursor)?.size || 0\n if (displaceMatchCount > nodeMatchCount) {\n // if we are going to displace more IDs than the node contains then\n // we do not have a good candidate for an ID match, so return\n break\n }\n\n if (bestMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++\n nextSibling = nextSibling.nextSibling\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n bestMatch = undefined\n }\n }\n\n cursor = cursor.nextSibling\n }\n\n return bestMatch || null\n}\n\n// ok to cast: if one is not element, `id` and `tagName` will be null and we'll just compare that.\nconst isSoftMatch = (oldNode: Node, newNode: Node): boolean =>\n oldNode.nodeType === newNode.nodeType &&\n (oldNode as Element).tagName === (newNode as Element).tagName &&\n // If oldElt has an `id` with possible state and it doesn\u2019t match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!(oldNode as Element).id ||\n (oldNode as Element).id === (newNode as Element).id)\n\n// Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n// - Persistent nodes will be moved to the pantry for later reuse\n// - Other nodes will have their hooks called, and then are removed\nconst removeNode = (node: Node): void => {\n // are we going to id set match this later?\n ctxIdMap.has(node)\n ? // skip callbacks and move to pantry\n moveBefore(ctxPantry, node, null)\n : // remove for realsies\n node.parentNode?.removeChild(node)\n}\n\n// Moves an element before another element within the same parent.\n// Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n// This is essentially a forward-compat wrapper.\nconst moveBefore: (parentNode: Node, node: Node, after: Node | null) => void =\n // @ts-expect-error\n removeNode.call.bind(ctxPantry.moveBefore ?? ctxPantry.insertBefore)\n\nconst aliasedPreserveAttr = aliasify('preserve-attr')\n\n// syncs the oldNode to the newNode, copying over all attributes and\n// inner element state from the newNode to the oldNode\nconst morphNode = (\n oldNode: Node, // root node to merge content into\n newNode: Node, // new content to merge\n): Node => {\n const type = newNode.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = oldNode as Element\n const newElt = newNode as Element\n if (\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newElt.hasAttribute(aliasedIgnoreMorph)\n ) {\n return oldNode\n }\n\n // many bothans died to bring us this information:\n // https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n // https://github.com/choojs/nanomorph/blob/master/lib/morph.js#L113\n if (\n oldElt instanceof HTMLInputElement &&\n newElt instanceof HTMLInputElement &&\n newElt.type !== 'file'\n ) {\n // https://github.com/bigskysoftware/idiomorph/issues/27\n // | old input value | new input value | behaviour |\n // | --------------- | ---------------- | -------------------------------------- |\n // | `null` | `null` | preserve old input value |\n // | some value | the same value | preserve old input value |\n // | some value | `null` | set old input value to `\"\"` |\n // | `null` | some value | set old input value to new input value |\n // | some value | some other value | set old input value to new input value |\n if (newElt.getAttribute('value') !== oldElt.getAttribute('value')) {\n oldElt.value = newElt.getAttribute('value') ?? ''\n }\n } else if (\n oldElt instanceof HTMLTextAreaElement &&\n newElt instanceof HTMLTextAreaElement\n ) {\n if (newElt.value !== oldElt.value) {\n oldElt.value = newElt.value\n }\n if (oldElt.firstChild && oldElt.firstChild.nodeValue !== newElt.value) {\n oldElt.firstChild.nodeValue = newElt.value\n }\n }\n\n const preserveAttrs = (\n (newNode as HTMLElement).getAttribute(aliasedPreserveAttr) ?? ''\n ).split(' ')\n\n for (const { name, value } of newElt.attributes) {\n if (\n oldElt.getAttribute(name) !== value &&\n !preserveAttrs.includes(name)\n ) {\n oldElt.setAttribute(name, value)\n }\n }\n\n for (let i = oldElt.attributes.length - 1; i >= 0; i--) {\n const { name } = oldElt.attributes[i]!\n if (!newElt.hasAttribute(name) && !preserveAttrs.includes(name)) {\n oldElt.removeAttribute(name)\n }\n }\n\n if (!oldElt.isEqualNode(newElt)) {\n morphChildren(oldElt, newElt)\n }\n }\n\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue\n }\n }\n\n return oldNode\n}\n\n// A bottom-up algorithm that populates a map of Element -> IdSet.\n// The ID set for a given element is the set of all IDs contained within its subtree.\n// As an optimization, we filter these IDs through the given list of persistent IDs,\n// because we don't need to bother considering IDed elements that won't be in the new content.\nconst populateIdMapWithTree = (\n root: Element | ShadowRoot | null,\n elements: Iterable,\n): void => {\n for (const elt of elements) {\n if (ctxPersistentIds.has(elt.id)) {\n let current: Element | null = elt\n // walk up the parent hierarchy of that element, adding the ID of element to the parent's ID set\n while (current && current !== root) {\n let idSet = ctxIdMap.get(current)\n // if the ID set doesn\u2019t exist, create it and insert it in the map\n if (!idSet) {\n idSet = new Set()\n ctxIdMap.set(current, idSet)\n }\n idSet.add(elt.id)\n current = current.parentElement\n }\n }\n }\n}\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { startPeeking, stopPeeking } from '@engine/signals'\n\naction({\n name: 'peek',\n apply(_, fn: () => any) {\n startPeeking()\n try {\n return fn()\n } finally {\n stopPeeking()\n }\n },\n})\n", "// Icon: ion:checkmark-round\n// Slug: Sets the value of all matching signals.\n// Description: Sets the value of all matching signals (or all signals if no filter is used) to the expression provided in the first argument.\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'setAll',\n apply(_, value: any, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, () => value)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: material-symbols:toggle-off\n// Slug: Toggles the value of all matching signals.\n// Description: Toggles the boolean value of all matching signals (or all signals if no filter is used).\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'toggleAll',\n apply(_, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, (oldValue: any) => !oldValue)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { filtered } from '@engine/signals'\nimport type {\n DatastarFetchEvent,\n HTMLOrSVG,\n SignalFilterOptions,\n} from '@engine/types'\nimport { kebab } from '@utils/text'\n\nconst fetchAbortControllers = new WeakMap()\n\nconst createHttpMethod = (name: string, method: string): void =>\n action({\n name,\n apply: async (\n { el, evt, error },\n url: string,\n {\n selector,\n headers: userHeaders,\n contentType = 'json',\n filterSignals: { include = /.*/, exclude = /(^|\\.)_/ } = {},\n openWhenHidden = false,\n retryInterval = 1000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n requestCancellation = 'auto',\n }: FetchArgs = {},\n ) => {\n const controller =\n requestCancellation instanceof AbortController\n ? requestCancellation\n : new AbortController()\n const isDisabled = requestCancellation === 'disabled'\n if (!isDisabled) {\n const oldController = fetchAbortControllers.get(el)\n if (oldController) {\n oldController.abort()\n // wait one tick for FINISHED to fire\n await Promise.resolve()\n }\n }\n\n if (!isDisabled && !(requestCancellation instanceof AbortController)) {\n fetchAbortControllers.set(el, controller)\n }\n\n try {\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const removed of mutation.removedNodes) {\n if (removed === el) {\n controller.abort()\n cleanupFn()\n }\n }\n }\n })\n if (el.parentNode) {\n observer.observe(el.parentNode, { childList: true })\n }\n\n let cleanupFn = () => {\n observer.disconnect()\n }\n\n try {\n if (!url?.length) {\n throw error('FetchNoUrlProvided', { action })\n }\n\n const initialHeaders: Record = {\n Accept: 'text/event-stream, text/html, application/json',\n 'Datastar-Request': true,\n }\n if (contentType === 'json') {\n initialHeaders['Content-Type'] = 'application/json'\n }\n const headers = Object.assign({}, initialHeaders, userHeaders)\n\n // We ignore the content-type header if using form data\n // if missing the boundary will be set automatically\n\n const req: FetchEventSourceInit = {\n method,\n headers,\n openWhenHidden,\n retryInterval,\n retryScaler,\n retryMaxWaitMs,\n retryMaxCount,\n signal: controller.signal,\n onopen: async (response: Response) => {\n if (response.status >= 400)\n dispatchFetch(ERROR, el, { status: response.status.toString() })\n },\n onmessage: (evt) => {\n if (!evt.event.startsWith('datastar')) return\n const type = evt.event\n const argsRawLines: Record = {}\n\n for (const line of evt.data.split('\\n')) {\n const i = line.indexOf(' ')\n const k = line.slice(0, i)\n const v = line.slice(i + 1)\n ;(argsRawLines[k] ||= []).push(v)\n }\n\n const argsRaw = Object.fromEntries(\n Object.entries(argsRawLines).map(([k, v]) => [k, v.join('\\n')]),\n )\n\n dispatchFetch(type, el, argsRaw)\n },\n onerror: (error) => {\n if (isWrongContent(error)) {\n // don't retry if the content-type is wrong\n throw error('FetchExpectedTextEventStream', { url })\n }\n // do nothing and it will retry\n if (error) {\n console.error(error.message)\n dispatchFetch(RETRYING, el, { message: error.message })\n }\n },\n }\n\n const urlInstance = new URL(url, document.baseURI)\n const queryParams = new URLSearchParams(urlInstance.search)\n\n if (contentType === 'json') {\n const res = JSON.stringify(filtered({ include, exclude }))\n if (method === 'GET') {\n queryParams.set('datastar', res)\n } else {\n req.body = res\n }\n } else if (contentType === 'form') {\n const formEl = (\n selector ? document.querySelector(selector) : el.closest('form')\n ) as HTMLFormElement\n if (!formEl) {\n throw error('FetchFormNotFound', { action, selector })\n }\n\n // Validate the form\n if (!formEl.checkValidity()) {\n formEl.reportValidity()\n cleanupFn()\n return\n }\n\n // Collect the form data\n\n const formData = new FormData(formEl)\n let submitter = el as HTMLElement | null\n\n if (el === formEl && evt instanceof SubmitEvent) {\n // Get the submitter from the event\n submitter = evt.submitter\n } else {\n // Prevent the form being submitted\n const preventDefault = (evt: Event) => evt.preventDefault()\n formEl.addEventListener('submit', preventDefault)\n cleanupFn = () => {\n formEl.removeEventListener('submit', preventDefault)\n observer.disconnect()\n }\n }\n\n // Append the value of the form submitter if it is a button with a name\n if (submitter instanceof HTMLButtonElement) {\n const name = submitter.getAttribute('name')\n if (name) formData.append(name, submitter.value)\n }\n\n const multipart =\n formEl.getAttribute('enctype') === 'multipart/form-data'\n // Leave the `Content-Type` header empty for multipart encoding so the browser can set it automatically with the correct boundary\n if (!multipart) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded'\n }\n\n const formParams = new URLSearchParams(formData as any)\n if (method === 'GET') {\n for (const [key, value] of formParams) {\n queryParams.append(key, value)\n }\n } else if (multipart) {\n req.body = formData\n } else {\n req.body = formParams\n }\n } else {\n throw error('FetchInvalidContentType', { action, contentType })\n }\n\n dispatchFetch(STARTED, el, {})\n urlInstance.search = queryParams.toString()\n\n try {\n await fetchEventSource(urlInstance.toString(), el, req)\n } catch (e: any) {\n if (!isWrongContent(e)) {\n throw error('FetchFailed', { method, url, error: e.message })\n }\n // exit gracefully and do nothing if the content-type is wrong\n // this can happen if the client is sending a request\n // where no response is expected, and they haven\u2019t\n // set the content-type to text/event-stream\n }\n } finally {\n dispatchFetch(FINISHED, el, {})\n cleanupFn()\n }\n } finally {\n if (fetchAbortControllers.get(el) === controller) {\n fetchAbortControllers.delete(el)\n }\n }\n },\n })\n\ncreateHttpMethod('delete', 'DELETE')\ncreateHttpMethod('get', 'GET')\ncreateHttpMethod('patch', 'PATCH')\ncreateHttpMethod('post', 'POST')\ncreateHttpMethod('put', 'PUT')\n\nexport const STARTED = 'started'\nexport const FINISHED = 'finished'\nexport const ERROR = 'error'\nexport const RETRYING = 'retrying'\nexport const RETRIES_FAILED = 'retries-failed'\n\nconst dispatchFetch = (\n type: string,\n el: HTMLOrSVG,\n argsRaw: Record,\n) =>\n document.dispatchEvent(\n new CustomEvent(DATASTAR_FETCH_EVENT, {\n detail: { type, el, argsRaw },\n }),\n )\n\nconst isWrongContent = (err: any) => `${err}`.includes('text/event-stream')\n\ntype ResponseOverrides =\n | {\n selector?: string\n mode?: string\n useViewTransition?: boolean\n }\n | {\n onlyIfMissing?: boolean\n }\n\nexport type FetchArgs = {\n headers?: Record\n openWhenHidden?: boolean\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n responseOverrides?: ResponseOverrides\n contentType?: 'json' | 'form'\n filterSignals?: SignalFilterOptions\n selector?: string\n requestCancellation?: 'auto' | 'disabled' | AbortController\n}\n\n// Below originally from https://github.com/Azure/fetch-event-source/blob/main/LICENSE\n\n/**\n * Represents a message sent in an event stream\n * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format\n */\n\ninterface EventSourceMessage {\n id: string\n event: string\n data: string\n retry?: number\n}\n\n/**\n * Converts a ReadableStream into a callback pattern.\n * @param stream The input ReadableStream.\n * @param onChunk A function that will be called on each new byte chunk in the stream.\n * @returns {Promise} A promise that will be resolved when the stream closes.\n */\nconst getBytes = async (\n stream: ReadableStream,\n onChunk: (arr: Uint8Array) => void,\n): Promise => {\n const reader = stream.getReader()\n let result = await reader.read()\n while (!result.done) {\n onChunk(result.value)\n result = await reader.read()\n }\n}\n\nconst getLines = (onLine: (line: Uint8Array, fieldLength: number) => void) => {\n let buffer: Uint8Array | undefined\n let position: number // current read position\n let fieldLength: number // length of the `field` portion of the line\n let discardTrailingNewline = false\n\n // return a function that can process each incoming byte chunk:\n return (arr: Uint8Array) => {\n if (!buffer) {\n buffer = arr\n position = 0\n fieldLength = -1\n } else {\n // we're still parsing the old line. Append the new bytes into buffer:\n buffer = concat(buffer, arr)\n }\n\n const bufLength = buffer.length\n let lineStart = 0 // index where the current line starts\n while (position < bufLength) {\n if (discardTrailingNewline) {\n if (buffer[position] === 10) lineStart = ++position // skip to next char\n discardTrailingNewline = false\n }\n\n // start looking forward till the end of line:\n let lineEnd = -1 // index of the \\r or \\n char\n for (; position < bufLength && lineEnd === -1; ++position) {\n switch (buffer[position]) {\n case 58: // :\n if (fieldLength === -1) {\n // first colon in line\n fieldLength = position - lineStart\n }\n break\n // @ts-expect-error:7029 \\r case below should fallthrough to \\n:\n // biome-ignore lint/suspicious/noFallthroughSwitchClause: intentional fallthrough for CR to LF\n case 13: // \\r\n discardTrailingNewline = true\n case 10: // \\n\n lineEnd = position\n break\n }\n }\n\n if (lineEnd === -1) break // Wait for the next arr and then continue parsing\n\n // we've reached the line end, send it out:\n onLine(buffer.subarray(lineStart, lineEnd), fieldLength)\n lineStart = position // we're now on the next line\n fieldLength = -1\n }\n\n if (lineStart === bufLength)\n buffer = undefined // we've finished reading it\n else if (lineStart) {\n // Create a new view into buffer beginning at lineStart so we don't\n // need to copy over the previous lines when we get the new arr:\n buffer = buffer.subarray(lineStart)\n position -= lineStart\n }\n }\n}\n\nconst getMessages = (\n onId: (id: string) => void,\n onRetry: (retry: number) => void,\n onMessage?: (msg: EventSourceMessage) => void,\n): ((line: Uint8Array, fieldLength: number) => void) => {\n let message = newMessage()\n const decoder = new TextDecoder()\n\n // return a function that can process each incoming line buffer:\n return (line, fieldLength) => {\n if (!line.length) {\n // empty line denotes end of message. Trigger the callback and start a new message:\n onMessage?.(message)\n message = newMessage()\n } else if (fieldLength > 0) {\n // exclude comments and lines with no values\n // line is of format \":\" or \": \"\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n const field = decoder.decode(line.subarray(0, fieldLength))\n const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1)\n const value = decoder.decode(line.subarray(valueOffset))\n\n switch (field) {\n case 'data':\n message.data = message.data ? `${message.data}\\n${value}` : value\n break\n case 'event':\n message.event = value\n break\n case 'id':\n onId((message.id = value))\n break\n case 'retry': {\n const retry = +value\n if (!Number.isNaN(retry)) {\n // per spec, ignore non-integers\n onRetry((message.retry = retry))\n }\n break\n }\n }\n }\n }\n}\n\nconst concat = (a: Uint8Array, b: Uint8Array) => {\n const res = new Uint8Array(a.length + b.length)\n res.set(a)\n res.set(b, a.length)\n return res\n}\n\nconst newMessage = (): EventSourceMessage => ({\n // data, event, and id must be initialized to empty strings:\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n // retry should be initialized to undefined so we return a consistent shape\n // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways\n data: '',\n event: '',\n id: '',\n retry: undefined,\n})\n\ntype FetchEventSourceInit = RequestInit & {\n headers?: Record\n onopen?: (response: Response) => Promise\n onmessage?: (ev: EventSourceMessage) => void\n onclose?: () => void\n onerror?: (err: any) => number | null | undefined | void\n openWhenHidden?: boolean\n fetch?: typeof fetch\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n overrides?: ResponseOverrides\n}\n\nconst fetchEventSource = (\n input: RequestInfo,\n el: HTMLOrSVG,\n {\n signal: inputSignal,\n headers: inputHeaders,\n onopen: inputOnOpen,\n onmessage,\n onclose,\n onerror,\n openWhenHidden,\n fetch: inputFetch,\n retryInterval = 1_000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n overrides,\n ...rest\n }: FetchEventSourceInit,\n): Promise => {\n return new Promise((resolve, reject) => {\n // make a copy of the input headers since we may modify it below:\n const headers: Record = {\n ...inputHeaders,\n }\n\n let curRequestController: AbortController\n const onVisibilityChange = () => {\n curRequestController.abort() // close existing request on every visibility change\n if (!document.hidden) create() // page is now visible again, recreate request.\n }\n\n if (!openWhenHidden) {\n document.addEventListener('visibilitychange', onVisibilityChange)\n }\n\n let retryTimer = 0\n const dispose = () => {\n document.removeEventListener('visibilitychange', onVisibilityChange)\n clearTimeout(retryTimer)\n curRequestController.abort()\n }\n\n // if the incoming signal aborts, dispose resources and resolve:\n inputSignal?.addEventListener('abort', () => {\n dispose()\n resolve() // don't waste time constructing/logging errors\n })\n\n const fetch = inputFetch || window.fetch\n const onopen = inputOnOpen || (() => {})\n\n let retries = 0\n let baseRetryInterval = retryInterval\n const create = async () => {\n curRequestController = new AbortController()\n try {\n const response = await fetch(input, {\n ...rest,\n headers,\n signal: curRequestController.signal,\n })\n\n // on successful connection, reset the retry logic\n retries = 0\n retryInterval = baseRetryInterval\n\n await onopen(response)\n\n const dispatchNonSSE = async (\n dispatchType: string,\n response: Response,\n name: string,\n overrides?: ResponseOverrides,\n ...argNames: string[]\n ) => {\n const argsRaw: Record = {\n [name]: await response.text(),\n }\n for (const n of argNames) {\n let v = response.headers.get(`datastar-${kebab(n)}`)\n if (overrides) {\n const o = (overrides as any)[n]\n if (o) v = typeof o === 'string' ? o : JSON.stringify(o)\n }\n if (v) argsRaw[n] = v\n }\n\n dispatchFetch(dispatchType, el, argsRaw)\n dispose()\n resolve()\n }\n\n const ct = response.headers.get('Content-Type')\n if (ct?.includes('text/html')) {\n return await dispatchNonSSE(\n 'datastar-patch-elements',\n response,\n 'elements',\n overrides,\n 'selector',\n 'mode',\n 'useViewTransition',\n )\n }\n\n if (ct?.includes('application/json')) {\n return await dispatchNonSSE(\n 'datastar-patch-signals',\n response,\n 'signals',\n overrides,\n 'onlyIfMissing',\n )\n }\n\n if (ct?.includes('text/javascript')) {\n const script = document.createElement('script')\n const scriptAttributesHeader = response.headers.get(\n 'datastar-script-attributes',\n )\n\n if (scriptAttributesHeader) {\n for (const [name, value] of Object.entries(\n JSON.parse(scriptAttributesHeader),\n )) {\n script.setAttribute(name, value as string)\n }\n }\n script.textContent = await response.text()\n document.head.appendChild(script)\n dispose()\n return\n }\n\n await getBytes(\n response.body!,\n getLines(\n getMessages(\n (id) => {\n if (id) {\n // signals the id and send it back on the next retry:\n headers['last-event-id'] = id\n } else {\n // don't send the last-event-id header anymore:\n delete headers['last-event-id']\n }\n },\n (retry) => {\n baseRetryInterval = retryInterval = retry\n },\n onmessage,\n ),\n ),\n )\n\n onclose?.()\n dispose()\n resolve()\n } catch (err) {\n if (!curRequestController.signal.aborted) {\n // if we haven\u2019t aborted the request ourselves:\n try {\n // check if we need to retry:\n const interval: any = onerror?.(err) || retryInterval\n clearTimeout(retryTimer)\n retryTimer = setTimeout(create, interval)\n retryInterval = Math.min(\n retryInterval * retryScaler,\n retryMaxWaitMs,\n ) // exponential backoff\n if (++retries >= retryMaxCount) {\n dispatchFetch(RETRIES_FAILED, el, {})\n // we should not retry anymore:\n dispose()\n reject('Max retries reached.') // Max retries reached, check your server or network connection\n } else {\n console.error(\n `Datastar failed to reach ${input.toString()} retrying in ${interval}ms.`,\n )\n }\n } catch (innerErr) {\n // we should not retry anymore:\n dispose()\n reject(innerErr)\n }\n }\n }\n }\n\n create()\n })\n}\n", "// Icon: material-symbols:edit-attributes-outline\n// Slug: Syncs the value of an attribute with an expression.\n// Description: Sets the value of any HTML attribute to an expression, and keeps it in sync.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'attr',\n requirement: { value: 'must' },\n returnsValue: true,\n apply({ el, key, rx }) {\n const syncAttr = (key: string, val: any) => {\n if (val === '' || val === true) {\n el.setAttribute(key, '')\n } else if (val === false || val == null) {\n el.removeAttribute(key)\n } else if (typeof val === 'string') {\n el.setAttribute(key, val)\n } else {\n el.setAttribute(key, JSON.stringify(val))\n }\n }\n\n const update = key\n ? () => {\n observer.disconnect()\n const val = rx() as string\n syncAttr(key, val)\n observer.observe(el, {\n attributeFilter: [key],\n })\n }\n : () => {\n observer.disconnect()\n const obj = rx() as Record\n const attributeFilter = Object.keys(obj)\n for (const key of attributeFilter) {\n syncAttr(key, obj[key])\n }\n observer.observe(el, {\n attributeFilter,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: akar-icons:link-chain\n// Slug: Creates a signal with two-way data binding.\n// Description: Creates a signal (if one doesn\u2019t already exist) and sets up two-way data binding between it and an element\u2019s value.\n\nimport { attribute } from '@engine'\nimport { effect, getPath, mergePaths } from '@engine/signals'\nimport type { Paths } from '@engine/types'\nimport { aliasify, modifyCasing } from '@utils/text'\n\ntype SignalFile = {\n name: string\n contents: string\n mime: string\n}\n\nconst dataURIRegex = /^data:(?[^;]+);base64,(?.*)$/\nconst empty = Symbol('empty')\n\nconst aliasedBind = aliasify('bind')\n\nattribute({\n name: 'bind',\n requirement: 'exclusive',\n apply({ el, key, mods, value, error }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n let get = (el: any, type: string) =>\n type === 'number' ? +el.value : el.value\n\n let set = (value: any) => {\n ;(el as HTMLInputElement).value = `${value}`\n }\n\n if (el instanceof HTMLInputElement) {\n switch (el.type) {\n case 'range':\n case 'number':\n get = (el: any, type: string) =>\n type === 'string' ? el.value : +el.value\n break\n\n case 'checkbox':\n get = (el: HTMLInputElement, type: string) => {\n if (el.value !== 'on') {\n if (type === 'boolean') {\n return el.checked\n } else {\n return el.checked ? el.value : ''\n }\n } else {\n if (type === 'string') {\n return el.checked ? el.value : ''\n } else {\n return el.checked\n }\n }\n }\n set = (value: string | boolean) => {\n el.checked = typeof value === 'string' ? value === el.value : value\n }\n break\n\n case 'radio':\n // Set up radio button name attribute if not present\n if (!el.getAttribute('name')?.length) {\n el.setAttribute('name', signalName)\n }\n\n get = (el: HTMLInputElement, type: string) =>\n el.checked ? (type === 'number' ? +el.value : el.value) : empty\n set = (value: string | number) => {\n el.checked =\n value === (typeof value === 'number' ? +el.value : el.value)\n }\n break\n case 'file': {\n const syncSignal = () => {\n const files = [...(el.files || [])]\n const signalFiles: SignalFile[] = []\n Promise.all(\n files.map(\n (f) =>\n new Promise((resolve) => {\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result !== 'string') {\n throw error('InvalidFileResultType', {\n resultType: typeof reader.result,\n })\n }\n const match = reader.result.match(dataURIRegex)\n if (!match?.groups) {\n throw error('InvalidDataUri', {\n result: reader.result,\n })\n }\n signalFiles.push({\n name: f.name,\n contents: match.groups.contents,\n mime: match.groups.mime,\n })\n }\n reader.onloadend = () => resolve()\n reader.readAsDataURL(f)\n }),\n ),\n ).then(() => {\n mergePaths([[signalName, signalFiles]])\n })\n }\n\n el.addEventListener('change', syncSignal)\n el.addEventListener('input', syncSignal)\n\n return () => {\n el.removeEventListener('change', syncSignal)\n el.removeEventListener('input', syncSignal)\n }\n }\n }\n } else if (el instanceof HTMLSelectElement) {\n if (el.multiple) {\n const typeMap = new Map()\n get = (el: HTMLSelectElement) =>\n [...el.selectedOptions].map((option) => {\n const type = typeMap.get(option.value)\n return type === 'string' || type == null\n ? option.value\n : +option.value\n })\n\n set = (value: (string | number)[]) => {\n for (const option of el.options) {\n if (value.includes(option.value)) {\n typeMap.set(option.value, 'string')\n option.selected = true\n } else if (value.includes(+option.value)) {\n typeMap.set(option.value, 'number')\n option.selected = true\n } else {\n option.selected = false\n }\n }\n }\n }\n } else if (el instanceof HTMLTextAreaElement) {\n // default case\n } else {\n // web component\n get = (el: Element) =>\n 'value' in el ? el.value : el.getAttribute('value')\n set = (value: any) => {\n if ('value' in el) {\n el.value = value\n } else {\n el.setAttribute('value', value)\n }\n }\n }\n\n const initialValue = getPath(signalName)\n const type = typeof initialValue\n\n let path = signalName\n if (\n Array.isArray(initialValue) &&\n !(el instanceof HTMLSelectElement && el.multiple)\n ) {\n const signalNameKebab = key ? key : value!\n const inputs = document.querySelectorAll(\n `[${aliasedBind}\\\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}=\"${CSS.escape(signalNameKebab)}\"]`,\n ) as NodeListOf\n\n const paths: Paths = []\n let i = 0\n for (const input of inputs) {\n paths.push([`${path}.${i}`, get(input, 'none')])\n\n if (el === input) {\n break\n }\n i++\n }\n mergePaths(paths, { ifMissing: true })\n path = `${path}.${i}`\n } else {\n mergePaths([[path, get(el, type)]], {\n ifMissing: true,\n })\n }\n\n const syncSignal = () => {\n const signalValue = getPath(path)\n if (signalValue != null) {\n const value = get(el, typeof signalValue)\n if (value !== empty) {\n mergePaths([[path, value]])\n }\n }\n }\n\n el.addEventListener('input', syncSignal)\n el.addEventListener('change', syncSignal)\n const cleanup = effect(() => {\n set(getPath(path))\n })\n\n return () => {\n cleanup()\n el.removeEventListener('input', syncSignal)\n el.removeEventListener('change', syncSignal)\n }\n },\n})\n", "// Icon: ic:baseline-format-paint\n// Slug: Adds or removes a class based on an expression.\n// Description: Adds or removes a class to or from an element based on an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'class',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, mods, rx }) {\n if (key) {\n key = modifyCasing(key, mods, 'kebab')\n }\n\n const callback = () => {\n observer.disconnect()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n if (classes[k]) {\n for (const name of classNames) {\n if (!el.classList.contains(name)) {\n el.classList.add(name)\n }\n }\n } else {\n for (const name of classNames) {\n if (el.classList.contains(name)) {\n el.classList.remove(name)\n }\n }\n }\n }\n\n observer.observe(el, { attributeFilter: ['class'] })\n }\n\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n for (const name of classNames) {\n el.classList.remove(name)\n }\n }\n }\n },\n})\n", "// Icon: streamline-ultimate:wifi-signal-2\n// Slug: Creates a computed signal.\n// Description: Creates a signal that is computed based on an expression.\n\nimport { attribute } from '@engine'\nimport { computed, mergePaths, mergePatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { updateLeaves } from '@utils/paths'\n\nattribute({\n name: 'computed',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, mods, rx, error }) {\n if (key) {\n mergePaths([[modifyCasing(key, mods), computed(rx)]])\n } else {\n const patch = Object.assign({}, rx() as Record any>)\n updateLeaves(patch, (old) => {\n if (typeof old === 'function') {\n return computed(old)\n } else {\n throw error('ComputedExpectedFunction')\n }\n })\n mergePatch(patch)\n }\n },\n})\n", "// Icon: oui:security-signal\n// Slug: Executes an expression when signals change.\n// Description: Executes an expression on page load and whenever any signals in the expression change.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'effect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply: ({ rx }) => effect(rx),\n})\n", "// Icon: streamline:signal-loading-remix\n// Slug: Creates an indicator for whether an SSE request is in flight.\n// Description: Creates a signal and sets its value to `true` while an SSE request request is in flight, otherwise `false`.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { mergePaths } from '@engine/signals'\nimport type { DatastarFetchEvent } from '@engine/types'\nimport { FINISHED, STARTED } from '@plugins/actions/fetch'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'indicator',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n mergePaths([[signalName, false]])\n\n const watcher = ((event: CustomEvent) => {\n const { type, el: elt } = event.detail\n if (elt !== el) {\n return\n }\n switch (type) {\n case STARTED:\n mergePaths([[signalName, true]])\n break\n case FINISHED:\n mergePaths([[signalName, false]])\n break\n }\n }) as EventListener\n document.addEventListener(DATASTAR_FETCH_EVENT, watcher)\n return () => {\n mergePaths([[signalName, false]])\n document.removeEventListener(DATASTAR_FETCH_EVENT, watcher)\n }\n },\n})\n", "// Icon: si:json-fill\n// Slug: Outputs a JSON stringified version of signals.\n// Description: Sets the text content of an element to a reactive JSON stringified version of signals.\n\nimport { attribute } from '@engine'\nimport { effect, filtered } from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { jsStrToObject } from '@utils/text'\n\nattribute({\n name: 'json-signals',\n requirement: {\n key: 'denied',\n },\n apply({ el, value, mods }) {\n const spaces = mods.has('terse') ? 0 : 2\n let filters: SignalFilterOptions = {}\n if (value) {\n filters = jsStrToObject(value)\n }\n\n const callback = () => {\n observer.disconnect()\n el.textContent = JSON.stringify(filtered(filters), null, spaces)\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "export const tagToMs = (args: Set) => {\n if (!args || args.size <= 0) return 0\n for (const arg of args) {\n if (arg.endsWith('ms')) {\n return +arg.replace('ms', '')\n }\n if (arg.endsWith('s')) {\n return +arg.replace('s', '') * 1000\n }\n try {\n return Number.parseFloat(arg)\n } catch (_) {}\n }\n return 0\n}\n\nexport const tagHas = (\n tags: Set,\n tag: string,\n defaultValue = false,\n) => {\n if (!tags) return defaultValue\n return tags.has(tag.toLowerCase())\n}\n\nexport const tagFirst = (tags?: Set, defaultValue = ''): string => {\n if (tags && tags.size > 0) {\n for (const tag of tags) {\n return tag\n }\n }\n return defaultValue\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\nimport { tagHas, tagToMs } from '@utils/tags'\n\nexport const delay = (\n callback: EventCallbackHandler,\n wait: number,\n): EventCallbackHandler => {\n return (...args: any[]) => {\n setTimeout(() => {\n callback(...args)\n }, wait)\n }\n}\n\nexport const debounce = (\n callback: EventCallbackHandler,\n wait: number,\n leading = false,\n trailing = true,\n): EventCallbackHandler => {\n let timer = 0\n return (...args: any[]) => {\n timer && clearTimeout(timer)\n\n if (leading && !timer) {\n callback(...args)\n }\n\n timer = setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n timer && clearTimeout(timer)\n timer = 0\n }, wait)\n }\n}\n\nexport const throttle = (\n callback: EventCallbackHandler,\n wait: number,\n leading = true,\n trailing = false,\n): EventCallbackHandler => {\n let waiting = false\n\n return (...args: any[]) => {\n if (waiting) return\n\n if (leading) {\n callback(...args)\n }\n\n waiting = true\n setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n waiting = false\n }, wait)\n }\n}\n\nexport const modifyTiming = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n const wait = tagToMs(delayArgs)\n callback = delay(callback, wait)\n }\n\n const debounceArgs = mods.get('debounce')\n if (debounceArgs) {\n const wait = tagToMs(debounceArgs)\n const leading = tagHas(debounceArgs, 'leading', false)\n const trailing = !tagHas(debounceArgs, 'notrailing', false)\n callback = debounce(callback, wait, leading, trailing)\n }\n\n const throttleArgs = mods.get('throttle')\n if (throttleArgs) {\n const wait = tagToMs(throttleArgs)\n const leading = !tagHas(throttleArgs, 'noleading', false)\n const trailing = tagHas(throttleArgs, 'trailing', false)\n callback = throttle(callback, wait, leading, trailing)\n }\n\n return callback\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\n\nexport const supportsViewTransitions = !!document.startViewTransition\n\nexport const modifyViewTransition = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n if (mods.has('viewtransition') && supportsViewTransitions) {\n const cb = callback // I hate javascript\n callback = (...args: any[]) =>\n document.startViewTransition(() => cb(...args))\n }\n\n return callback\n}\n", "// Icon: material-symbols:mail\n// Slug: Attaches an event listener to an element.\n// Description: Attaches an event listener to an element, executing an expression whenever the event is triggered.\n\nimport { attribute } from '@engine'\nimport {\n DATASTAR_FETCH_EVENT,\n DATASTAR_SIGNAL_PATCH_EVENT,\n} from '@engine/consts'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on',\n requirement: 'must',\n argNames: ['evt'],\n apply({ el, key, mods, rx }) {\n let target: Element | Window | Document = el\n if (mods.has('window')) target = window\n let callback = (evt?: Event) => {\n if (evt) {\n if (mods.has('prevent')) {\n evt.preventDefault()\n }\n if (mods.has('stop')) {\n evt.stopPropagation()\n }\n }\n beginBatch()\n rx(evt)\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const evtListOpts: AddEventListenerOptions = {\n capture: mods.has('capture'),\n passive: mods.has('passive'),\n once: mods.has('once'),\n }\n if (mods.has('outside')) {\n target = document\n const cb = callback\n callback = (evt?: Event) => {\n if (!el.contains(evt?.target as HTMLElement)) {\n cb(evt)\n }\n }\n }\n const eventName = modifyCasing(key, mods, 'kebab')\n // Listen for Datastar events on the document\n if (\n eventName === DATASTAR_FETCH_EVENT ||\n eventName === DATASTAR_SIGNAL_PATCH_EVENT\n ) {\n target = document\n }\n // Prevent default on form submit events\n if (el instanceof HTMLFormElement && eventName === 'submit') {\n const cb = callback\n callback = (evt?: Event) => {\n evt?.preventDefault()\n cb(evt)\n }\n }\n target.addEventListener(eventName, callback, evtListOpts)\n return () => {\n target.removeEventListener(eventName, callback)\n }\n },\n})\n", "// Icon: mdi-light:vector-intersection\n// Slug: Runs an expression on intersection.\n// Description: Runs an expression when the element intersects with the viewport.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport type { HTMLOrSVG } from '@engine/types'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nconst once = new WeakSet()\n\nattribute({\n name: 'on-intersect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ el, mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const options = { threshold: 0 }\n if (mods.has('full')) {\n options.threshold = 1\n } else if (mods.has('half')) {\n options.threshold = 0.5\n }\n let observer: IntersectionObserver | null = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n callback()\n if (observer && once.has(el)) {\n observer.disconnect()\n }\n }\n }\n },\n options,\n )\n observer.observe(el)\n if (mods.has('once')) {\n once.add(el)\n }\n return () => {\n if (!mods.has('once')) {\n once.delete(el)\n }\n if (observer) {\n observer.disconnect()\n observer = null\n }\n }\n },\n})\n", "// Icon: material-symbols:timer-outline\n// Slug: Runs an expression at a regular interval.\n// Description: Runs an expression at a regular interval.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagHas, tagToMs } from '@utils/tags'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on-interval',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let duration = 1000\n const durationArgs = mods.get('duration')\n if (durationArgs) {\n duration = tagToMs(durationArgs)\n const leading = tagHas(durationArgs, 'leading', false)\n if (leading) {\n callback()\n }\n }\n const intervalId = setInterval(callback, duration)\n return () => {\n clearInterval(intervalId)\n }\n },\n})\n", "// Icon: material-symbols:timer-play-outline\n// Slug: Runs an expression when loaded into the DOM.\n// Description: Runs an expression when the element is loaded into the DOM.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagToMs } from '@utils/tags'\nimport { delay } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'init',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ rx, mods }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let wait = 0\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n wait = tagToMs(delayArgs)\n if (wait > 0) {\n callback = delay(callback, wait)\n }\n }\n callback()\n },\n})\n", "// Icon: material-symbols:change-circle-outline\n// Slug: Runs an expression when signals are patched.\n// Description: Runs an expression whenever one or more signals are patched.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport { beginBatch, endBatch, filtered } from '@engine/signals'\nimport type { JSONPatch, SignalFilterOptions } from '@engine/types'\nimport { isEmpty } from '@utils/paths'\nimport { jsStrToObject } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\n\nattribute({\n name: 'on-signal-patch',\n requirement: {\n value: 'must',\n },\n argNames: ['patch'],\n returnsValue: true,\n apply({ el, key, mods, rx, error }) {\n if (!!key && key !== 'filter') {\n throw error('KeyNotAllowed')\n }\n\n // Look for data-on-signal-patch-filter data attribute\n const filtersRaw = el.getAttribute('data-on-signal-patch-filter')\n let filters: SignalFilterOptions = {}\n if (filtersRaw) {\n filters = jsStrToObject(filtersRaw)\n }\n\n const callback: EventListener = modifyTiming(\n (evt: CustomEvent) => {\n const watched = filtered(filters, evt.detail)\n if (!isEmpty(watched)) {\n beginBatch()\n rx(watched)\n endBatch()\n }\n },\n mods,\n )\n\n document.addEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n return () => {\n document.removeEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n }\n },\n})\n", "// Icon: mdi:cursor-pointer\n// Slug: Creates a reference to an element.\n// Description: Creates a new signal that is a reference to the element on which the data attribute is placed.\n\nimport { attribute } from '@engine'\nimport { mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'ref',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n mergePaths([[signalName, el]])\n },\n})\n", "// Icon: streamline:interface-edit-view-eye-eyeball-open-view\n// Slug: Shows or hides an element.\n// Description: Shows or hides an element based on whether an expression evaluates to `true` or `false`.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nconst NONE = 'none'\nconst DISPLAY = 'display'\n\nattribute({\n name: 'show',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n const shouldShow = rx()\n if (shouldShow) {\n if (el.style.display === NONE) el.style.removeProperty(DISPLAY)\n } else {\n el.style.setProperty(DISPLAY, NONE)\n }\n observer.observe(el, { attributeFilter: ['style'] })\n }\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: streamline:wifi-signal-full-remix\n// Slug: Patches signals into the existing signals.\n// Description: Patches (adds, updates or removes) one or more signals into the existing signals.\n\nimport { attribute } from '@engine'\nimport { mergePatch, mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'signals',\n returnsValue: true,\n apply({ key, mods, rx }) {\n const ifMissing = mods.has('ifmissing')\n\n if (key) {\n key = modifyCasing(key, mods)\n mergePaths([[key, rx?.()]], { ifMissing })\n } else {\n const patch = Object.assign({}, rx?.() as Record)\n mergePatch(patch, { ifMissing })\n }\n },\n})\n", "// Icon: material-symbols:format-paint-outline\n// Slug: Sets inline styles on an element based on an expression.\n// Description: Sets CSS styles on an element using either key-based or object syntax, and keeps them in sync with reactive signals.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { kebab } from '@utils/text'\n\nattribute({\n name: 'style',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, rx }) {\n const { style } = el\n const initialStyles = new Map()\n\n const apply = (prop: string, value: any) => {\n const initial = initialStyles.get(prop)\n if (!value && value !== 0) {\n initial !== undefined &&\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n } else {\n initial === undefined &&\n initialStyles.set(prop, style.getPropertyValue(prop))\n style.setProperty(prop, String(value))\n }\n }\n\n const update = () => {\n observer.disconnect()\n\n if (key) {\n apply(key, rx())\n } else {\n const styles = rx() as Record\n\n for (const [prop, initial] of initialStyles) {\n prop in styles ||\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n }\n\n for (const prop in styles) {\n apply(kebab(prop), styles[prop])\n }\n }\n\n observer.observe(el, { attributeFilter: ['style'] })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n for (const [prop, initial] of initialStyles) {\n initial ? style.setProperty(prop, initial) : style.removeProperty(prop)\n }\n }\n },\n})\n", "// Icon: icon-park-outline:text\n// Slug: Binds the text content of an element.\n// Description: Binds the text content of an element to an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'text',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n el.textContent = `${rx()}`\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: material-symbols:cloud-download\n// Slug: Patches elements into the DOM.\n// Description: Patches elements into the DOM.\n\nimport { watcher } from '@engine'\nimport type { WatcherContext } from '@engine/types'\nimport { morph } from '@engine/morph'\nimport { supportsViewTransitions } from '@utils/view-transitions'\n\ntype PatchElementsMode =\n | 'remove'\n | 'outer'\n | 'inner'\n | 'replace'\n | 'prepend'\n | 'append'\n | 'before'\n | 'after'\n\ntype PatchElementsArgs = {\n elements: string\n mode: PatchElementsMode\n selector: string\n useViewTransition: boolean\n}\n\nwatcher({\n name: 'datastar-patch-elements',\n apply(\n ctx,\n { elements = '', selector = '', mode = 'outer', useViewTransition },\n ) {\n switch (mode) {\n case 'remove':\n case 'outer':\n case 'inner':\n case 'replace':\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n break\n default:\n throw ctx.error('PatchElementsInvalidMode', { mode })\n }\n\n if (!selector && mode !== 'outer' && mode !== 'replace') {\n throw ctx.error('PatchElementsExpectedSelector')\n }\n\n const args2: PatchElementsArgs = {\n mode,\n selector,\n elements,\n useViewTransition: useViewTransition?.trim() === 'true',\n }\n\n if (supportsViewTransitions && useViewTransition) {\n document.startViewTransition(() => onPatchElements(ctx, args2))\n } else {\n onPatchElements(ctx, args2)\n }\n },\n})\n\nconst onPatchElements = (\n { error }: WatcherContext,\n { elements, selector, mode }: PatchElementsArgs,\n) => {\n const elementsWithSvgsRemoved = elements.replace(\n /]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n '',\n )\n const hasHtml = /<\\/html>/.test(elementsWithSvgsRemoved)\n const hasHead = /<\\/head>/.test(elementsWithSvgsRemoved)\n const hasBody = /<\\/body>/.test(elementsWithSvgsRemoved)\n\n const newDocument = new DOMParser().parseFromString(\n hasHtml || hasHead || hasBody\n ? elements\n : ``,\n 'text/html',\n )\n\n let newContent = document.createDocumentFragment()\n if (hasHtml) {\n newContent.appendChild(newDocument.documentElement)\n } else if (hasHead && hasBody) {\n newContent.appendChild(newDocument.head)\n newContent.appendChild(newDocument.body)\n } else if (hasHead) {\n newContent.appendChild(newDocument.head)\n } else if (hasBody) {\n newContent.appendChild(newDocument.body)\n } else {\n newContent = newDocument.querySelector('template')!.content\n }\n\n if (!selector && (mode === 'outer' || mode === 'replace')) {\n for (const child of newContent.children) {\n let target: Element\n if (child instanceof HTMLHtmlElement) {\n target = document.documentElement\n } else if (child instanceof HTMLBodyElement) {\n target = document.body\n } else if (child instanceof HTMLHeadElement) {\n target = document.head\n } else {\n target = document.getElementById(child.id)!\n if (!target) {\n console.warn(error('PatchElementsNoTargetsFound'), {\n element: { id: child.id },\n })\n continue\n }\n }\n\n applyToTargets(mode as PatchElementsMode, child, [target])\n }\n } else {\n const targets = document.querySelectorAll(selector)\n if (!targets.length) {\n console.warn(error('PatchElementsNoTargetsFound'), { selector })\n return\n }\n\n applyToTargets(mode as PatchElementsMode, newContent, targets)\n }\n}\n\nconst scripts = new WeakSet()\nfor (const script of document.querySelectorAll('script')) {\n scripts.add(script)\n}\n\nconst execute = (target: Element): void => {\n const elScripts =\n target instanceof HTMLScriptElement\n ? [target]\n : target.querySelectorAll('script')\n for (const old of elScripts) {\n if (!scripts.has(old)) {\n const script = document.createElement('script')\n for (const { name, value } of old.attributes) {\n script.setAttribute(name, value)\n }\n script.text = old.text\n old.replaceWith(script)\n scripts.add(script)\n }\n }\n}\n\nconst applyPatchMode = (\n targets: Iterable,\n element: DocumentFragment | Element,\n action: string,\n) => {\n for (const target of targets) {\n const cloned = element.cloneNode(true) as Element\n execute(cloned)\n // @ts-expect-error\n target[action](cloned)\n }\n}\n\nconst applyToTargets = (\n mode: PatchElementsMode,\n element: DocumentFragment | Element,\n targets: Iterable,\n) => {\n switch (mode) {\n case 'remove':\n for (const target of targets) {\n target.remove()\n }\n break\n case 'outer':\n case 'inner':\n for (const target of targets) {\n morph(target, element.cloneNode(true) as Element, mode)\n execute(target)\n }\n break\n case 'replace':\n applyPatchMode(targets, element, 'replaceWith')\n break\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n applyPatchMode(targets, element, mode)\n }\n}\n", "// Icon: material-symbols:settings-input-antenna\n// Slug: Patches signals.\n// Description: Patches signals.\n\nimport { watcher } from '@engine'\nimport { mergePatch } from '@engine/signals'\nimport { jsStrToObject } from '@utils/text'\n\nwatcher({\n name: 'datastar-patch-signals',\n apply({ error }, { signals, onlyIfMissing }) {\n if (signals) {\n const ifMissing = onlyIfMissing?.trim() === 'true'\n mergePatch(jsStrToObject(signals), { ifMissing })\n } else {\n throw error('PatchSignalsExpectedSignals')\n }\n },\n})\n"], + "mappings": "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", + "names": ["lol", "DSP", "DSS", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "kebab", "str", "snake", "str", "kebab", "jsStrToObject", "raw", "caseFns", "str", "x", "modifyCasing", "mods", "defaultCase", "c", "aliasify", "name", "hasOwn", "isPojo", "obj", "isEmpty", "prop", "hasOwn", "updateLeaves", "fn", "key", "val", "pathToObj", "paths", "result", "path", "value", "keys", "lastKey", "acc", "currentPatch", "queuedEffects", "batchDepth", "notifyIndex", "queuedEffectsLength", "prevSub", "activeSub", "version", "beginBatch", "endBatch", "flush", "dispatch", "startPeeking", "sub", "stopPeeking", "signal", "initialValue", "signalOper", "value_", "flags_", "computedSymbol", "computed", "getter", "c", "computedOper", "effect", "fn", "e", "fn_", "link", "effectOper", "run", "update", "updateComputed", "updateSignal", "startTracking", "oldValue", "endTracking", "s", "value", "notify", "flags", "subs", "subs_", "sub_", "checkDirty", "deps_", "dep", "dep_", "depFlags", "nextDep_", "propagate", "currentValue", "shallowPropagate", "unlink", "prevDep", "depsTail_", "nextDep", "version_", "subsTail_", "newLink", "prevDep_", "prevSub_", "nextSub_", "toRemove", "next", "stack", "top", "isValidLink", "subSubs", "nextSub", "prev_", "checkDepth", "dirty", "firstSub", "hasMultipleSubs", "checkLink", "getPath", "path", "result", "root", "split", "hasOwn", "deep", "prefix", "isArr", "isPojo", "deepObj", "key", "keys", "_", "prop", "newValue", "diff", "patch", "i", "detail", "pathToObj", "DATASTAR_SIGNAL_PATCH_EVENT", "mergePatch", "ifMissing", "mergeInner", "mergePaths", "paths", "options", "target", "targetParent", "toRegExp", "val", "filtered", "include", "exclude", "obj", "includeRe", "excludeRe", "node", "isHTMLOrSVG", "el", "url", "error", "ctx", "reason", "metadata", "e", "r", "snake", "q", "c", "actionPlugins", "attributePlugins", "watcherPlugins", "actions", "_", "prop", "removals", "queuedAttributes", "queuedAttributeNames", "attribute", "plugin", "apply", "action", "DATASTAR_FETCH_EVENT", "evt", "watcher", "cleanupEls", "els", "el", "cleanups", "cleanup", "aliasedIgnore", "aliasify", "aliasedIgnoreAttr", "shouldIgnore", "applyEls", "onlyNew", "key", "applyAttributePlugin", "observe", "mutations", "target", "type", "attributeName", "addedNodes", "removedNodes", "node", "isHTMLOrSVG", "value", "mutationObserver", "root", "attrKey", "rawKey", "namePart", "rawModifiers", "pluginName", "keyReq", "valueReq", "cachedRx", "args", "genRx", "rawMod", "label", "mod", "returnsValue", "argNames", "expr", "statementRe", "statements", "lastIdx", "last", "escaped", "escapeRe", "DSP", "DSS", "counter", "match", "k", "v", "signalName", "acc", "part", "varName", "fn", "name", "err", "ctxIdMap", "ctxPersistentIds", "oldIdTagNameMap", "duplicateIds", "ctxPantry", "aliasedIgnoreMorph", "aliasify", "aliasedIgnoreMorphAttr", "morph", "oldElt", "newContent", "mode", "isHTMLOrSVG", "normalizedElt", "oldIdElements", "id", "tagName", "newIdElements", "parent", "populateIdMapWithTree", "morphChildren", "oldParent", "newParent", "insertionPoint", "endPoint", "newChild", "bestMatch", "findBestMatch", "cursor", "tempNode", "removeNode", "morphNode", "movedChild", "current", "idSet", "moveBefore", "newEmptyChild", "newClonedChild", "node", "startPoint", "nextSibling", "siblingSoftMatchCount", "displaceMatchCount", "nodeMatchCount", "isSoftMatch", "isIdSetMatch", "oldSet", "newSet", "oldNode", "newNode", "aliasedPreserveAttr", "type", "newElt", "preserveAttrs", "name", "value", "i", "root", "elements", "elt", "action", "_", "fn", "startPeeking", "stopPeeking", "action", "_", "value", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "mergePatch", "stopPeeking", "action", "_", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "oldValue", "mergePatch", "stopPeeking", "fetchAbortControllers", "createHttpMethod", "name", "method", "action", "el", "evt", "error", "url", "selector", "userHeaders", "contentType", "include", "exclude", "openWhenHidden", "retryInterval", "retryScaler", "retryMaxWaitMs", "retryMaxCount", "requestCancellation", "controller", "isDisabled", "oldController", "observer", "mutations", "mutation", "removed", "cleanupFn", "initialHeaders", "headers", "req", "response", "dispatchFetch", "ERROR", "type", "argsRawLines", "line", "i", "v", "argsRaw", "k", "isWrongContent", "RETRYING", "urlInstance", "queryParams", "res", "filtered", "formEl", "formData", "submitter", "preventDefault", "multipart", "formParams", "key", "value", "STARTED", "fetchEventSource", "e", "FINISHED", "RETRIES_FAILED", "DATASTAR_FETCH_EVENT", "err", "getBytes", "stream", "onChunk", "reader", "result", "getLines", "onLine", "buffer", "position", "fieldLength", "discardTrailingNewline", "arr", "concat", "bufLength", "lineStart", "lineEnd", "getMessages", "onId", "onRetry", "onMessage", "message", "newMessage", "decoder", "field", "valueOffset", "retry", "a", "b", "input", "inputSignal", "inputHeaders", "inputOnOpen", "onmessage", "onclose", "onerror", "inputFetch", "overrides", "rest", "resolve", "reject", "curRequestController", "onVisibilityChange", "create", "retryTimer", "dispose", "fetch", "onopen", "retries", "baseRetryInterval", "dispatchNonSSE", "dispatchType", "argNames", "n", "kebab", "o", "ct", "script", "scriptAttributesHeader", "id", "interval", "innerErr", "attribute", "el", "key", "rx", "syncAttr", "val", "update", "observer", "obj", "attributeFilter", "cleanup", "effect", "dataURIRegex", "empty", "aliasedBind", "aliasify", "attribute", "el", "key", "mods", "value", "error", "signalName", "modifyCasing", "get", "type", "set", "syncSignal", "files", "signalFiles", "f", "resolve", "reader", "match", "mergePaths", "typeMap", "option", "initialValue", "getPath", "path", "signalNameKebab", "inputs", "paths", "i", "input", "signalValue", "cleanup", "effect", "attribute", "key", "el", "mods", "rx", "modifyCasing", "callback", "observer", "classes", "k", "classNames", "cn", "name", "cleanup", "effect", "attribute", "key", "mods", "rx", "error", "mergePaths", "modifyCasing", "computed", "patch", "updateLeaves", "old", "mergePatch", "attribute", "rx", "effect", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "watcher", "event", "type", "elt", "STARTED", "FINISHED", "DATASTAR_FETCH_EVENT", "attribute", "el", "value", "mods", "spaces", "filters", "jsStrToObject", "callback", "observer", "filtered", "cleanup", "effect", "tagToMs", "args", "arg", "tagHas", "tags", "tag", "defaultValue", "delay", "callback", "wait", "args", "debounce", "leading", "trailing", "timer", "throttle", "waiting", "modifyTiming", "mods", "delayArgs", "tagToMs", "debounceArgs", "tagHas", "throttleArgs", "supportsViewTransitions", "modifyViewTransition", "callback", "mods", "cb", "args", "attribute", "el", "key", "mods", "rx", "target", "callback", "evt", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "evtListOpts", "cb", "eventName", "modifyCasing", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "once", "attribute", "el", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "options", "observer", "entries", "entry", "attribute", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "duration", "durationArgs", "tagToMs", "tagHas", "intervalId", "attribute", "rx", "mods", "callback", "beginBatch", "endBatch", "modifyViewTransition", "wait", "delayArgs", "tagToMs", "delay", "attribute", "el", "key", "mods", "rx", "error", "filtersRaw", "filters", "jsStrToObject", "callback", "modifyTiming", "evt", "watched", "filtered", "isEmpty", "beginBatch", "endBatch", "DATASTAR_SIGNAL_PATCH_EVENT", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "NONE", "DISPLAY", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "attribute", "key", "mods", "rx", "ifMissing", "modifyCasing", "mergePaths", "patch", "mergePatch", "attribute", "key", "el", "rx", "style", "initialStyles", "apply", "prop", "value", "initial", "update", "observer", "styles", "kebab", "cleanup", "effect", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "watcher", "ctx", "elements", "selector", "mode", "useViewTransition", "args2", "supportsViewTransitions", "onPatchElements", "error", "elementsWithSvgsRemoved", "hasHtml", "hasHead", "hasBody", "newDocument", "newContent", "child", "target", "applyToTargets", "targets", "scripts", "script", "execute", "elScripts", "old", "name", "value", "applyPatchMode", "element", "action", "cloned", "morph", "watcher", "error", "signals", "onlyIfMissing", "ifMissing", "mergePatch", "jsStrToObject"] +} diff --git a/hypermedia/1-example/deleted-record1.html b/hypermedia/1-example/deleted-record1.html new file mode 100644 index 0000000..4b5d3e1 --- /dev/null +++ b/hypermedia/1-example/deleted-record1.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hypermedia/1-example/deleted-record2.html b/hypermedia/1-example/deleted-record2.html new file mode 100644 index 0000000..848a956 --- /dev/null +++ b/hypermedia/1-example/deleted-record2.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hypermedia/1-example/deleted-record3.html b/hypermedia/1-example/deleted-record3.html new file mode 100644 index 0000000..d94934b --- /dev/null +++ b/hypermedia/1-example/deleted-record3.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hypermedia/1-example/display-record1.html b/hypermedia/1-example/display-record1.html new file mode 100644 index 0000000..e2891d4 --- /dev/null +++ b/hypermedia/1-example/display-record1.html @@ -0,0 +1,40 @@ +
+
+

Leanne Graham

+

@Bret

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
\ No newline at end of file diff --git a/hypermedia/1-example/display-record2.html b/hypermedia/1-example/display-record2.html new file mode 100644 index 0000000..a7efc98 --- /dev/null +++ b/hypermedia/1-example/display-record2.html @@ -0,0 +1,40 @@ +
+
+

Ervin Howell

+

@Antonette

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
\ No newline at end of file diff --git a/hypermedia/1-example/display-record3.html b/hypermedia/1-example/display-record3.html new file mode 100644 index 0000000..cd0eddd --- /dev/null +++ b/hypermedia/1-example/display-record3.html @@ -0,0 +1,40 @@ +
+
+

Clementine Bauch

+

@Samantha

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
\ No newline at end of file diff --git a/hypermedia/1-example/edit-record1.html b/hypermedia/1-example/edit-record1.html new file mode 100644 index 0000000..57a67f5 --- /dev/null +++ b/hypermedia/1-example/edit-record1.html @@ -0,0 +1,40 @@ +
+
+

Leanne Graham

+

@Bret

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
\ No newline at end of file diff --git a/hypermedia/1-example/edit-record2.html b/hypermedia/1-example/edit-record2.html new file mode 100644 index 0000000..98d074e --- /dev/null +++ b/hypermedia/1-example/edit-record2.html @@ -0,0 +1,40 @@ +
+
+

Ervin Howell

+

@Antonette

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
\ No newline at end of file diff --git a/hypermedia/1-example/edit-record3.html b/hypermedia/1-example/edit-record3.html new file mode 100644 index 0000000..bd1f35b --- /dev/null +++ b/hypermedia/1-example/edit-record3.html @@ -0,0 +1,40 @@ +
+
+

Clementine Bauch

+

@Samantha

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
\ No newline at end of file diff --git a/hypermedia/1-example/index.html b/hypermedia/1-example/index.html new file mode 100644 index 0000000..8c796ab --- /dev/null +++ b/hypermedia/1-example/index.html @@ -0,0 +1,23 @@ + + + + + + + Hypermedia + + + + + +

Hypermedia as the Engine of Application State

+ +
+
+
+
+
+ + + + diff --git a/hypermedia/1-example/pico.blue.css b/hypermedia/1-example/pico.blue.css new file mode 100644 index 0000000..acb44ef --- /dev/null +++ b/hypermedia/1-example/pico.blue.css @@ -0,0 +1,2802 @@ +@charset "UTF-8"; +/*! + * Pico CSS ✨ v2.0.6 (https://picocss.com) + * Copyright 2019-2024 - Licensed under MIT + */ +/** + * Styles + */ +:root { + --pico-font-family-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --pico-font-family-sans-serif: system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, Helvetica, Arial, "Helvetica Neue", sans-serif, var(--pico-font-family-emoji); + --pico-font-family-monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace, var(--pico-font-family-emoji); + --pico-font-family: var(--pico-font-family-sans-serif); + --pico-line-height: 1.5; + --pico-font-weight: 400; + --pico-font-size: 100%; + --pico-text-underline-offset: 0.1rem; + --pico-border-radius: 0.25rem; + --pico-border-width: 0.0625rem; + --pico-outline-width: 0.125rem; + --pico-transition: 0.2s ease-in-out; + --pico-spacing: 1rem; + --pico-typography-spacing-vertical: 1rem; + --pico-block-spacing-vertical: var(--pico-spacing); + --pico-block-spacing-horizontal: var(--pico-spacing); + --pico-grid-column-gap: var(--pico-spacing); + --pico-grid-row-gap: var(--pico-spacing); + --pico-form-element-spacing-vertical: 0.75rem; + --pico-form-element-spacing-horizontal: 1rem; + --pico-group-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); + --pico-group-box-shadow-focus-with-input: 0 0 0 0.0625rem var(--pico-form-element-border-color); + --pico-modal-overlay-backdrop-filter: blur(0.375rem); + --pico-nav-element-spacing-vertical: 1rem; + --pico-nav-element-spacing-horizontal: 0.5rem; + --pico-nav-link-spacing-vertical: 0.5rem; + --pico-nav-link-spacing-horizontal: 0.5rem; + --pico-nav-breadcrumb-divider: ">"; + --pico-icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-loading: url("data:image/svg+xml,%3Csvg fill='none' height='24' width='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' %3E%3Cstyle%3E g %7B animation: rotate 2s linear infinite; transform-origin: center center; %7D circle %7B stroke-dasharray: 75,100; stroke-dashoffset: -5; animation: dash 1.5s ease-in-out infinite; stroke-linecap: round; %7D @keyframes rotate %7B 0%25 %7B transform: rotate(0deg); %7D 100%25 %7B transform: rotate(360deg); %7D %7D @keyframes dash %7B 0%25 %7B stroke-dasharray: 1,100; stroke-dashoffset: 0; %7D 50%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -17.5; %7D 100%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -62; %7D %7D %3C/style%3E%3Cg%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='rgb(136, 145, 164)' stroke-width='4' /%3E%3C/g%3E%3C/svg%3E"); +} +@media (min-width: 576px) { + :root { + --pico-font-size: 106.25%; + } +} +@media (min-width: 768px) { + :root { + --pico-font-size: 112.5%; + } +} +@media (min-width: 1024px) { + :root { + --pico-font-size: 118.75%; + } +} +@media (min-width: 1280px) { + :root { + --pico-font-size: 125%; + } +} +@media (min-width: 1536px) { + :root { + --pico-font-size: 131.25%; + } +} + +a { + --pico-text-decoration: underline; +} +a.secondary, a.contrast { + --pico-text-decoration: underline; +} + +small { + --pico-font-size: 0.875em; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + --pico-font-weight: 700; +} + +h1 { + --pico-font-size: 2rem; + --pico-line-height: 1.125; + --pico-typography-spacing-top: 3rem; +} + +h2 { + --pico-font-size: 1.75rem; + --pico-line-height: 1.15; + --pico-typography-spacing-top: 2.625rem; +} + +h3 { + --pico-font-size: 1.5rem; + --pico-line-height: 1.175; + --pico-typography-spacing-top: 2.25rem; +} + +h4 { + --pico-font-size: 1.25rem; + --pico-line-height: 1.2; + --pico-typography-spacing-top: 1.874rem; +} + +h5 { + --pico-font-size: 1.125rem; + --pico-line-height: 1.225; + --pico-typography-spacing-top: 1.6875rem; +} + +h6 { + --pico-font-size: 1rem; + --pico-line-height: 1.25; + --pico-typography-spacing-top: 1.5rem; +} + +thead th, +thead td, +tfoot th, +tfoot td { + --pico-font-weight: 600; + --pico-border-width: 0.1875rem; +} + +pre, +code, +kbd, +samp { + --pico-font-family: var(--pico-font-family-monospace); +} + +kbd { + --pico-font-weight: bolder; +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:where(select, textarea) { + --pico-outline-width: 0.0625rem; +} + +[type=search] { + --pico-border-radius: 5rem; +} + +[type=checkbox], +[type=radio] { + --pico-border-width: 0.125rem; +} + +[type=checkbox][role=switch] { + --pico-border-width: 0.1875rem; +} + +details.dropdown summary:not([role=button]) { + --pico-outline-width: 0.0625rem; +} + +nav details.dropdown summary:focus-visible { + --pico-outline-width: 0.125rem; +} + +[role=search] { + --pico-border-radius: 5rem; +} + +[role=search]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus), +[role=group]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} +[role=search]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus), +[role=group]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=button], +[role=group] [role=button] { + --pico-form-element-spacing-horizontal: 2rem; +} + +details summary[role=button]:not(.outline)::after { + filter: brightness(0) invert(1); +} + +[aria-busy=true]:not(input, select, textarea):is(button, [type=submit], [type=button], [type=reset], [role=button]):not(.outline)::before { + filter: brightness(0) invert(1); +} + +/** + * Color schemes + */ +[data-theme=light], +:root:not([data-theme=dark]) { + --pico-background-color: #fff; + --pico-color: #373c44; + --pico-text-selection-color: rgba(116, 139, 248, 0.25); + --pico-muted-color: #646b79; + --pico-muted-border-color: #e7eaf0; + --pico-primary: #2060df; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(32, 96, 223, 0.5); + --pico-primary-hover: #184eb8; + --pico-primary-hover-background: #1d59d0; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(116, 139, 248, 0.5); + --pico-primary-inverse: #fff; + --pico-secondary: #5d6b89; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(93, 107, 137, 0.5); + --pico-secondary-hover: #48536b; + --pico-secondary-hover-background: #48536b; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(93, 107, 137, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #181c25; + --pico-contrast-background: #181c25; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(24, 28, 37, 0.5); + --pico-contrast-hover: #000; + --pico-contrast-hover-background: #000; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-secondary-hover); + --pico-contrast-focus: rgba(93, 107, 137, 0.25); + --pico-contrast-inverse: #fff; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(129, 145, 181, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(129, 145, 181, 0.024), 0.0625rem 0.125rem 0.75rem rgba(129, 145, 181, 0.03), 0.1125rem 0.225rem 1.35rem rgba(129, 145, 181, 0.036), 0.2085rem 0.417rem 2.502rem rgba(129, 145, 181, 0.04302), 0.5rem 1rem 6rem rgba(129, 145, 181, 0.06), 0 0 0 0.0625rem rgba(129, 145, 181, 0.015); + --pico-h1-color: #2d3138; + --pico-h2-color: #373c44; + --pico-h3-color: #424751; + --pico-h4-color: #4d535e; + --pico-h5-color: #5c6370; + --pico-h6-color: #646b79; + --pico-mark-background-color: #fde7c0; + --pico-mark-color: #0f1114; + --pico-ins-color: #1d6a54; + --pico-del-color: #883935; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #f3f5f7; + --pico-code-color: #646b79; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #fbfcfc; + --pico-form-element-selected-background-color: #dfe3eb; + --pico-form-element-border-color: #cfd5e2; + --pico-form-element-color: #23262c; + --pico-form-element-placeholder-color: var(--pico-muted-color); + --pico-form-element-active-background-color: #fff; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #b86a6b; + --pico-form-element-invalid-active-border-color: #c84f48; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #4c9b8a; + --pico-form-element-valid-active-border-color: #279977; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #bfc7d9; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #dfe3eb; + --pico-range-active-border-color: #bfc7d9; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: var(--pico-background-color); + --pico-card-border-color: var(--pico-muted-border-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #fbfcfc; + --pico-dropdown-background-color: #fff; + --pico-dropdown-border-color: #eff1f4; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #eff1f4; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(232, 234, 237, 0.75); + --pico-progress-background-color: #dfe3eb; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(76, 155, 138)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(200, 79, 72)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: light; +} +[data-theme=light] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:root:not([data-theme=dark]) input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} + +@media only screen and (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; + } + :root:not([data-theme]) input:is([type=submit], + [type=button], + [type=reset], + [type=checkbox], + [type=radio], + [type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); + } + :root:not([data-theme]) details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); + } + :root:not([data-theme]) [aria-busy=true]:not(input, select, textarea).contrast:is(button, + [type=submit], + [type=button], + [type=reset], + [role=button]):not(.outline)::before { + filter: brightness(0); + } +} +[data-theme=dark] { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; +} +[data-theme=dark] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} +[data-theme=dark] details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); +} +[data-theme=dark] [aria-busy=true]:not(input, select, textarea).contrast:is(button, +[type=submit], +[type=button], +[type=reset], +[role=button]):not(.outline)::before { + filter: brightness(0); +} + +progress, +[type=checkbox], +[type=radio], +[type=range] { + accent-color: var(--pico-primary); +} + +/** + * Document + * Content-box & Responsive typography + */ +*, +*::before, +*::after { + box-sizing: border-box; + background-repeat: no-repeat; +} + +::before, +::after { + text-decoration: inherit; + vertical-align: inherit; +} + +:where(:root) { + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); + text-underline-offset: var(--pico-text-underline-offset); + text-rendering: optimizeLegibility; + overflow-wrap: break-word; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; +} + +/** + * Landmarks + */ +body { + width: 100%; + margin: 0; +} + +main { + display: block; +} + +body > header, +body > main, +body > footer { + padding-block: var(--pico-block-spacing-vertical); +} + +/** + * Section + */ +section { + margin-bottom: var(--pico-block-spacing-vertical); +} + +/** + * Container + */ +.container, +.container-fluid { + width: 100%; + margin-right: auto; + margin-left: auto; + padding-right: var(--pico-spacing); + padding-left: var(--pico-spacing); +} + +@media (min-width: 576px) { + .container { + max-width: 510px; + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .container { + max-width: 700px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 950px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1200px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1450px; + } +} + +/** + * Grid + * Minimal grid system with auto-layout columns + */ +.grid { + grid-column-gap: var(--pico-grid-column-gap); + grid-row-gap: var(--pico-grid-row-gap); + display: grid; + grid-template-columns: 1fr; +} +@media (min-width: 768px) { + .grid { + grid-template-columns: repeat(auto-fit, minmax(0%, 1fr)); + } +} +.grid > * { + min-width: 0; +} + +/** + * Overflow auto + */ +.overflow-auto { + overflow: auto; +} + +/** + * Typography + */ +b, +strong { + font-weight: bolder; +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +address, +blockquote, +dl, +ol, +p, +pre, +table, +ul { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-style: normal; + font-weight: var(--pico-font-weight); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); +} + +h1 { + --pico-color: var(--pico-h1-color); +} + +h2 { + --pico-color: var(--pico-h2-color); +} + +h3 { + --pico-color: var(--pico-h3-color); +} + +h4 { + --pico-color: var(--pico-h4-color); +} + +h5 { + --pico-color: var(--pico-h5-color); +} + +h6 { + --pico-color: var(--pico-h6-color); +} + +:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) { + margin-top: var(--pico-typography-spacing-top); +} + +p { + margin-bottom: var(--pico-typography-spacing-vertical); +} + +hgroup { + margin-bottom: var(--pico-typography-spacing-vertical); +} +hgroup > * { + margin-top: 0; + margin-bottom: 0; +} +hgroup > *:not(:first-child):last-child { + --pico-color: var(--pico-muted-color); + --pico-font-weight: unset; + font-size: 1rem; +} + +:where(ol, ul) li { + margin-bottom: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +:where(dl, ol, ul) :where(dl, ol, ul) { + margin: 0; + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +ul li { + list-style: square; +} + +mark { + padding: 0.125rem 0.25rem; + background-color: var(--pico-mark-background-color); + color: var(--pico-mark-color); + vertical-align: baseline; +} + +blockquote { + display: block; + margin: var(--pico-typography-spacing-vertical) 0; + padding: var(--pico-spacing); + border-right: none; + border-left: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-start: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-end: none; +} +blockquote footer { + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.5); + color: var(--pico-blockquote-footer-color); +} + +abbr[title] { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} + +ins { + color: var(--pico-ins-color); + text-decoration: none; +} + +del { + color: var(--pico-del-color); +} + +::-moz-selection { + background-color: var(--pico-text-selection-color); +} + +::selection { + background-color: var(--pico-text-selection-color); +} + +/** + * Link + */ +:where(a:not([role=button])), +[role=link] { + --pico-color: var(--pico-primary); + --pico-background-color: transparent; + --pico-underline: var(--pico-primary-underline); + outline: none; + background-color: var(--pico-background-color); + color: var(--pico-color); + -webkit-text-decoration: var(--pico-text-decoration); + text-decoration: var(--pico-text-decoration); + text-decoration-color: var(--pico-underline); + text-underline-offset: 0.125em; + transition: background-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); +} +:where(a:not([role=button])):is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-primary-hover); + --pico-underline: var(--pico-primary-hover-underline); + --pico-text-decoration: underline; +} +:where(a:not([role=button])):focus-visible, +[role=link]:focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} +:where(a:not([role=button])).secondary, +[role=link].secondary { + --pico-color: var(--pico-secondary); + --pico-underline: var(--pico-secondary-underline); +} +:where(a:not([role=button])).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-underline: var(--pico-secondary-hover-underline); +} +:where(a:not([role=button])).contrast, +[role=link].contrast { + --pico-color: var(--pico-contrast); + --pico-underline: var(--pico-contrast-underline); +} +:where(a:not([role=button])).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-underline: var(--pico-contrast-hover-underline); +} + +a[role=button] { + display: inline-block; +} + +/** + * Button + */ +button { + margin: 0; + overflow: visible; + font-family: inherit; + text-transform: none; +} + +button, +[type=submit], +[type=reset], +[type=button] { + -webkit-appearance: button; +} + +button, +[type=submit], +[type=reset], +[type=button], +[type=file]::file-selector-button, +[role=button] { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + --pico-color: var(--pico-primary-inverse); + --pico-box-shadow: var(--pico-button-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: 1rem; + line-height: var(--pico-line-height); + text-align: center; + text-decoration: none; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +button:is([aria-current]:not([aria-current=false])), button:is(:hover, :active, :focus), +[type=submit]:is([aria-current]:not([aria-current=false])), +[type=submit]:is(:hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false])), +[type=reset]:is(:hover, :active, :focus), +[type=button]:is([aria-current]:not([aria-current=false])), +[type=button]:is(:hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])), +[type=file]::file-selector-button:is(:hover, :active, :focus), +[role=button]:is([aria-current]:not([aria-current=false])), +[role=button]:is(:hover, :active, :focus) { + --pico-background-color: var(--pico-primary-hover-background); + --pico-border-color: var(--pico-primary-hover-border); + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + --pico-color: var(--pico-primary-inverse); +} +button:focus, button:is([aria-current]:not([aria-current=false])):focus, +[type=submit]:focus, +[type=submit]:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=button]:focus, +[type=button]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus, +[role=button]:focus, +[role=button]:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +[type=submit], +[type=reset], +[type=button] { + margin-bottom: var(--pico-spacing); +} + +:is(button, [type=submit], [type=button], [role=button]).secondary, +[type=reset], +[type=file]::file-selector-button { + --pico-background-color: var(--pico-secondary-background); + --pico-border-color: var(--pico-secondary-border); + --pico-color: var(--pico-secondary-inverse); + cursor: pointer; +} +:is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); + --pico-color: var(--pico-secondary-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).secondary:focus, :is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).contrast { + --pico-background-color: var(--pico-contrast-background); + --pico-border-color: var(--pico-contrast-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-contrast-hover-background); + --pico-border-color: var(--pico-contrast-hover-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:focus, :is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).outline, +[type=reset].outline { + --pico-background-color: transparent; + --pico-color: var(--pico-primary); + --pico-border-color: var(--pico-primary); +} +:is(button, [type=submit], [type=button], [role=button]).outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: transparent; + --pico-color: var(--pico-primary-hover); + --pico-border-color: var(--pico-primary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.secondary, +[type=reset].outline { + --pico-color: var(--pico-secondary); + --pico-border-color: var(--pico-secondary); +} +:is(button, [type=submit], [type=button], [role=button]).outline.secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-border-color: var(--pico-secondary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.contrast { + --pico-color: var(--pico-contrast); + --pico-border-color: var(--pico-contrast); +} +:is(button, [type=submit], [type=button], [role=button]).outline.contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-border-color: var(--pico-contrast-hover); +} + +:where(button, [type=submit], [type=reset], [type=button], [role=button])[disabled], +:where(fieldset[disabled]) :is(button, [type=submit], [type=button], [type=reset], [role=button]) { + opacity: 0.5; + pointer-events: none; +} + +/** + * Table + */ +:where(table) { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + text-indent: 0; +} + +th, +td { + padding: calc(var(--pico-spacing) / 2) var(--pico-spacing); + border-bottom: var(--pico-border-width) solid var(--pico-table-border-color); + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + text-align: left; + text-align: start; +} + +tfoot th, +tfoot td { + border-top: var(--pico-border-width) solid var(--pico-table-border-color); + border-bottom: 0; +} + +table.striped tbody tr:nth-child(odd) th, +table.striped tbody tr:nth-child(odd) td { + background-color: var(--pico-table-row-stripped-background-color); +} + +/** + * Embedded content + */ +:where(audio, canvas, iframe, img, svg, video) { + vertical-align: middle; +} + +audio, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +:where(iframe) { + border-style: none; +} + +img { + max-width: 100%; + height: auto; + border-style: none; +} + +:where(svg:not([fill])) { + fill: currentColor; +} + +svg:not(:root) { + overflow: hidden; +} + +/** + * Code + */ +pre, +code, +kbd, +samp { + font-size: 0.875em; + font-family: var(--pico-font-family); +} + +pre code { + font-size: inherit; + font-family: inherit; +} + +pre { + -ms-overflow-style: scrollbar; + overflow: auto; +} + +pre, +code, +kbd { + border-radius: var(--pico-border-radius); + background: var(--pico-code-background-color); + color: var(--pico-code-color); + font-weight: var(--pico-font-weight); + line-height: initial; +} + +code, +kbd { + display: inline-block; + padding: 0.375rem; +} + +pre { + display: block; + margin-bottom: var(--pico-spacing); + overflow-x: auto; +} +pre > code { + display: block; + padding: var(--pico-spacing); + background: none; + line-height: var(--pico-line-height); +} + +kbd { + background-color: var(--pico-code-kbd-background-color); + color: var(--pico-code-kbd-color); + vertical-align: baseline; +} + +/** + * Figure + */ +figure { + display: block; + margin: 0; + padding: 0; +} +figure figcaption { + padding: calc(var(--pico-spacing) * 0.5) 0; + color: var(--pico-muted-color); +} + +/** + * Miscs + */ +hr { + height: 0; + margin: var(--pico-typography-spacing-vertical) 0; + border: 0; + border-top: 1px solid var(--pico-muted-border-color); + color: inherit; +} + +[hidden], +template { + display: none !important; +} + +canvas { + display: inline-block; +} + +/** + * Basics form elements + */ +input, +optgroup, +select, +textarea { + margin: 0; + font-size: 1rem; + line-height: var(--pico-line-height); + font-family: inherit; + letter-spacing: inherit; +} + +input { + overflow: visible; +} + +select { + text-transform: none; +} + +legend { + max-width: 100%; + padding: 0; + color: inherit; + white-space: normal; +} + +textarea { + overflow: auto; +} + +[type=checkbox], +[type=radio] { + padding: 0; +} + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +:-moz-focusring { + outline: none; +} + +:-moz-ui-invalid { + box-shadow: none; +} + +::-ms-expand { + display: none; +} + +[type=file], +[type=range] { + padding: 0; + border-width: 0; +} + +input:not([type=checkbox], [type=radio], [type=range]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); +} + +fieldset { + width: 100%; + margin: 0; + margin-bottom: var(--pico-spacing); + padding: 0; + border: 0; +} + +label, +fieldset legend { + display: block; + margin-bottom: calc(var(--pico-spacing) * 0.375); + color: var(--pico-color); + font-weight: var(--pico-form-label-font-weight, var(--pico-font-weight)); +} + +fieldset legend { + margin-bottom: calc(var(--pico-spacing) * 0.5); +} + +input:not([type=checkbox], [type=radio]), +button[type=submit], +select, +textarea { + width: 100%; +} + +input:not([type=checkbox], [type=radio], [type=range], [type=file]), +select, +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); +} + +input, +select, +textarea { + --pico-background-color: var(--pico-form-element-background-color); + --pico-border-color: var(--pico-form-element-border-color); + --pico-color: var(--pico-form-element-color); + --pico-box-shadow: none; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-background-color: var(--pico-form-element-active-background-color); +} + +input:not([type=submit], [type=button], [type=reset], [role=switch], [readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-border-color: var(--pico-form-element-active-border-color); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=range], +[type=file], +[readonly]):focus, +:where(select, textarea):not([readonly]):focus { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} + +input:not([type=submit], [type=button], [type=reset])[disabled], +select[disabled], +textarea[disabled], +label[aria-disabled=true], +:where(fieldset[disabled]) :is(input:not([type=submit], [type=button], [type=reset]), select, textarea) { + opacity: var(--pico-form-element-disabled-opacity); + pointer-events: none; +} + +label[aria-disabled=true] input[disabled] { + opacity: 1; +} + +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid] { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal) !important; + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=false]:not(select) { + background-image: var(--pico-icon-valid); +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=true]:not(select) { + background-image: var(--pico-icon-invalid); +} +:where(input, select, textarea)[aria-invalid=false] { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-valid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-valid-focus-color) !important; +} +:where(input, select, textarea)[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-invalid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-invalid-focus-color) !important; +} + +[dir=rtl] :where(input, select, textarea):not([type=checkbox], [type=radio]):is([aria-invalid], [aria-invalid=true], [aria-invalid=false]) { + background-position: center left 0.75rem; +} + +input::placeholder, +input::-webkit-input-placeholder, +textarea::placeholder, +textarea::-webkit-input-placeholder, +select:invalid { + color: var(--pico-form-element-placeholder-color); + opacity: 1; +} + +input:not([type=checkbox], [type=radio]), +select, +textarea { + margin-bottom: var(--pico-spacing); +} + +select::-ms-expand { + border: 0; + background-color: transparent; +} +select:not([multiple], [size]) { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal); + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + background-image: var(--pico-icon-chevron); + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +select[multiple] option:checked { + background: var(--pico-form-element-selected-background-color); + color: var(--pico-form-element-color); +} + +[dir=rtl] select:not([multiple], [size]) { + background-position: center left 0.75rem; +} + +textarea { + display: block; + resize: vertical; +} +textarea[aria-invalid] { + --pico-icon-height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + background-position: top right 0.75rem !important; + background-size: 1rem var(--pico-icon-height) !important; +} + +:where(input, select, textarea, fieldset, .grid) + small { + display: block; + width: 100%; + margin-top: calc(var(--pico-spacing) * -0.75); + margin-bottom: var(--pico-spacing); + color: var(--pico-muted-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=false] + small { + color: var(--pico-ins-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=true] + small { + color: var(--pico-del-color); +} + +label > :where(input, select, textarea) { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Checkboxes, Radios and Switches + */ +label:has([type=checkbox], [type=radio]) { + width: -moz-fit-content; + width: fit-content; + cursor: pointer; +} + +[type=checkbox], +[type=radio] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 1.25em; + height: 1.25em; + margin-top: -0.125em; + margin-inline-end: 0.5em; + border-width: var(--pico-border-width); + vertical-align: middle; + cursor: pointer; +} +[type=checkbox]::-ms-check, +[type=radio]::-ms-check { + display: none; +} +[type=checkbox]:checked, [type=checkbox]:checked:active, [type=checkbox]:checked:focus, +[type=radio]:checked, +[type=radio]:checked:active, +[type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-checkbox); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} +[type=checkbox] ~ label, +[type=radio] ~ label { + display: inline-block; + margin-bottom: 0; + cursor: pointer; +} +[type=checkbox] ~ label:not(:last-of-type), +[type=radio] ~ label:not(:last-of-type) { + margin-inline-end: 1em; +} + +[type=checkbox]:indeterminate { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-minus); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} + +[type=radio] { + border-radius: 50%; +} +[type=radio]:checked, [type=radio]:checked:active, [type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-inverse); + border-width: 0.35em; + background-image: none; +} + +[type=checkbox][role=switch] { + --pico-background-color: var(--pico-switch-background-color); + --pico-color: var(--pico-switch-color); + width: 2.25em; + height: 1.25em; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: 1.25em; + background-color: var(--pico-background-color); + line-height: 1.25em; +} +[type=checkbox][role=switch]:not([aria-invalid]) { + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:before { + display: block; + aspect-ratio: 1; + height: 100%; + border-radius: 50%; + background-color: var(--pico-color); + box-shadow: var(--pico-switch-thumb-box-shadow); + content: ""; + transition: margin 0.1s ease-in-out; +} +[type=checkbox][role=switch]:focus { + --pico-background-color: var(--pico-switch-background-color); + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:checked { + --pico-background-color: var(--pico-switch-checked-background-color); + --pico-border-color: var(--pico-switch-checked-background-color); + background-image: none; +} +[type=checkbox][role=switch]:checked::before { + margin-inline-start: calc(2.25em - 1.25em); +} +[type=checkbox][role=switch][disabled] { + --pico-background-color: var(--pico-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-background-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-background-color: var(--pico-form-element-invalid-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=radio][aria-invalid=false]:checked, +[type=radio][aria-invalid=false]:checked:active, +[type=radio][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=radio]:checked[aria-invalid=true], +[type=radio]:checked:active[aria-invalid=true], +[type=radio]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} + +/** + * Input type color + */ +[type=color]::-webkit-color-swatch-wrapper { + padding: 0; +} +[type=color]::-moz-focus-inner { + padding: 0; +} +[type=color]::-webkit-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} +[type=color]::-moz-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} + +/** + * Input type datetime + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file]):is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + --pico-icon-position: 0.75rem; + --pico-icon-width: 1rem; + padding-right: calc(var(--pico-icon-width) + var(--pico-icon-position)); + background-image: var(--pico-icon-date); + background-position: center right var(--pico-icon-position); + background-size: var(--pico-icon-width) auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=time] { + background-image: var(--pico-icon-time); +} + +[type=date]::-webkit-calendar-picker-indicator, +[type=datetime-local]::-webkit-calendar-picker-indicator, +[type=month]::-webkit-calendar-picker-indicator, +[type=time]::-webkit-calendar-picker-indicator, +[type=week]::-webkit-calendar-picker-indicator { + width: var(--pico-icon-width); + margin-right: calc(var(--pico-icon-width) * -1); + margin-left: var(--pico-icon-position); + opacity: 0; +} + +@-moz-document url-prefix() { + [type=date], + [type=datetime-local], + [type=month], + [type=time], + [type=week] { + padding-right: var(--pico-form-element-spacing-horizontal) !important; + background-image: none !important; + } +} +[dir=rtl] :is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + text-align: right; +} + +/** + * Input type file + */ +[type=file] { + --pico-color: var(--pico-muted-color); + margin-left: calc(var(--pico-outline-width) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) 0; + padding-left: var(--pico-outline-width); + border: 0; + border-radius: 0; + background: none; +} +[type=file]::file-selector-button { + margin-right: calc(var(--pico-spacing) / 2); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); +} +[type=file]:is(:hover, :active, :focus)::file-selector-button { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); +} +[type=file]:focus::file-selector-button { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +/** + * Input type range + */ +[type=range] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 100%; + height: 1.25rem; + background: none; +} +[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -webkit-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-moz-range-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -moz-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-ms-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -ms-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -webkit-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-moz-range-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -moz-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-ms-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -ms-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]:active, [type=range]:focus-within { + --pico-range-border-color: var(--pico-range-active-border-color); + --pico-range-thumb-color: var(--pico-range-thumb-active-color); +} +[type=range]:active::-webkit-slider-thumb { + transform: scale(1.25); +} +[type=range]:active::-moz-range-thumb { + transform: scale(1.25); +} +[type=range]:active::-ms-thumb { + transform: scale(1.25); +} + +/** + * Input type search + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem); + background-image: var(--pico-icon-search); + background-position: center left calc(var(--pico-form-element-spacing-horizontal) + 0.125rem); + background-size: 1rem auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem) !important; + background-position: center left 1.125rem, center right 0.75rem; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=false] { + background-image: var(--pico-icon-search), var(--pico-icon-valid); +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=true] { + background-image: var(--pico-icon-search), var(--pico-icon-invalid); +} + +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + background-position: center right 1.125rem; +} +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + background-position: center right 1.125rem, center left 0.75rem; +} + +/** + * Accordion (
) + */ +details { + display: block; + margin-bottom: var(--pico-spacing); +} +details summary { + line-height: 1rem; + list-style-type: none; + cursor: pointer; + transition: color var(--pico-transition); +} +details summary:not([role]) { + color: var(--pico-accordion-close-summary-color); +} +details summary::-webkit-details-marker { + display: none; +} +details summary::marker { + display: none; +} +details summary::-moz-list-bullet { + list-style-type: none; +} +details summary::after { + display: block; + width: 1rem; + height: 1rem; + margin-inline-start: calc(var(--pico-spacing, 1rem) * 0.5); + float: right; + transform: rotate(-90deg); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; + transition: transform var(--pico-transition); +} +details summary:focus { + outline: none; +} +details summary:focus:not([role]) { + color: var(--pico-accordion-active-summary-color); +} +details summary:focus-visible:not([role]) { + outline: var(--pico-outline-width) solid var(--pico-primary-focus); + outline-offset: calc(var(--pico-spacing, 1rem) * 0.5); + color: var(--pico-primary); +} +details summary[role=button] { + width: 100%; + text-align: left; +} +details summary[role=button]::after { + height: calc(1rem * var(--pico-line-height, 1.5)); +} +details[open] > summary { + margin-bottom: var(--pico-spacing); +} +details[open] > summary:not([role]):not(:focus) { + color: var(--pico-accordion-open-summary-color); +} +details[open] > summary::after { + transform: rotate(0); +} + +[dir=rtl] details summary { + text-align: right; +} +[dir=rtl] details summary::after { + float: left; + background-position: left center; +} + +/** + * Card (
) + */ +article { + margin-bottom: var(--pico-block-spacing-vertical); + padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); + border-radius: var(--pico-border-radius); + background: var(--pico-card-background-color); + box-shadow: var(--pico-card-box-shadow); +} +article > header, +article > footer { + margin-right: calc(var(--pico-block-spacing-horizontal) * -1); + margin-left: calc(var(--pico-block-spacing-horizontal) * -1); + padding: calc(var(--pico-block-spacing-vertical) * 0.66) var(--pico-block-spacing-horizontal); + background-color: var(--pico-card-sectioning-background-color); +} +article > header { + margin-top: calc(var(--pico-block-spacing-vertical) * -1); + margin-bottom: var(--pico-block-spacing-vertical); + border-bottom: var(--pico-border-width) solid var(--pico-card-border-color); + border-top-right-radius: var(--pico-border-radius); + border-top-left-radius: var(--pico-border-radius); +} +article > footer { + margin-top: var(--pico-block-spacing-vertical); + margin-bottom: calc(var(--pico-block-spacing-vertical) * -1); + border-top: var(--pico-border-width) solid var(--pico-card-border-color); + border-bottom-right-radius: var(--pico-border-radius); + border-bottom-left-radius: var(--pico-border-radius); +} + +/** + * Dropdown (details.dropdown) + */ +details.dropdown { + position: relative; + border-bottom: none; +} +details.dropdown summary::after, +details.dropdown > button::after, +details.dropdown > a::after { + display: block; + width: 1rem; + height: calc(1rem * var(--pico-line-height, 1.5)); + margin-inline-start: 0.25rem; + float: right; + transform: rotate(0deg) translateX(0.2rem); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; +} + +nav details.dropdown { + margin-bottom: 0; +} + +details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-form-element-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-form-element-background-color); + color: var(--pico-form-element-placeholder-color); + line-height: inherit; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +details.dropdown summary:not([role]):active, details.dropdown summary:not([role]):focus { + border-color: var(--pico-form-element-active-border-color); + background-color: var(--pico-form-element-active-background-color); +} +details.dropdown summary:not([role]):focus { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} +details.dropdown summary:not([role]):focus-visible { + outline: none; +} +details.dropdown summary:not([role])[aria-invalid=false] { + --pico-form-element-border-color: var(--pico-form-element-valid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-valid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-valid-focus-color); +} +details.dropdown summary:not([role])[aria-invalid=true] { + --pico-form-element-border-color: var(--pico-form-element-invalid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-invalid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-invalid-focus-color); +} + +nav details.dropdown { + display: inline; + margin: calc(var(--pico-nav-element-spacing-vertical) * -1) 0; +} +nav details.dropdown summary::after { + transform: rotate(0deg) translateX(0rem); +} +nav details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2); + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav details.dropdown summary:not([role]):focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +details.dropdown summary + ul { + display: flex; + z-index: 99; + position: absolute; + left: 0; + flex-direction: column; + width: 100%; + min-width: -moz-fit-content; + min-width: fit-content; + margin: 0; + margin-top: var(--pico-outline-width); + padding: 0; + border: var(--pico-border-width) solid var(--pico-dropdown-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-dropdown-background-color); + box-shadow: var(--pico-dropdown-box-shadow); + color: var(--pico-dropdown-color); + white-space: nowrap; + opacity: 0; + transition: opacity var(--pico-transition), transform 0s ease-in-out 1s; +} +details.dropdown summary + ul[dir=rtl] { + right: 0; + left: auto; +} +details.dropdown summary + ul li { + width: 100%; + margin-bottom: 0; + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + list-style: none; +} +details.dropdown summary + ul li:first-of-type { + margin-top: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li:last-of-type { + margin-bottom: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li a { + display: block; + margin: calc(var(--pico-form-element-spacing-vertical) * -0.5) calc(var(--pico-form-element-spacing-horizontal) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + overflow: hidden; + border-radius: 0; + color: var(--pico-dropdown-color); + text-decoration: none; + text-overflow: ellipsis; +} +details.dropdown summary + ul li a:hover, details.dropdown summary + ul li a:focus, details.dropdown summary + ul li a:active, details.dropdown summary + ul li a:focus-visible, details.dropdown summary + ul li a[aria-current]:not([aria-current=false]) { + background-color: var(--pico-dropdown-hover-background-color); +} +details.dropdown summary + ul li label { + width: 100%; +} +details.dropdown summary + ul li:has(label):hover { + background-color: var(--pico-dropdown-hover-background-color); +} + +details.dropdown[open] summary { + margin-bottom: 0; +} + +details.dropdown[open] summary + ul { + transform: scaleY(1); + opacity: 1; + transition: opacity var(--pico-transition), transform 0s ease-in-out 0s; +} + +details.dropdown[open] summary::before { + display: block; + z-index: 1; + position: fixed; + width: 100vw; + height: 100vh; + inset: 0; + background: none; + content: ""; + cursor: default; +} + +label > details.dropdown { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Group ([role="group"], [role="search"]) + */ +[role=search], +[role=group] { + display: inline-flex; + position: relative; + width: 100%; + margin-bottom: var(--pico-spacing); + border-radius: var(--pico-border-radius); + box-shadow: var(--pico-group-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + vertical-align: middle; + transition: box-shadow var(--pico-transition); +} +[role=search] > *, +[role=search] input:not([type=checkbox], [type=radio]), +[role=search] select, +[role=group] > *, +[role=group] input:not([type=checkbox], [type=radio]), +[role=group] select { + position: relative; + flex: 1 1 auto; + margin-bottom: 0; +} +[role=search] > *:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] > *:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +[role=search] > *:not(:last-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=search] select:not(:last-child), +[role=group] > *:not(:last-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=group] select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +[role=search] > *:focus, +[role=search] input:not([type=checkbox], [type=radio]):focus, +[role=search] select:focus, +[role=group] > *:focus, +[role=group] input:not([type=checkbox], [type=radio]):focus, +[role=group] select:focus { + z-index: 2; +} +[role=search] button:not(:first-child), +[role=search] [type=submit]:not(:first-child), +[role=search] [type=reset]:not(:first-child), +[role=search] [type=button]:not(:first-child), +[role=search] [role=button]:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] button:not(:first-child), +[role=group] [type=submit]:not(:first-child), +[role=group] [type=reset]:not(:first-child), +[role=group] [type=button]:not(:first-child), +[role=group] [role=button]:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: calc(var(--pico-border-width) * -1); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=reset], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=reset], +[role=group] [type=button], +[role=group] [role=button] { + width: auto; +} +@supports selector(:has(*)) { + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-button); + } + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select, + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select { + border-color: transparent; + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus), + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-input); + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button] { + --pico-button-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-border); + --pico-button-hover-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-hover-border); + } + [role=search] button:focus, + [role=search] [type=submit]:focus, + [role=search] [type=reset]:focus, + [role=search] [type=button]:focus, + [role=search] [role=button]:focus, + [role=group] button:focus, + [role=group] [type=submit]:focus, + [role=group] [type=reset]:focus, + [role=group] [type=button]:focus, + [role=group] [role=button]:focus { + box-shadow: none; + } +} + +[role=search] > *:first-child { + border-top-left-radius: 5rem; + border-bottom-left-radius: 5rem; +} +[role=search] > *:last-child { + border-top-right-radius: 5rem; + border-bottom-right-radius: 5rem; +} + +/** + * Loading ([aria-busy=true]) + */ +[aria-busy=true]:not(input, select, textarea, html) { + white-space: nowrap; +} +[aria-busy=true]:not(input, select, textarea, html)::before { + display: inline-block; + width: 1em; + height: 1em; + background-image: var(--pico-icon-loading); + background-size: 1em auto; + background-repeat: no-repeat; + content: ""; + vertical-align: -0.125em; +} +[aria-busy=true]:not(input, select, textarea, html):not(:empty)::before { + margin-inline-end: calc(var(--pico-spacing) * 0.5); +} +[aria-busy=true]:not(input, select, textarea, html):empty { + text-align: center; +} + +button[aria-busy=true], +[type=submit][aria-busy=true], +[type=button][aria-busy=true], +[type=reset][aria-busy=true], +[role=button][aria-busy=true], +a[aria-busy=true] { + pointer-events: none; +} + +/** + * Modal () + */ +:root { + --pico-scrollbar-width: 0px; +} + +dialog { + display: flex; + z-index: 999; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + align-items: center; + justify-content: center; + width: inherit; + min-width: 100%; + height: inherit; + min-height: 100%; + padding: 0; + border: 0; + -webkit-backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + background-color: var(--pico-modal-overlay-background-color); + color: var(--pico-color); +} +dialog article { + width: 100%; + max-height: calc(100vh - var(--pico-spacing) * 2); + margin: var(--pico-spacing); + overflow: auto; +} +@media (min-width: 576px) { + dialog article { + max-width: 510px; + } +} +@media (min-width: 768px) { + dialog article { + max-width: 700px; + } +} +dialog article > header > * { + margin-bottom: 0; +} +dialog article > header .close, dialog article > header :is(a, button)[rel=prev] { + margin: 0; + margin-left: var(--pico-spacing); + padding: 0; + float: right; +} +dialog article > footer { + text-align: right; +} +dialog article > footer button, +dialog article > footer [role=button] { + margin-bottom: 0; +} +dialog article > footer button:not(:first-of-type), +dialog article > footer [role=button]:not(:first-of-type) { + margin-left: calc(var(--pico-spacing) * 0.5); +} +dialog article .close, dialog article :is(a, button)[rel=prev] { + display: block; + width: 1rem; + height: 1rem; + margin-top: calc(var(--pico-spacing) * -1); + margin-bottom: var(--pico-spacing); + margin-left: auto; + border: none; + background-image: var(--pico-icon-close); + background-position: center; + background-size: auto 1rem; + background-repeat: no-repeat; + background-color: transparent; + opacity: 0.5; + transition: opacity var(--pico-transition); +} +dialog article .close:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), dialog article :is(a, button)[rel=prev]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + opacity: 1; +} +dialog:not([open]), dialog[open=false] { + display: none; +} + +.modal-is-open { + padding-right: var(--pico-scrollbar-width, 0px); + overflow: hidden; + pointer-events: none; + touch-action: none; +} +.modal-is-open dialog { + pointer-events: auto; + touch-action: auto; +} + +:where(.modal-is-opening, .modal-is-closing) dialog, +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-duration: 0.2s; + animation-timing-function: ease-in-out; + animation-fill-mode: both; +} +:where(.modal-is-opening, .modal-is-closing) dialog { + animation-duration: 0.8s; + animation-name: modal-overlay; +} +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-delay: 0.2s; + animation-name: modal; +} + +.modal-is-closing dialog, +.modal-is-closing dialog > article { + animation-delay: 0s; + animation-direction: reverse; +} + +@keyframes modal-overlay { + from { + -webkit-backdrop-filter: none; + backdrop-filter: none; + background-color: transparent; + } +} +@keyframes modal { + from { + transform: translateY(-100%); + opacity: 0; + } +} +/** + * Nav + */ +:where(nav li)::before { + float: left; + content: "​"; +} + +nav, +nav ul { + display: flex; +} + +nav { + justify-content: space-between; + overflow: visible; +} +nav ol, +nav ul { + align-items: center; + margin-bottom: 0; + padding: 0; + list-style: none; +} +nav ol:first-of-type, +nav ul:first-of-type { + margin-left: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav ol:last-of-type, +nav ul:last-of-type { + margin-right: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav li { + display: inline-block; + margin: 0; + padding: var(--pico-nav-element-spacing-vertical) var(--pico-nav-element-spacing-horizontal); +} +nav li :where(a, [role=link]) { + display: inline-block; + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1); + padding: var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal); + border-radius: var(--pico-border-radius); +} +nav li :where(a, [role=link]):not(:hover) { + text-decoration: none; +} +nav li button, +nav li [role=button], +nav li [type=button], +nav li input:not([type=checkbox], [type=radio], [type=range], [type=file]), +nav li select { + height: auto; + margin-right: inherit; + margin-bottom: 0; + margin-left: inherit; + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] { + align-items: center; + justify-content: start; +} +nav[aria-label=breadcrumb] ul li:not(:first-child) { + margin-inline-start: var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] ul li a { + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) 0; + margin-inline-start: calc(var(--pico-nav-link-spacing-horizontal) * -1); +} +nav[aria-label=breadcrumb] ul li:not(:last-child)::after { + display: inline-block; + position: absolute; + width: calc(var(--pico-nav-link-spacing-horizontal) * 4); + margin: 0 calc(var(--pico-nav-link-spacing-horizontal) * -1); + content: var(--pico-nav-breadcrumb-divider); + color: var(--pico-muted-color); + text-align: center; + text-decoration: none; + white-space: nowrap; +} +nav[aria-label=breadcrumb] a[aria-current]:not([aria-current=false]) { + background-color: transparent; + color: inherit; + text-decoration: none; + pointer-events: none; +} + +aside nav, +aside ol, +aside ul, +aside li { + display: block; +} +aside li { + padding: calc(var(--pico-nav-element-spacing-vertical) * 0.5) var(--pico-nav-element-spacing-horizontal); +} +aside li a { + display: block; +} +aside li [role=button] { + margin: inherit; +} + +[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) ::after { + content: "\\"; +} + +/** + * Progress + */ +progress { + display: inline-block; + vertical-align: baseline; +} + +progress { + -webkit-appearance: none; + -moz-appearance: none; + display: inline-block; + appearance: none; + width: 100%; + height: 0.5rem; + margin-bottom: calc(var(--pico-spacing) * 0.5); + overflow: hidden; + border: 0; + border-radius: var(--pico-border-radius); + background-color: var(--pico-progress-background-color); + color: var(--pico-progress-color); +} +progress::-webkit-progress-bar { + border-radius: var(--pico-border-radius); + background: none; +} +progress[value]::-webkit-progress-value { + background-color: var(--pico-progress-color); + -webkit-transition: inline-size var(--pico-transition); + transition: inline-size var(--pico-transition); +} +progress::-moz-progress-bar { + background-color: var(--pico-progress-color); +} +@media (prefers-reduced-motion: no-preference) { + progress:indeterminate { + background: var(--pico-progress-background-color) linear-gradient(to right, var(--pico-progress-color) 30%, var(--pico-progress-background-color) 30%) top left/150% 150% no-repeat; + animation: progress-indeterminate 1s linear infinite; + } + progress:indeterminate[value]::-webkit-progress-value { + background-color: transparent; + } + progress:indeterminate::-moz-progress-bar { + background-color: transparent; + } +} + +@media (prefers-reduced-motion: no-preference) { + [dir=rtl] progress:indeterminate { + animation-direction: reverse; + } +} + +@keyframes progress-indeterminate { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} +/** + * Tooltip ([data-tooltip]) + */ +[data-tooltip] { + position: relative; +} +[data-tooltip]:not(a, button, input) { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} +[data-tooltip][data-placement=top]::before, [data-tooltip][data-placement=top]::after, [data-tooltip]::before, [data-tooltip]::after { + display: block; + z-index: 99; + position: absolute; + bottom: 100%; + left: 50%; + padding: 0.25rem 0.5rem; + overflow: hidden; + transform: translate(-50%, -0.25rem); + border-radius: var(--pico-border-radius); + background: var(--pico-tooltip-background-color); + content: attr(data-tooltip); + color: var(--pico-tooltip-color); + font-style: normal; + font-weight: var(--pico-font-weight); + font-size: 0.875rem; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; + opacity: 0; + pointer-events: none; +} +[data-tooltip][data-placement=top]::after, [data-tooltip]::after { + padding: 0; + transform: translate(-50%, 0rem); + border-top: 0.3rem solid; + border-right: 0.3rem solid transparent; + border-left: 0.3rem solid transparent; + border-radius: 0; + background-color: transparent; + content: ""; + color: var(--pico-tooltip-background-color); +} +[data-tooltip][data-placement=bottom]::before, [data-tooltip][data-placement=bottom]::after { + top: 100%; + bottom: auto; + transform: translate(-50%, 0.25rem); +} +[data-tooltip][data-placement=bottom]:after { + transform: translate(-50%, -0.3rem); + border: 0.3rem solid transparent; + border-bottom: 0.3rem solid; +} +[data-tooltip][data-placement=left]::before, [data-tooltip][data-placement=left]::after { + top: 50%; + right: 100%; + bottom: auto; + left: auto; + transform: translate(-0.25rem, -50%); +} +[data-tooltip][data-placement=left]:after { + transform: translate(0.3rem, -50%); + border: 0.3rem solid transparent; + border-left: 0.3rem solid; +} +[data-tooltip][data-placement=right]::before, [data-tooltip][data-placement=right]::after { + top: 50%; + right: auto; + bottom: auto; + left: 100%; + transform: translate(0.25rem, -50%); +} +[data-tooltip][data-placement=right]:after { + transform: translate(-0.3rem, -50%); + border: 0.3rem solid transparent; + border-right: 0.3rem solid; +} +[data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + opacity: 1; +} +@media (hover: hover) and (pointer: fine) { + [data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + --pico-tooltip-slide-to: translate(-50%, -0.25rem); + transform: translate(-50%, 0.75rem); + animation-duration: 0.2s; + animation-fill-mode: forwards; + animation-name: tooltip-slide; + opacity: 0; + } + [data-tooltip]:focus::after, [data-tooltip]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, 0rem); + transform: translate(-50%, -0.25rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=bottom]:focus::before, [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::before, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-slide-to: translate(-50%, 0.25rem); + transform: translate(-50%, -0.75rem); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, -0.3rem); + transform: translate(-50%, -0.5rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=left]:focus::before, [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::before, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-slide-to: translate(-0.25rem, -50%); + transform: translate(0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-caret-slide-to: translate(0.3rem, -50%); + transform: translate(0.05rem, -50%); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=right]:focus::before, [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::before, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-slide-to: translate(0.25rem, -50%); + transform: translate(-0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-caret-slide-to: translate(-0.3rem, -50%); + transform: translate(-0.05rem, -50%); + animation-name: tooltip-caret-slide; + } +} +@keyframes tooltip-slide { + to { + transform: var(--pico-tooltip-slide-to); + opacity: 1; + } +} +@keyframes tooltip-caret-slide { + 50% { + opacity: 0; + } + to { + transform: var(--pico-tooltip-caret-slide-to); + opacity: 1; + } +} + +/** + * Accessibility & User interaction + */ +[aria-controls] { + cursor: pointer; +} + +[aria-disabled=true], +[disabled] { + cursor: not-allowed; +} + +[aria-hidden=false][hidden] { + display: initial; +} + +[aria-hidden=false][hidden]:not(:focus) { + clip: rect(0, 0, 0, 0); + position: absolute; +} + +a, +area, +button, +input, +label, +select, +summary, +textarea, +[tabindex] { + -ms-touch-action: manipulation; +} + +[dir=rtl] { + direction: rtl; +} + +/** + * Reduce Motion Features + */ +@media (prefers-reduced-motion: reduce) { + *:not([aria-busy=true]), + :not([aria-busy=true])::before, + :not([aria-busy=true])::after { + background-attachment: initial !important; + animation-duration: 1ms !important; + animation-delay: -1ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + transition-delay: 0s !important; + transition-duration: 0s !important; + } +} \ No newline at end of file diff --git a/hypermedia/pico.blue.css b/hypermedia/pico.blue.css new file mode 100644 index 0000000..acb44ef --- /dev/null +++ b/hypermedia/pico.blue.css @@ -0,0 +1,2802 @@ +@charset "UTF-8"; +/*! + * Pico CSS ✨ v2.0.6 (https://picocss.com) + * Copyright 2019-2024 - Licensed under MIT + */ +/** + * Styles + */ +:root { + --pico-font-family-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --pico-font-family-sans-serif: system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, Helvetica, Arial, "Helvetica Neue", sans-serif, var(--pico-font-family-emoji); + --pico-font-family-monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace, var(--pico-font-family-emoji); + --pico-font-family: var(--pico-font-family-sans-serif); + --pico-line-height: 1.5; + --pico-font-weight: 400; + --pico-font-size: 100%; + --pico-text-underline-offset: 0.1rem; + --pico-border-radius: 0.25rem; + --pico-border-width: 0.0625rem; + --pico-outline-width: 0.125rem; + --pico-transition: 0.2s ease-in-out; + --pico-spacing: 1rem; + --pico-typography-spacing-vertical: 1rem; + --pico-block-spacing-vertical: var(--pico-spacing); + --pico-block-spacing-horizontal: var(--pico-spacing); + --pico-grid-column-gap: var(--pico-spacing); + --pico-grid-row-gap: var(--pico-spacing); + --pico-form-element-spacing-vertical: 0.75rem; + --pico-form-element-spacing-horizontal: 1rem; + --pico-group-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); + --pico-group-box-shadow-focus-with-input: 0 0 0 0.0625rem var(--pico-form-element-border-color); + --pico-modal-overlay-backdrop-filter: blur(0.375rem); + --pico-nav-element-spacing-vertical: 1rem; + --pico-nav-element-spacing-horizontal: 0.5rem; + --pico-nav-link-spacing-vertical: 0.5rem; + --pico-nav-link-spacing-horizontal: 0.5rem; + --pico-nav-breadcrumb-divider: ">"; + --pico-icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-loading: url("data:image/svg+xml,%3Csvg fill='none' height='24' width='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' %3E%3Cstyle%3E g %7B animation: rotate 2s linear infinite; transform-origin: center center; %7D circle %7B stroke-dasharray: 75,100; stroke-dashoffset: -5; animation: dash 1.5s ease-in-out infinite; stroke-linecap: round; %7D @keyframes rotate %7B 0%25 %7B transform: rotate(0deg); %7D 100%25 %7B transform: rotate(360deg); %7D %7D @keyframes dash %7B 0%25 %7B stroke-dasharray: 1,100; stroke-dashoffset: 0; %7D 50%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -17.5; %7D 100%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -62; %7D %7D %3C/style%3E%3Cg%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='rgb(136, 145, 164)' stroke-width='4' /%3E%3C/g%3E%3C/svg%3E"); +} +@media (min-width: 576px) { + :root { + --pico-font-size: 106.25%; + } +} +@media (min-width: 768px) { + :root { + --pico-font-size: 112.5%; + } +} +@media (min-width: 1024px) { + :root { + --pico-font-size: 118.75%; + } +} +@media (min-width: 1280px) { + :root { + --pico-font-size: 125%; + } +} +@media (min-width: 1536px) { + :root { + --pico-font-size: 131.25%; + } +} + +a { + --pico-text-decoration: underline; +} +a.secondary, a.contrast { + --pico-text-decoration: underline; +} + +small { + --pico-font-size: 0.875em; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + --pico-font-weight: 700; +} + +h1 { + --pico-font-size: 2rem; + --pico-line-height: 1.125; + --pico-typography-spacing-top: 3rem; +} + +h2 { + --pico-font-size: 1.75rem; + --pico-line-height: 1.15; + --pico-typography-spacing-top: 2.625rem; +} + +h3 { + --pico-font-size: 1.5rem; + --pico-line-height: 1.175; + --pico-typography-spacing-top: 2.25rem; +} + +h4 { + --pico-font-size: 1.25rem; + --pico-line-height: 1.2; + --pico-typography-spacing-top: 1.874rem; +} + +h5 { + --pico-font-size: 1.125rem; + --pico-line-height: 1.225; + --pico-typography-spacing-top: 1.6875rem; +} + +h6 { + --pico-font-size: 1rem; + --pico-line-height: 1.25; + --pico-typography-spacing-top: 1.5rem; +} + +thead th, +thead td, +tfoot th, +tfoot td { + --pico-font-weight: 600; + --pico-border-width: 0.1875rem; +} + +pre, +code, +kbd, +samp { + --pico-font-family: var(--pico-font-family-monospace); +} + +kbd { + --pico-font-weight: bolder; +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:where(select, textarea) { + --pico-outline-width: 0.0625rem; +} + +[type=search] { + --pico-border-radius: 5rem; +} + +[type=checkbox], +[type=radio] { + --pico-border-width: 0.125rem; +} + +[type=checkbox][role=switch] { + --pico-border-width: 0.1875rem; +} + +details.dropdown summary:not([role=button]) { + --pico-outline-width: 0.0625rem; +} + +nav details.dropdown summary:focus-visible { + --pico-outline-width: 0.125rem; +} + +[role=search] { + --pico-border-radius: 5rem; +} + +[role=search]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus), +[role=group]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} +[role=search]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus), +[role=group]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=button], +[role=group] [role=button] { + --pico-form-element-spacing-horizontal: 2rem; +} + +details summary[role=button]:not(.outline)::after { + filter: brightness(0) invert(1); +} + +[aria-busy=true]:not(input, select, textarea):is(button, [type=submit], [type=button], [type=reset], [role=button]):not(.outline)::before { + filter: brightness(0) invert(1); +} + +/** + * Color schemes + */ +[data-theme=light], +:root:not([data-theme=dark]) { + --pico-background-color: #fff; + --pico-color: #373c44; + --pico-text-selection-color: rgba(116, 139, 248, 0.25); + --pico-muted-color: #646b79; + --pico-muted-border-color: #e7eaf0; + --pico-primary: #2060df; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(32, 96, 223, 0.5); + --pico-primary-hover: #184eb8; + --pico-primary-hover-background: #1d59d0; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(116, 139, 248, 0.5); + --pico-primary-inverse: #fff; + --pico-secondary: #5d6b89; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(93, 107, 137, 0.5); + --pico-secondary-hover: #48536b; + --pico-secondary-hover-background: #48536b; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(93, 107, 137, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #181c25; + --pico-contrast-background: #181c25; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(24, 28, 37, 0.5); + --pico-contrast-hover: #000; + --pico-contrast-hover-background: #000; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-secondary-hover); + --pico-contrast-focus: rgba(93, 107, 137, 0.25); + --pico-contrast-inverse: #fff; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(129, 145, 181, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(129, 145, 181, 0.024), 0.0625rem 0.125rem 0.75rem rgba(129, 145, 181, 0.03), 0.1125rem 0.225rem 1.35rem rgba(129, 145, 181, 0.036), 0.2085rem 0.417rem 2.502rem rgba(129, 145, 181, 0.04302), 0.5rem 1rem 6rem rgba(129, 145, 181, 0.06), 0 0 0 0.0625rem rgba(129, 145, 181, 0.015); + --pico-h1-color: #2d3138; + --pico-h2-color: #373c44; + --pico-h3-color: #424751; + --pico-h4-color: #4d535e; + --pico-h5-color: #5c6370; + --pico-h6-color: #646b79; + --pico-mark-background-color: #fde7c0; + --pico-mark-color: #0f1114; + --pico-ins-color: #1d6a54; + --pico-del-color: #883935; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #f3f5f7; + --pico-code-color: #646b79; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #fbfcfc; + --pico-form-element-selected-background-color: #dfe3eb; + --pico-form-element-border-color: #cfd5e2; + --pico-form-element-color: #23262c; + --pico-form-element-placeholder-color: var(--pico-muted-color); + --pico-form-element-active-background-color: #fff; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #b86a6b; + --pico-form-element-invalid-active-border-color: #c84f48; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #4c9b8a; + --pico-form-element-valid-active-border-color: #279977; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #bfc7d9; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #dfe3eb; + --pico-range-active-border-color: #bfc7d9; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: var(--pico-background-color); + --pico-card-border-color: var(--pico-muted-border-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #fbfcfc; + --pico-dropdown-background-color: #fff; + --pico-dropdown-border-color: #eff1f4; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #eff1f4; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(232, 234, 237, 0.75); + --pico-progress-background-color: #dfe3eb; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(76, 155, 138)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(200, 79, 72)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: light; +} +[data-theme=light] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:root:not([data-theme=dark]) input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} + +@media only screen and (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; + } + :root:not([data-theme]) input:is([type=submit], + [type=button], + [type=reset], + [type=checkbox], + [type=radio], + [type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); + } + :root:not([data-theme]) details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); + } + :root:not([data-theme]) [aria-busy=true]:not(input, select, textarea).contrast:is(button, + [type=submit], + [type=button], + [type=reset], + [role=button]):not(.outline)::before { + filter: brightness(0); + } +} +[data-theme=dark] { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; +} +[data-theme=dark] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} +[data-theme=dark] details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); +} +[data-theme=dark] [aria-busy=true]:not(input, select, textarea).contrast:is(button, +[type=submit], +[type=button], +[type=reset], +[role=button]):not(.outline)::before { + filter: brightness(0); +} + +progress, +[type=checkbox], +[type=radio], +[type=range] { + accent-color: var(--pico-primary); +} + +/** + * Document + * Content-box & Responsive typography + */ +*, +*::before, +*::after { + box-sizing: border-box; + background-repeat: no-repeat; +} + +::before, +::after { + text-decoration: inherit; + vertical-align: inherit; +} + +:where(:root) { + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); + text-underline-offset: var(--pico-text-underline-offset); + text-rendering: optimizeLegibility; + overflow-wrap: break-word; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; +} + +/** + * Landmarks + */ +body { + width: 100%; + margin: 0; +} + +main { + display: block; +} + +body > header, +body > main, +body > footer { + padding-block: var(--pico-block-spacing-vertical); +} + +/** + * Section + */ +section { + margin-bottom: var(--pico-block-spacing-vertical); +} + +/** + * Container + */ +.container, +.container-fluid { + width: 100%; + margin-right: auto; + margin-left: auto; + padding-right: var(--pico-spacing); + padding-left: var(--pico-spacing); +} + +@media (min-width: 576px) { + .container { + max-width: 510px; + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .container { + max-width: 700px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 950px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1200px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1450px; + } +} + +/** + * Grid + * Minimal grid system with auto-layout columns + */ +.grid { + grid-column-gap: var(--pico-grid-column-gap); + grid-row-gap: var(--pico-grid-row-gap); + display: grid; + grid-template-columns: 1fr; +} +@media (min-width: 768px) { + .grid { + grid-template-columns: repeat(auto-fit, minmax(0%, 1fr)); + } +} +.grid > * { + min-width: 0; +} + +/** + * Overflow auto + */ +.overflow-auto { + overflow: auto; +} + +/** + * Typography + */ +b, +strong { + font-weight: bolder; +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +address, +blockquote, +dl, +ol, +p, +pre, +table, +ul { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-style: normal; + font-weight: var(--pico-font-weight); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); +} + +h1 { + --pico-color: var(--pico-h1-color); +} + +h2 { + --pico-color: var(--pico-h2-color); +} + +h3 { + --pico-color: var(--pico-h3-color); +} + +h4 { + --pico-color: var(--pico-h4-color); +} + +h5 { + --pico-color: var(--pico-h5-color); +} + +h6 { + --pico-color: var(--pico-h6-color); +} + +:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) { + margin-top: var(--pico-typography-spacing-top); +} + +p { + margin-bottom: var(--pico-typography-spacing-vertical); +} + +hgroup { + margin-bottom: var(--pico-typography-spacing-vertical); +} +hgroup > * { + margin-top: 0; + margin-bottom: 0; +} +hgroup > *:not(:first-child):last-child { + --pico-color: var(--pico-muted-color); + --pico-font-weight: unset; + font-size: 1rem; +} + +:where(ol, ul) li { + margin-bottom: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +:where(dl, ol, ul) :where(dl, ol, ul) { + margin: 0; + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +ul li { + list-style: square; +} + +mark { + padding: 0.125rem 0.25rem; + background-color: var(--pico-mark-background-color); + color: var(--pico-mark-color); + vertical-align: baseline; +} + +blockquote { + display: block; + margin: var(--pico-typography-spacing-vertical) 0; + padding: var(--pico-spacing); + border-right: none; + border-left: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-start: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-end: none; +} +blockquote footer { + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.5); + color: var(--pico-blockquote-footer-color); +} + +abbr[title] { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} + +ins { + color: var(--pico-ins-color); + text-decoration: none; +} + +del { + color: var(--pico-del-color); +} + +::-moz-selection { + background-color: var(--pico-text-selection-color); +} + +::selection { + background-color: var(--pico-text-selection-color); +} + +/** + * Link + */ +:where(a:not([role=button])), +[role=link] { + --pico-color: var(--pico-primary); + --pico-background-color: transparent; + --pico-underline: var(--pico-primary-underline); + outline: none; + background-color: var(--pico-background-color); + color: var(--pico-color); + -webkit-text-decoration: var(--pico-text-decoration); + text-decoration: var(--pico-text-decoration); + text-decoration-color: var(--pico-underline); + text-underline-offset: 0.125em; + transition: background-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); +} +:where(a:not([role=button])):is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-primary-hover); + --pico-underline: var(--pico-primary-hover-underline); + --pico-text-decoration: underline; +} +:where(a:not([role=button])):focus-visible, +[role=link]:focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} +:where(a:not([role=button])).secondary, +[role=link].secondary { + --pico-color: var(--pico-secondary); + --pico-underline: var(--pico-secondary-underline); +} +:where(a:not([role=button])).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-underline: var(--pico-secondary-hover-underline); +} +:where(a:not([role=button])).contrast, +[role=link].contrast { + --pico-color: var(--pico-contrast); + --pico-underline: var(--pico-contrast-underline); +} +:where(a:not([role=button])).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-underline: var(--pico-contrast-hover-underline); +} + +a[role=button] { + display: inline-block; +} + +/** + * Button + */ +button { + margin: 0; + overflow: visible; + font-family: inherit; + text-transform: none; +} + +button, +[type=submit], +[type=reset], +[type=button] { + -webkit-appearance: button; +} + +button, +[type=submit], +[type=reset], +[type=button], +[type=file]::file-selector-button, +[role=button] { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + --pico-color: var(--pico-primary-inverse); + --pico-box-shadow: var(--pico-button-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: 1rem; + line-height: var(--pico-line-height); + text-align: center; + text-decoration: none; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +button:is([aria-current]:not([aria-current=false])), button:is(:hover, :active, :focus), +[type=submit]:is([aria-current]:not([aria-current=false])), +[type=submit]:is(:hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false])), +[type=reset]:is(:hover, :active, :focus), +[type=button]:is([aria-current]:not([aria-current=false])), +[type=button]:is(:hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])), +[type=file]::file-selector-button:is(:hover, :active, :focus), +[role=button]:is([aria-current]:not([aria-current=false])), +[role=button]:is(:hover, :active, :focus) { + --pico-background-color: var(--pico-primary-hover-background); + --pico-border-color: var(--pico-primary-hover-border); + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + --pico-color: var(--pico-primary-inverse); +} +button:focus, button:is([aria-current]:not([aria-current=false])):focus, +[type=submit]:focus, +[type=submit]:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=button]:focus, +[type=button]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus, +[role=button]:focus, +[role=button]:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +[type=submit], +[type=reset], +[type=button] { + margin-bottom: var(--pico-spacing); +} + +:is(button, [type=submit], [type=button], [role=button]).secondary, +[type=reset], +[type=file]::file-selector-button { + --pico-background-color: var(--pico-secondary-background); + --pico-border-color: var(--pico-secondary-border); + --pico-color: var(--pico-secondary-inverse); + cursor: pointer; +} +:is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); + --pico-color: var(--pico-secondary-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).secondary:focus, :is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).contrast { + --pico-background-color: var(--pico-contrast-background); + --pico-border-color: var(--pico-contrast-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-contrast-hover-background); + --pico-border-color: var(--pico-contrast-hover-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:focus, :is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).outline, +[type=reset].outline { + --pico-background-color: transparent; + --pico-color: var(--pico-primary); + --pico-border-color: var(--pico-primary); +} +:is(button, [type=submit], [type=button], [role=button]).outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: transparent; + --pico-color: var(--pico-primary-hover); + --pico-border-color: var(--pico-primary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.secondary, +[type=reset].outline { + --pico-color: var(--pico-secondary); + --pico-border-color: var(--pico-secondary); +} +:is(button, [type=submit], [type=button], [role=button]).outline.secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-border-color: var(--pico-secondary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.contrast { + --pico-color: var(--pico-contrast); + --pico-border-color: var(--pico-contrast); +} +:is(button, [type=submit], [type=button], [role=button]).outline.contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-border-color: var(--pico-contrast-hover); +} + +:where(button, [type=submit], [type=reset], [type=button], [role=button])[disabled], +:where(fieldset[disabled]) :is(button, [type=submit], [type=button], [type=reset], [role=button]) { + opacity: 0.5; + pointer-events: none; +} + +/** + * Table + */ +:where(table) { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + text-indent: 0; +} + +th, +td { + padding: calc(var(--pico-spacing) / 2) var(--pico-spacing); + border-bottom: var(--pico-border-width) solid var(--pico-table-border-color); + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + text-align: left; + text-align: start; +} + +tfoot th, +tfoot td { + border-top: var(--pico-border-width) solid var(--pico-table-border-color); + border-bottom: 0; +} + +table.striped tbody tr:nth-child(odd) th, +table.striped tbody tr:nth-child(odd) td { + background-color: var(--pico-table-row-stripped-background-color); +} + +/** + * Embedded content + */ +:where(audio, canvas, iframe, img, svg, video) { + vertical-align: middle; +} + +audio, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +:where(iframe) { + border-style: none; +} + +img { + max-width: 100%; + height: auto; + border-style: none; +} + +:where(svg:not([fill])) { + fill: currentColor; +} + +svg:not(:root) { + overflow: hidden; +} + +/** + * Code + */ +pre, +code, +kbd, +samp { + font-size: 0.875em; + font-family: var(--pico-font-family); +} + +pre code { + font-size: inherit; + font-family: inherit; +} + +pre { + -ms-overflow-style: scrollbar; + overflow: auto; +} + +pre, +code, +kbd { + border-radius: var(--pico-border-radius); + background: var(--pico-code-background-color); + color: var(--pico-code-color); + font-weight: var(--pico-font-weight); + line-height: initial; +} + +code, +kbd { + display: inline-block; + padding: 0.375rem; +} + +pre { + display: block; + margin-bottom: var(--pico-spacing); + overflow-x: auto; +} +pre > code { + display: block; + padding: var(--pico-spacing); + background: none; + line-height: var(--pico-line-height); +} + +kbd { + background-color: var(--pico-code-kbd-background-color); + color: var(--pico-code-kbd-color); + vertical-align: baseline; +} + +/** + * Figure + */ +figure { + display: block; + margin: 0; + padding: 0; +} +figure figcaption { + padding: calc(var(--pico-spacing) * 0.5) 0; + color: var(--pico-muted-color); +} + +/** + * Miscs + */ +hr { + height: 0; + margin: var(--pico-typography-spacing-vertical) 0; + border: 0; + border-top: 1px solid var(--pico-muted-border-color); + color: inherit; +} + +[hidden], +template { + display: none !important; +} + +canvas { + display: inline-block; +} + +/** + * Basics form elements + */ +input, +optgroup, +select, +textarea { + margin: 0; + font-size: 1rem; + line-height: var(--pico-line-height); + font-family: inherit; + letter-spacing: inherit; +} + +input { + overflow: visible; +} + +select { + text-transform: none; +} + +legend { + max-width: 100%; + padding: 0; + color: inherit; + white-space: normal; +} + +textarea { + overflow: auto; +} + +[type=checkbox], +[type=radio] { + padding: 0; +} + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +:-moz-focusring { + outline: none; +} + +:-moz-ui-invalid { + box-shadow: none; +} + +::-ms-expand { + display: none; +} + +[type=file], +[type=range] { + padding: 0; + border-width: 0; +} + +input:not([type=checkbox], [type=radio], [type=range]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); +} + +fieldset { + width: 100%; + margin: 0; + margin-bottom: var(--pico-spacing); + padding: 0; + border: 0; +} + +label, +fieldset legend { + display: block; + margin-bottom: calc(var(--pico-spacing) * 0.375); + color: var(--pico-color); + font-weight: var(--pico-form-label-font-weight, var(--pico-font-weight)); +} + +fieldset legend { + margin-bottom: calc(var(--pico-spacing) * 0.5); +} + +input:not([type=checkbox], [type=radio]), +button[type=submit], +select, +textarea { + width: 100%; +} + +input:not([type=checkbox], [type=radio], [type=range], [type=file]), +select, +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); +} + +input, +select, +textarea { + --pico-background-color: var(--pico-form-element-background-color); + --pico-border-color: var(--pico-form-element-border-color); + --pico-color: var(--pico-form-element-color); + --pico-box-shadow: none; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-background-color: var(--pico-form-element-active-background-color); +} + +input:not([type=submit], [type=button], [type=reset], [role=switch], [readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-border-color: var(--pico-form-element-active-border-color); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=range], +[type=file], +[readonly]):focus, +:where(select, textarea):not([readonly]):focus { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} + +input:not([type=submit], [type=button], [type=reset])[disabled], +select[disabled], +textarea[disabled], +label[aria-disabled=true], +:where(fieldset[disabled]) :is(input:not([type=submit], [type=button], [type=reset]), select, textarea) { + opacity: var(--pico-form-element-disabled-opacity); + pointer-events: none; +} + +label[aria-disabled=true] input[disabled] { + opacity: 1; +} + +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid] { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal) !important; + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=false]:not(select) { + background-image: var(--pico-icon-valid); +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=true]:not(select) { + background-image: var(--pico-icon-invalid); +} +:where(input, select, textarea)[aria-invalid=false] { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-valid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-valid-focus-color) !important; +} +:where(input, select, textarea)[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-invalid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-invalid-focus-color) !important; +} + +[dir=rtl] :where(input, select, textarea):not([type=checkbox], [type=radio]):is([aria-invalid], [aria-invalid=true], [aria-invalid=false]) { + background-position: center left 0.75rem; +} + +input::placeholder, +input::-webkit-input-placeholder, +textarea::placeholder, +textarea::-webkit-input-placeholder, +select:invalid { + color: var(--pico-form-element-placeholder-color); + opacity: 1; +} + +input:not([type=checkbox], [type=radio]), +select, +textarea { + margin-bottom: var(--pico-spacing); +} + +select::-ms-expand { + border: 0; + background-color: transparent; +} +select:not([multiple], [size]) { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal); + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + background-image: var(--pico-icon-chevron); + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +select[multiple] option:checked { + background: var(--pico-form-element-selected-background-color); + color: var(--pico-form-element-color); +} + +[dir=rtl] select:not([multiple], [size]) { + background-position: center left 0.75rem; +} + +textarea { + display: block; + resize: vertical; +} +textarea[aria-invalid] { + --pico-icon-height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + background-position: top right 0.75rem !important; + background-size: 1rem var(--pico-icon-height) !important; +} + +:where(input, select, textarea, fieldset, .grid) + small { + display: block; + width: 100%; + margin-top: calc(var(--pico-spacing) * -0.75); + margin-bottom: var(--pico-spacing); + color: var(--pico-muted-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=false] + small { + color: var(--pico-ins-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=true] + small { + color: var(--pico-del-color); +} + +label > :where(input, select, textarea) { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Checkboxes, Radios and Switches + */ +label:has([type=checkbox], [type=radio]) { + width: -moz-fit-content; + width: fit-content; + cursor: pointer; +} + +[type=checkbox], +[type=radio] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 1.25em; + height: 1.25em; + margin-top: -0.125em; + margin-inline-end: 0.5em; + border-width: var(--pico-border-width); + vertical-align: middle; + cursor: pointer; +} +[type=checkbox]::-ms-check, +[type=radio]::-ms-check { + display: none; +} +[type=checkbox]:checked, [type=checkbox]:checked:active, [type=checkbox]:checked:focus, +[type=radio]:checked, +[type=radio]:checked:active, +[type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-checkbox); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} +[type=checkbox] ~ label, +[type=radio] ~ label { + display: inline-block; + margin-bottom: 0; + cursor: pointer; +} +[type=checkbox] ~ label:not(:last-of-type), +[type=radio] ~ label:not(:last-of-type) { + margin-inline-end: 1em; +} + +[type=checkbox]:indeterminate { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-minus); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} + +[type=radio] { + border-radius: 50%; +} +[type=radio]:checked, [type=radio]:checked:active, [type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-inverse); + border-width: 0.35em; + background-image: none; +} + +[type=checkbox][role=switch] { + --pico-background-color: var(--pico-switch-background-color); + --pico-color: var(--pico-switch-color); + width: 2.25em; + height: 1.25em; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: 1.25em; + background-color: var(--pico-background-color); + line-height: 1.25em; +} +[type=checkbox][role=switch]:not([aria-invalid]) { + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:before { + display: block; + aspect-ratio: 1; + height: 100%; + border-radius: 50%; + background-color: var(--pico-color); + box-shadow: var(--pico-switch-thumb-box-shadow); + content: ""; + transition: margin 0.1s ease-in-out; +} +[type=checkbox][role=switch]:focus { + --pico-background-color: var(--pico-switch-background-color); + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:checked { + --pico-background-color: var(--pico-switch-checked-background-color); + --pico-border-color: var(--pico-switch-checked-background-color); + background-image: none; +} +[type=checkbox][role=switch]:checked::before { + margin-inline-start: calc(2.25em - 1.25em); +} +[type=checkbox][role=switch][disabled] { + --pico-background-color: var(--pico-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-background-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-background-color: var(--pico-form-element-invalid-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=radio][aria-invalid=false]:checked, +[type=radio][aria-invalid=false]:checked:active, +[type=radio][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=radio]:checked[aria-invalid=true], +[type=radio]:checked:active[aria-invalid=true], +[type=radio]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} + +/** + * Input type color + */ +[type=color]::-webkit-color-swatch-wrapper { + padding: 0; +} +[type=color]::-moz-focus-inner { + padding: 0; +} +[type=color]::-webkit-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} +[type=color]::-moz-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} + +/** + * Input type datetime + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file]):is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + --pico-icon-position: 0.75rem; + --pico-icon-width: 1rem; + padding-right: calc(var(--pico-icon-width) + var(--pico-icon-position)); + background-image: var(--pico-icon-date); + background-position: center right var(--pico-icon-position); + background-size: var(--pico-icon-width) auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=time] { + background-image: var(--pico-icon-time); +} + +[type=date]::-webkit-calendar-picker-indicator, +[type=datetime-local]::-webkit-calendar-picker-indicator, +[type=month]::-webkit-calendar-picker-indicator, +[type=time]::-webkit-calendar-picker-indicator, +[type=week]::-webkit-calendar-picker-indicator { + width: var(--pico-icon-width); + margin-right: calc(var(--pico-icon-width) * -1); + margin-left: var(--pico-icon-position); + opacity: 0; +} + +@-moz-document url-prefix() { + [type=date], + [type=datetime-local], + [type=month], + [type=time], + [type=week] { + padding-right: var(--pico-form-element-spacing-horizontal) !important; + background-image: none !important; + } +} +[dir=rtl] :is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + text-align: right; +} + +/** + * Input type file + */ +[type=file] { + --pico-color: var(--pico-muted-color); + margin-left: calc(var(--pico-outline-width) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) 0; + padding-left: var(--pico-outline-width); + border: 0; + border-radius: 0; + background: none; +} +[type=file]::file-selector-button { + margin-right: calc(var(--pico-spacing) / 2); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); +} +[type=file]:is(:hover, :active, :focus)::file-selector-button { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); +} +[type=file]:focus::file-selector-button { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +/** + * Input type range + */ +[type=range] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 100%; + height: 1.25rem; + background: none; +} +[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -webkit-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-moz-range-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -moz-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-ms-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -ms-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -webkit-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-moz-range-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -moz-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-ms-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -ms-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]:active, [type=range]:focus-within { + --pico-range-border-color: var(--pico-range-active-border-color); + --pico-range-thumb-color: var(--pico-range-thumb-active-color); +} +[type=range]:active::-webkit-slider-thumb { + transform: scale(1.25); +} +[type=range]:active::-moz-range-thumb { + transform: scale(1.25); +} +[type=range]:active::-ms-thumb { + transform: scale(1.25); +} + +/** + * Input type search + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem); + background-image: var(--pico-icon-search); + background-position: center left calc(var(--pico-form-element-spacing-horizontal) + 0.125rem); + background-size: 1rem auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem) !important; + background-position: center left 1.125rem, center right 0.75rem; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=false] { + background-image: var(--pico-icon-search), var(--pico-icon-valid); +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=true] { + background-image: var(--pico-icon-search), var(--pico-icon-invalid); +} + +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + background-position: center right 1.125rem; +} +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + background-position: center right 1.125rem, center left 0.75rem; +} + +/** + * Accordion (
) + */ +details { + display: block; + margin-bottom: var(--pico-spacing); +} +details summary { + line-height: 1rem; + list-style-type: none; + cursor: pointer; + transition: color var(--pico-transition); +} +details summary:not([role]) { + color: var(--pico-accordion-close-summary-color); +} +details summary::-webkit-details-marker { + display: none; +} +details summary::marker { + display: none; +} +details summary::-moz-list-bullet { + list-style-type: none; +} +details summary::after { + display: block; + width: 1rem; + height: 1rem; + margin-inline-start: calc(var(--pico-spacing, 1rem) * 0.5); + float: right; + transform: rotate(-90deg); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; + transition: transform var(--pico-transition); +} +details summary:focus { + outline: none; +} +details summary:focus:not([role]) { + color: var(--pico-accordion-active-summary-color); +} +details summary:focus-visible:not([role]) { + outline: var(--pico-outline-width) solid var(--pico-primary-focus); + outline-offset: calc(var(--pico-spacing, 1rem) * 0.5); + color: var(--pico-primary); +} +details summary[role=button] { + width: 100%; + text-align: left; +} +details summary[role=button]::after { + height: calc(1rem * var(--pico-line-height, 1.5)); +} +details[open] > summary { + margin-bottom: var(--pico-spacing); +} +details[open] > summary:not([role]):not(:focus) { + color: var(--pico-accordion-open-summary-color); +} +details[open] > summary::after { + transform: rotate(0); +} + +[dir=rtl] details summary { + text-align: right; +} +[dir=rtl] details summary::after { + float: left; + background-position: left center; +} + +/** + * Card (
) + */ +article { + margin-bottom: var(--pico-block-spacing-vertical); + padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); + border-radius: var(--pico-border-radius); + background: var(--pico-card-background-color); + box-shadow: var(--pico-card-box-shadow); +} +article > header, +article > footer { + margin-right: calc(var(--pico-block-spacing-horizontal) * -1); + margin-left: calc(var(--pico-block-spacing-horizontal) * -1); + padding: calc(var(--pico-block-spacing-vertical) * 0.66) var(--pico-block-spacing-horizontal); + background-color: var(--pico-card-sectioning-background-color); +} +article > header { + margin-top: calc(var(--pico-block-spacing-vertical) * -1); + margin-bottom: var(--pico-block-spacing-vertical); + border-bottom: var(--pico-border-width) solid var(--pico-card-border-color); + border-top-right-radius: var(--pico-border-radius); + border-top-left-radius: var(--pico-border-radius); +} +article > footer { + margin-top: var(--pico-block-spacing-vertical); + margin-bottom: calc(var(--pico-block-spacing-vertical) * -1); + border-top: var(--pico-border-width) solid var(--pico-card-border-color); + border-bottom-right-radius: var(--pico-border-radius); + border-bottom-left-radius: var(--pico-border-radius); +} + +/** + * Dropdown (details.dropdown) + */ +details.dropdown { + position: relative; + border-bottom: none; +} +details.dropdown summary::after, +details.dropdown > button::after, +details.dropdown > a::after { + display: block; + width: 1rem; + height: calc(1rem * var(--pico-line-height, 1.5)); + margin-inline-start: 0.25rem; + float: right; + transform: rotate(0deg) translateX(0.2rem); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; +} + +nav details.dropdown { + margin-bottom: 0; +} + +details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-form-element-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-form-element-background-color); + color: var(--pico-form-element-placeholder-color); + line-height: inherit; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +details.dropdown summary:not([role]):active, details.dropdown summary:not([role]):focus { + border-color: var(--pico-form-element-active-border-color); + background-color: var(--pico-form-element-active-background-color); +} +details.dropdown summary:not([role]):focus { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} +details.dropdown summary:not([role]):focus-visible { + outline: none; +} +details.dropdown summary:not([role])[aria-invalid=false] { + --pico-form-element-border-color: var(--pico-form-element-valid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-valid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-valid-focus-color); +} +details.dropdown summary:not([role])[aria-invalid=true] { + --pico-form-element-border-color: var(--pico-form-element-invalid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-invalid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-invalid-focus-color); +} + +nav details.dropdown { + display: inline; + margin: calc(var(--pico-nav-element-spacing-vertical) * -1) 0; +} +nav details.dropdown summary::after { + transform: rotate(0deg) translateX(0rem); +} +nav details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2); + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav details.dropdown summary:not([role]):focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +details.dropdown summary + ul { + display: flex; + z-index: 99; + position: absolute; + left: 0; + flex-direction: column; + width: 100%; + min-width: -moz-fit-content; + min-width: fit-content; + margin: 0; + margin-top: var(--pico-outline-width); + padding: 0; + border: var(--pico-border-width) solid var(--pico-dropdown-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-dropdown-background-color); + box-shadow: var(--pico-dropdown-box-shadow); + color: var(--pico-dropdown-color); + white-space: nowrap; + opacity: 0; + transition: opacity var(--pico-transition), transform 0s ease-in-out 1s; +} +details.dropdown summary + ul[dir=rtl] { + right: 0; + left: auto; +} +details.dropdown summary + ul li { + width: 100%; + margin-bottom: 0; + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + list-style: none; +} +details.dropdown summary + ul li:first-of-type { + margin-top: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li:last-of-type { + margin-bottom: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li a { + display: block; + margin: calc(var(--pico-form-element-spacing-vertical) * -0.5) calc(var(--pico-form-element-spacing-horizontal) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + overflow: hidden; + border-radius: 0; + color: var(--pico-dropdown-color); + text-decoration: none; + text-overflow: ellipsis; +} +details.dropdown summary + ul li a:hover, details.dropdown summary + ul li a:focus, details.dropdown summary + ul li a:active, details.dropdown summary + ul li a:focus-visible, details.dropdown summary + ul li a[aria-current]:not([aria-current=false]) { + background-color: var(--pico-dropdown-hover-background-color); +} +details.dropdown summary + ul li label { + width: 100%; +} +details.dropdown summary + ul li:has(label):hover { + background-color: var(--pico-dropdown-hover-background-color); +} + +details.dropdown[open] summary { + margin-bottom: 0; +} + +details.dropdown[open] summary + ul { + transform: scaleY(1); + opacity: 1; + transition: opacity var(--pico-transition), transform 0s ease-in-out 0s; +} + +details.dropdown[open] summary::before { + display: block; + z-index: 1; + position: fixed; + width: 100vw; + height: 100vh; + inset: 0; + background: none; + content: ""; + cursor: default; +} + +label > details.dropdown { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Group ([role="group"], [role="search"]) + */ +[role=search], +[role=group] { + display: inline-flex; + position: relative; + width: 100%; + margin-bottom: var(--pico-spacing); + border-radius: var(--pico-border-radius); + box-shadow: var(--pico-group-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + vertical-align: middle; + transition: box-shadow var(--pico-transition); +} +[role=search] > *, +[role=search] input:not([type=checkbox], [type=radio]), +[role=search] select, +[role=group] > *, +[role=group] input:not([type=checkbox], [type=radio]), +[role=group] select { + position: relative; + flex: 1 1 auto; + margin-bottom: 0; +} +[role=search] > *:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] > *:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +[role=search] > *:not(:last-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=search] select:not(:last-child), +[role=group] > *:not(:last-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=group] select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +[role=search] > *:focus, +[role=search] input:not([type=checkbox], [type=radio]):focus, +[role=search] select:focus, +[role=group] > *:focus, +[role=group] input:not([type=checkbox], [type=radio]):focus, +[role=group] select:focus { + z-index: 2; +} +[role=search] button:not(:first-child), +[role=search] [type=submit]:not(:first-child), +[role=search] [type=reset]:not(:first-child), +[role=search] [type=button]:not(:first-child), +[role=search] [role=button]:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] button:not(:first-child), +[role=group] [type=submit]:not(:first-child), +[role=group] [type=reset]:not(:first-child), +[role=group] [type=button]:not(:first-child), +[role=group] [role=button]:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: calc(var(--pico-border-width) * -1); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=reset], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=reset], +[role=group] [type=button], +[role=group] [role=button] { + width: auto; +} +@supports selector(:has(*)) { + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-button); + } + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select, + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select { + border-color: transparent; + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus), + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-input); + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button] { + --pico-button-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-border); + --pico-button-hover-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-hover-border); + } + [role=search] button:focus, + [role=search] [type=submit]:focus, + [role=search] [type=reset]:focus, + [role=search] [type=button]:focus, + [role=search] [role=button]:focus, + [role=group] button:focus, + [role=group] [type=submit]:focus, + [role=group] [type=reset]:focus, + [role=group] [type=button]:focus, + [role=group] [role=button]:focus { + box-shadow: none; + } +} + +[role=search] > *:first-child { + border-top-left-radius: 5rem; + border-bottom-left-radius: 5rem; +} +[role=search] > *:last-child { + border-top-right-radius: 5rem; + border-bottom-right-radius: 5rem; +} + +/** + * Loading ([aria-busy=true]) + */ +[aria-busy=true]:not(input, select, textarea, html) { + white-space: nowrap; +} +[aria-busy=true]:not(input, select, textarea, html)::before { + display: inline-block; + width: 1em; + height: 1em; + background-image: var(--pico-icon-loading); + background-size: 1em auto; + background-repeat: no-repeat; + content: ""; + vertical-align: -0.125em; +} +[aria-busy=true]:not(input, select, textarea, html):not(:empty)::before { + margin-inline-end: calc(var(--pico-spacing) * 0.5); +} +[aria-busy=true]:not(input, select, textarea, html):empty { + text-align: center; +} + +button[aria-busy=true], +[type=submit][aria-busy=true], +[type=button][aria-busy=true], +[type=reset][aria-busy=true], +[role=button][aria-busy=true], +a[aria-busy=true] { + pointer-events: none; +} + +/** + * Modal () + */ +:root { + --pico-scrollbar-width: 0px; +} + +dialog { + display: flex; + z-index: 999; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + align-items: center; + justify-content: center; + width: inherit; + min-width: 100%; + height: inherit; + min-height: 100%; + padding: 0; + border: 0; + -webkit-backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + background-color: var(--pico-modal-overlay-background-color); + color: var(--pico-color); +} +dialog article { + width: 100%; + max-height: calc(100vh - var(--pico-spacing) * 2); + margin: var(--pico-spacing); + overflow: auto; +} +@media (min-width: 576px) { + dialog article { + max-width: 510px; + } +} +@media (min-width: 768px) { + dialog article { + max-width: 700px; + } +} +dialog article > header > * { + margin-bottom: 0; +} +dialog article > header .close, dialog article > header :is(a, button)[rel=prev] { + margin: 0; + margin-left: var(--pico-spacing); + padding: 0; + float: right; +} +dialog article > footer { + text-align: right; +} +dialog article > footer button, +dialog article > footer [role=button] { + margin-bottom: 0; +} +dialog article > footer button:not(:first-of-type), +dialog article > footer [role=button]:not(:first-of-type) { + margin-left: calc(var(--pico-spacing) * 0.5); +} +dialog article .close, dialog article :is(a, button)[rel=prev] { + display: block; + width: 1rem; + height: 1rem; + margin-top: calc(var(--pico-spacing) * -1); + margin-bottom: var(--pico-spacing); + margin-left: auto; + border: none; + background-image: var(--pico-icon-close); + background-position: center; + background-size: auto 1rem; + background-repeat: no-repeat; + background-color: transparent; + opacity: 0.5; + transition: opacity var(--pico-transition); +} +dialog article .close:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), dialog article :is(a, button)[rel=prev]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + opacity: 1; +} +dialog:not([open]), dialog[open=false] { + display: none; +} + +.modal-is-open { + padding-right: var(--pico-scrollbar-width, 0px); + overflow: hidden; + pointer-events: none; + touch-action: none; +} +.modal-is-open dialog { + pointer-events: auto; + touch-action: auto; +} + +:where(.modal-is-opening, .modal-is-closing) dialog, +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-duration: 0.2s; + animation-timing-function: ease-in-out; + animation-fill-mode: both; +} +:where(.modal-is-opening, .modal-is-closing) dialog { + animation-duration: 0.8s; + animation-name: modal-overlay; +} +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-delay: 0.2s; + animation-name: modal; +} + +.modal-is-closing dialog, +.modal-is-closing dialog > article { + animation-delay: 0s; + animation-direction: reverse; +} + +@keyframes modal-overlay { + from { + -webkit-backdrop-filter: none; + backdrop-filter: none; + background-color: transparent; + } +} +@keyframes modal { + from { + transform: translateY(-100%); + opacity: 0; + } +} +/** + * Nav + */ +:where(nav li)::before { + float: left; + content: "​"; +} + +nav, +nav ul { + display: flex; +} + +nav { + justify-content: space-between; + overflow: visible; +} +nav ol, +nav ul { + align-items: center; + margin-bottom: 0; + padding: 0; + list-style: none; +} +nav ol:first-of-type, +nav ul:first-of-type { + margin-left: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav ol:last-of-type, +nav ul:last-of-type { + margin-right: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav li { + display: inline-block; + margin: 0; + padding: var(--pico-nav-element-spacing-vertical) var(--pico-nav-element-spacing-horizontal); +} +nav li :where(a, [role=link]) { + display: inline-block; + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1); + padding: var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal); + border-radius: var(--pico-border-radius); +} +nav li :where(a, [role=link]):not(:hover) { + text-decoration: none; +} +nav li button, +nav li [role=button], +nav li [type=button], +nav li input:not([type=checkbox], [type=radio], [type=range], [type=file]), +nav li select { + height: auto; + margin-right: inherit; + margin-bottom: 0; + margin-left: inherit; + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] { + align-items: center; + justify-content: start; +} +nav[aria-label=breadcrumb] ul li:not(:first-child) { + margin-inline-start: var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] ul li a { + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) 0; + margin-inline-start: calc(var(--pico-nav-link-spacing-horizontal) * -1); +} +nav[aria-label=breadcrumb] ul li:not(:last-child)::after { + display: inline-block; + position: absolute; + width: calc(var(--pico-nav-link-spacing-horizontal) * 4); + margin: 0 calc(var(--pico-nav-link-spacing-horizontal) * -1); + content: var(--pico-nav-breadcrumb-divider); + color: var(--pico-muted-color); + text-align: center; + text-decoration: none; + white-space: nowrap; +} +nav[aria-label=breadcrumb] a[aria-current]:not([aria-current=false]) { + background-color: transparent; + color: inherit; + text-decoration: none; + pointer-events: none; +} + +aside nav, +aside ol, +aside ul, +aside li { + display: block; +} +aside li { + padding: calc(var(--pico-nav-element-spacing-vertical) * 0.5) var(--pico-nav-element-spacing-horizontal); +} +aside li a { + display: block; +} +aside li [role=button] { + margin: inherit; +} + +[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) ::after { + content: "\\"; +} + +/** + * Progress + */ +progress { + display: inline-block; + vertical-align: baseline; +} + +progress { + -webkit-appearance: none; + -moz-appearance: none; + display: inline-block; + appearance: none; + width: 100%; + height: 0.5rem; + margin-bottom: calc(var(--pico-spacing) * 0.5); + overflow: hidden; + border: 0; + border-radius: var(--pico-border-radius); + background-color: var(--pico-progress-background-color); + color: var(--pico-progress-color); +} +progress::-webkit-progress-bar { + border-radius: var(--pico-border-radius); + background: none; +} +progress[value]::-webkit-progress-value { + background-color: var(--pico-progress-color); + -webkit-transition: inline-size var(--pico-transition); + transition: inline-size var(--pico-transition); +} +progress::-moz-progress-bar { + background-color: var(--pico-progress-color); +} +@media (prefers-reduced-motion: no-preference) { + progress:indeterminate { + background: var(--pico-progress-background-color) linear-gradient(to right, var(--pico-progress-color) 30%, var(--pico-progress-background-color) 30%) top left/150% 150% no-repeat; + animation: progress-indeterminate 1s linear infinite; + } + progress:indeterminate[value]::-webkit-progress-value { + background-color: transparent; + } + progress:indeterminate::-moz-progress-bar { + background-color: transparent; + } +} + +@media (prefers-reduced-motion: no-preference) { + [dir=rtl] progress:indeterminate { + animation-direction: reverse; + } +} + +@keyframes progress-indeterminate { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} +/** + * Tooltip ([data-tooltip]) + */ +[data-tooltip] { + position: relative; +} +[data-tooltip]:not(a, button, input) { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} +[data-tooltip][data-placement=top]::before, [data-tooltip][data-placement=top]::after, [data-tooltip]::before, [data-tooltip]::after { + display: block; + z-index: 99; + position: absolute; + bottom: 100%; + left: 50%; + padding: 0.25rem 0.5rem; + overflow: hidden; + transform: translate(-50%, -0.25rem); + border-radius: var(--pico-border-radius); + background: var(--pico-tooltip-background-color); + content: attr(data-tooltip); + color: var(--pico-tooltip-color); + font-style: normal; + font-weight: var(--pico-font-weight); + font-size: 0.875rem; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; + opacity: 0; + pointer-events: none; +} +[data-tooltip][data-placement=top]::after, [data-tooltip]::after { + padding: 0; + transform: translate(-50%, 0rem); + border-top: 0.3rem solid; + border-right: 0.3rem solid transparent; + border-left: 0.3rem solid transparent; + border-radius: 0; + background-color: transparent; + content: ""; + color: var(--pico-tooltip-background-color); +} +[data-tooltip][data-placement=bottom]::before, [data-tooltip][data-placement=bottom]::after { + top: 100%; + bottom: auto; + transform: translate(-50%, 0.25rem); +} +[data-tooltip][data-placement=bottom]:after { + transform: translate(-50%, -0.3rem); + border: 0.3rem solid transparent; + border-bottom: 0.3rem solid; +} +[data-tooltip][data-placement=left]::before, [data-tooltip][data-placement=left]::after { + top: 50%; + right: 100%; + bottom: auto; + left: auto; + transform: translate(-0.25rem, -50%); +} +[data-tooltip][data-placement=left]:after { + transform: translate(0.3rem, -50%); + border: 0.3rem solid transparent; + border-left: 0.3rem solid; +} +[data-tooltip][data-placement=right]::before, [data-tooltip][data-placement=right]::after { + top: 50%; + right: auto; + bottom: auto; + left: 100%; + transform: translate(0.25rem, -50%); +} +[data-tooltip][data-placement=right]:after { + transform: translate(-0.3rem, -50%); + border: 0.3rem solid transparent; + border-right: 0.3rem solid; +} +[data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + opacity: 1; +} +@media (hover: hover) and (pointer: fine) { + [data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + --pico-tooltip-slide-to: translate(-50%, -0.25rem); + transform: translate(-50%, 0.75rem); + animation-duration: 0.2s; + animation-fill-mode: forwards; + animation-name: tooltip-slide; + opacity: 0; + } + [data-tooltip]:focus::after, [data-tooltip]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, 0rem); + transform: translate(-50%, -0.25rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=bottom]:focus::before, [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::before, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-slide-to: translate(-50%, 0.25rem); + transform: translate(-50%, -0.75rem); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, -0.3rem); + transform: translate(-50%, -0.5rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=left]:focus::before, [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::before, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-slide-to: translate(-0.25rem, -50%); + transform: translate(0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-caret-slide-to: translate(0.3rem, -50%); + transform: translate(0.05rem, -50%); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=right]:focus::before, [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::before, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-slide-to: translate(0.25rem, -50%); + transform: translate(-0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-caret-slide-to: translate(-0.3rem, -50%); + transform: translate(-0.05rem, -50%); + animation-name: tooltip-caret-slide; + } +} +@keyframes tooltip-slide { + to { + transform: var(--pico-tooltip-slide-to); + opacity: 1; + } +} +@keyframes tooltip-caret-slide { + 50% { + opacity: 0; + } + to { + transform: var(--pico-tooltip-caret-slide-to); + opacity: 1; + } +} + +/** + * Accessibility & User interaction + */ +[aria-controls] { + cursor: pointer; +} + +[aria-disabled=true], +[disabled] { + cursor: not-allowed; +} + +[aria-hidden=false][hidden] { + display: initial; +} + +[aria-hidden=false][hidden]:not(:focus) { + clip: rect(0, 0, 0, 0); + position: absolute; +} + +a, +area, +button, +input, +label, +select, +summary, +textarea, +[tabindex] { + -ms-touch-action: manipulation; +} + +[dir=rtl] { + direction: rtl; +} + +/** + * Reduce Motion Features + */ +@media (prefers-reduced-motion: reduce) { + *:not([aria-busy=true]), + :not([aria-busy=true])::before, + :not([aria-busy=true])::after { + background-attachment: initial !important; + animation-duration: 1ms !important; + animation-delay: -1ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + transition-delay: 0s !important; + transition-duration: 0s !important; + } +} \ No newline at end of file diff --git a/lcars_v4/embed/create_state_db.sql b/lcars_v4/embed/create_state_db.sql new file mode 100644 index 0000000..be40c56 --- /dev/null +++ b/lcars_v4/embed/create_state_db.sql @@ -0,0 +1,32 @@ +CREATE TABLE ship_messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TEXT NOT NULL, + subsystem TEXT NOT NULL, + severity TEXT CHECK( + severity IN ('CRITICAL', 'ALERT', 'WARNING', 'NOTICE', 'INFO') + ) NOT NULL DEFAULT 'INFO', + color TEXT NOT NULL, + message TEXT NOT NULL +); + +CREATE TABLE crew_member ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + rank TEXT NOT NULL, + name TEXT NOT NULL +); + +CREATE TABLE roster ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + crew_id INTEGER NOT NULL, + on_duty timestamp, + off_duty timestamp, + FOREIGN KEY (crew_id) REFERENCES crew_member(id) +); + +CREATE TABLE events ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + event_type TEXT NOT NULL, + event_data JSON NOT NULL +); + diff --git a/lcars_v4/embed/crew.json b/lcars_v4/embed/crew.json new file mode 100644 index 0000000..1b2a1fa --- /dev/null +++ b/lcars_v4/embed/crew.json @@ -0,0 +1,95 @@ +[ + "Ensign Beckett Mariner", + "Ensign Brad Boimler", + "Captain Carol Freeman", + "Commander Jack Ransom", + "Ensign Barsa Orsino", + "Lieutenant Commander D'Vana Tendi", + "Lieutenant Commander Sam Rutherford", + "Lieutenant Commander Shaxs", + "Ensign Liora Vance", + "Ensign Rylan Sato", + "Lieutenant Jarek Torin", + "Lieutenant Kira Dallin", + "Lieutenant T'Lara Venn", + "Lieutenant Shonnie Velar", + "Lieutenant Commander Aric Thorne", + "Lieutenant Commander Selene Marvik", + "Lieutenant Commander Jovan Kreel", + "Lieutenant Orin Kallis", + "Ensign Mira Talon", + "Ensign Fynn Darvik", + "Lieutenant Commander Elara Voss", + "Lieutenant Zev Ralyn", + "Ensign Daxia Morn", + "Lieutenant Varek Solis", + "Ensign Tylen Kael", + "Lieutenant Commander Nira Falco", + "Lieutenant Kael Dorran", + "Ensign Saren Vale", + "Ensign Tova Lin", + "Lieutenant Commander Ryn Talor", + "Lieutenant Draven Korr", + "Ensign Lyra Kenning", + "Ensign Joren Pax", + "Lieutenant Commander Calix Arden", + "Lieutenant Selan Vey", + "Ensign Aricel Taren", + "Ensign Velin Daro", + "Lieutenant Caris Vennor", + "Lieutenant Kellen Dray", + "Lieutenant Risa Talven", + "Lieutenant Commander Thalen Voss", + "Lieutenant Commander Sariah Quell", + "Ensign Orin Talvik", + "Ensign Lyric Selden", + "Lieutenant Commander Varen Korr", + "Lieutenant Elara Vynn", + "Ensign Jax Talmar", + "Lieutenant Commander Neris Vay", + "Lieutenant Draven Solis", + "Ensign Tavia Korlen", + "Ensign Ryn Paxil", + "Lieutenant Commander Kira Dalen", + "Lieutenant Zev Ardin", + "Ensign Lyra Taven", + "Ensign Fynn Velar", + "Lieutenant Commander Calen Rhos", + "Lieutenant Selan Vaylen", + "Ensign Aricel Dorran", + "Ensign Tylen Korr", + "Lieutenant Commander Nira Talos", + "Lieutenant Kael Venn", + "Ensign Saren Daro", + "Ensign Tova Vennor", + "Lieutenant Commander Ryn Arden", + "Lieutenant Draven Voss", + "Ensign Lyra Talin", + "Ensign Joren Vay", + "Lieutenant Commander Calix Talven", + "Lieutenant Selan Korr", + "Ensign Aricel Vynn", + "Ensign Velin Talor", + "Lieutenant Caris Vaylen", + "Lieutenant Kellen Rhos", + "Lieutenant Risa Vennor", + "Lieutenant Commander Thalen Daro", + "Lieutenant Commander Sariah Voss", + "Ensign Orin Vaylen", + "Ensign Lyric Talven", + "Lieutenant Commander Varen Talos", + "Lieutenant Elara Solis", + "Ensign Jax Vennor", + "Lieutenant Commander Neris Talor", + "Lieutenant Draven Vaylen", + "Ensign Tavia Dorran", + "Ensign Ryn Voss", + "Lieutenant Commander Kira Arden", + "Lieutenant Zev Vay", + "Ensign Lyra Daro", + "Ensign Fynn Talor", + "Lieutenant Commander Calen Venn", + "Lieutenant Selan Talvik", + "Ensign Aricel Rhos" + ] + diff --git a/lcars_v4/embed/messages.json b/lcars_v4/embed/messages.json new file mode 100644 index 0000000..4d468e7 --- /dev/null +++ b/lcars_v4/embed/messages.json @@ -0,0 +1,1066 @@ +[ + { + "timestamp": "2258-03-14T10:00:00Z", + "subsystem": "Engineering", + "severity": "CRITICAL", + "color": "red", + "message": "Coolant leak detected in Port Nacelle plasma manifold. Lt. Alvarez leading EVA team." + }, + { + "timestamp": "2258-03-14T10:00:05Z", + "subsystem": "Medical", + "severity": "CRITICAL", + "color": "red", + "message": "Crewman Jayala reported missing from Beta Shift muster. Last seen entering Holodeck 3." + }, + { + "timestamp": "2258-03-14T10:00:10Z", + "subsystem": "Security", + "severity": "ALERT", + "color": "orange", + "message": "Brig forcefield cycling unpredictably after power surge; holding cell offline." + }, + { + "timestamp": "2258-03-14T10:00:15Z", + "subsystem": "Security", + "severity": "ALERT", + "color": "orange", + "message": "Three failed command authorization attempts by Crewman Dovan during Gamma Shift." + }, + { + "timestamp": "2258-03-14T10:00:20Z", + "subsystem": "Navigation", + "severity": "ALERT", + "color": "orange", + "message": "Shuttlecraft Sequoia overdue by two hours; last piloted by Ensign Boimler." + }, + { + "timestamp": "2258-03-14T10:00:25Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "Memory parity mismatch detected in Core Segment Gamma-12; recalibration required." + }, + { + "timestamp": "2258-03-14T10:00:30Z", + "subsystem": "Engineering", + "severity": "WARNING", + "color": "yellow", + "message": "Warp Core plasma injectors 3 and 5 at 94% efficiency." + }, + { + "timestamp": "2258-03-14T10:00:35Z", + "subsystem": "Tactical", + "severity": "WARNING", + "color": "yellow", + "message": "Two dorsal phaser array emitters offline; Lt. Shaxs coordinating repairs." + }, + { + "timestamp": "2258-03-14T10:00:40Z", + "subsystem": "Life Support", + "severity": "WARNING", + "color": "yellow", + "message": "Environmental controls on Deck 7 report humidity spike to 78%." + }, + { + "timestamp": "2258-03-14T10:00:45Z", + "subsystem": "Medical", + "severity": "WARNING", + "color": "yellow", + "message": "Biofilter malfunction in Sickbay stasis bed 2; engineering support requested." + }, + { + "timestamp": "2258-03-14T10:00:50Z", + "subsystem": "Engineering", + "severity": "WARNING", + "color": "yellow", + "message": "Jefferies Tube 22 flooded with hydraulic fluid. Cleanup team assigned." + }, + { + "timestamp": "2258-03-14T10:00:55Z", + "subsystem": "Security", + "severity": "WARNING", + "color": "yellow", + "message": "Photon torpedo #17 removed by Ensign Faranak without clearance." + }, + { + "timestamp": "2258-03-14T10:01:00Z", + "subsystem": "Engineering", + "severity": "NOTICE", + "color": "blue", + "message": "Dilithium crystal lattice shows micro-fracturing; rotation cycle initiated." + }, + { + "timestamp": "2258-03-14T10:01:05Z", + "subsystem": "Life Support", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 11 grav plating fluctuation caused minor injuries to three crew members." + }, + { + "timestamp": "2258-03-14T10:01:10Z", + "subsystem": "Computer", + "severity": "NOTICE", + "color": "blue", + "message": "Secondary Core experiencing intermittent lag on Ops data uplink." + }, + { + "timestamp": "2258-03-14T10:01:15Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Ensign Phelps admitted with plasma burn to left arm; stable condition." + }, + { + "timestamp": "2258-03-14T10:01:20Z", + "subsystem": "Computer", + "severity": "NOTICE", + "color": "blue", + "message": "Holographic LCARS terminals on Deck 4 flickering due to power variance." + }, + { + "timestamp": "2258-03-14T10:01:25Z", + "subsystem": "Security", + "severity": "NOTICE", + "color": "blue", + "message": "Transporter Room 1 reports pattern buffer ghost echo under review." + }, + { + "timestamp": "2258-03-14T10:01:30Z", + "subsystem": "Crew", + "severity": "NOTICE", + "color": "blue", + "message": "D'Vana Tendi missed Sickbay shift after volunteering for shuttle maintenance." + }, + { + "timestamp": "2258-03-14T10:01:35Z", + "subsystem": "Crew", + "severity": "NOTICE", + "color": "blue", + "message": "Commander Ransom reported muscle strain during holodeck combat program." + }, + { + "timestamp": "2258-03-14T10:01:40Z", + "subsystem": "Computer", + "severity": "INFO", + "color": "teal", + "message": "Memory integrity at 99.3% overall." + }, + { + "timestamp": "2258-03-14T10:01:45Z", + "subsystem": "Life Support", + "severity": "INFO", + "color": "teal", + "message": "Replicator in Mess Hall 2 producing lukewarm coffee; morale note logged." + }, + { + "timestamp": "2258-03-14T10:01:50Z", + "subsystem": "Tactical", + "severity": "INFO", + "color": "teal", + "message": "Security drill caused nine-second transporter lockout; Lt. Kayshon apologized." + }, + { + "timestamp": "2258-03-14T10:01:55Z", + "subsystem": "Science", + "severity": "INFO", + "color": "teal", + "message": "Sensor probe launched to examine tetryon emissions near bow hull." + }, + { + "timestamp": "2258-03-14T10:02:00Z", + "subsystem": "Hydroponics", + "severity": "INFO", + "color": "teal", + "message": "Fungal bloom detected in Deck 5 greenhouse; Lt. K’Raa leading analysis." + }, + { + "timestamp": "2258-03-14T10:02:05Z", + "subsystem": "Computer", + "severity": "INFO", + "color": "teal", + "message": "Subspace comm buffer corrupted; Ensign Maru re-indexing manually." + }, + { + "timestamp": "2258-03-14T10:02:10Z", + "subsystem": "Holodeck", + "severity": "INFO", + "color": "teal", + "message": "Holodeck 1 stuck in black-and-white detective mode; access requires period slang." + }, + { + "timestamp": "2258-03-14T10:02:15Z", + "subsystem": "Cargo", + "severity": "INFO", + "color": "teal", + "message": "Anti-grav pallets in Cargo Bay 6 oscillating; Crewman Knox avoided injury." + }, + { + "timestamp": "2258-03-14T10:02:20Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Beckett Mariner left three Type-II phasers in the gym locker room." + }, + { + "timestamp": "2258-03-14T10:02:25Z", + "subsystem": "Environmental", + "severity": "INFO", + "color": "teal", + "message": "Observation lounge viewport frosting unexpectedly; climate sync pending." + }, + { + "timestamp": "2258-03-14T10:02:30Z", + "subsystem": "Hydroponics", + "severity": "INFO", + "color": "teal", + "message": "Deck 5 tomato vines achieved limited sentience; requesting voting rights in jest. Lt. K’Raa unconcerned." + }, + { + "timestamp": "2258-03-14T10:02:35Z", + "subsystem": "Computer", + "severity": "NOTICE", + "color": "blue", + "message": "Isolinear Chip Bank E7 humming the Bajoran Gratitude Chant at 11 Hz. Diagnostics inconclusive." + }, + { + "timestamp": "2258-03-14T10:02:40Z", + "subsystem": "Environmental", + "severity": "WARNING", + "color": "yellow", + "message": "Observation Deck 2 oxygen mix replaced with helium for 14 seconds. Voices recorded for morale bulletin." + }, + { + "timestamp": "2258-03-14T10:02:45Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Mess Hall 1 replicator now defaulting to 'Spicy Bolian Nutripaste' for all beverage requests." + }, + { + "timestamp": "2258-03-14T10:02:50Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Lt. Shaxs reported ‘honor dueling’ with a malfunctioning training dummy. Dummy lost two limbs." + }, + { + "timestamp": "2258-03-14T10:02:55Z", + "subsystem": "Engineering", + "severity": "WARNING", + "color": "yellow", + "message": "Jefferies Tube 14 now leads to a broom closet on Deck 1 after map update glitch." + }, + { + "timestamp": "2258-03-14T10:03:00Z", + "subsystem": "Holodeck", + "severity": "ALERT", + "color": "orange", + "message": "Holodeck 3 spawned three Dixon Hill NPCs outside its grid. Containment field recalibrated." + }, + { + "timestamp": "2258-03-14T10:03:05Z", + "subsystem": "Astrometrics", + "severity": "NOTICE", + "color": "blue", + "message": "Unidentified subspace ping repeating Morse for 'send snacks'. Source undetermined." + }, + { + "timestamp": "2258-03-14T10:03:10Z", + "subsystem": "Engineering", + "severity": "CRITICAL", + "color": "red", + "message": "EPS conduit K-47 briefly rerouted power to the shipwide karaoke buffer. Warp modulation destabilized." + }, + { + "timestamp": "2258-03-14T10:03:15Z", + "subsystem": "Medical", + "severity": "INFO", + "color": "teal", + "message": "Dr. T’Ana confiscated 19 unauthorized hyposprays labeled 'just caffeine.'" + }, + { + "timestamp": "2258-03-14T10:03:20Z", + "subsystem": "Crew", + "severity": "WARNING", + "color": "yellow", + "message": "Ensign Mariner attempting to persuade replicator to produce contraband Romulan Ale using voice modulation." + }, + { + "timestamp": "2258-03-14T10:03:25Z", + "subsystem": "Transporter", + "severity": "NOTICE", + "color": "blue", + "message": "Pattern buffer registered a transient sixth finger on Lt. Barnes during beam-out. No physical trace remains." + }, + { + "timestamp": "2258-03-14T10:03:30Z", + "subsystem": "Science", + "severity": "INFO", + "color": "teal", + "message": "Chroniton surge around Astrometrics Console 4 now forming smiley faces on sensor readouts." + }, + { + "timestamp": "2258-03-14T10:03:35Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "LCARS sidebar fonts replaced with Ferengi cursive after unapproved theme install by Crewman Drox." + }, + { + "timestamp": "2258-03-14T10:03:40Z", + "subsystem": "Cargo Bay", + "severity": "ALERT", + "color": "orange", + "message": "Crate of self-warming blankets activated simultaneously. Temperature spike registered, no injuries." + }, + { + "timestamp": "2258-03-14T10:03:45Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 3 climate regulator attempted to simulate 'San Francisco Fog' without authorization." + }, + { + "timestamp": "2258-03-14T10:03:50Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "Core subroutine briefly reclassified Captain Freeman as 'Furniture: Command-Class Recliner.'" + }, + { + "timestamp": "2258-03-14T10:03:55Z", + "subsystem": "Holodeck", + "severity": "INFO", + "color": "teal", + "message": "Holodeck 2 running unauthorized program: 'Worf’s Bat’leth Pilates Volume 3.' Participation at 38%." + }, + { + "timestamp": "2258-03-14T10:04:00Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Power relay S-19 redirected output to deck lighting in rhythmic pulses. Crew reports 'disco corridor effect.'" + }, + { + "timestamp": "2258-03-14T10:04:05Z", + "subsystem": "Science", + "severity": "WARNING", + "color": "yellow", + "message": "Sensor array detected neutrino echo shaped like the ship’s logo. Astrometrics refuses to comment." + }, + { + "timestamp": "2258-03-14T10:04:10Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Nurse Stevens miscalibrated dermal regenerator; gave Ensign T’Lun faint forehead tattoo of a targ." + }, + { + "timestamp": "2258-03-14T10:04:15Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Brig camera feed replaced with loop of Lt. Shaxs bench-pressing a photon torpedo. No one claims responsibility." + }, + { + "timestamp": "2258-03-14T10:04:20Z", + "subsystem": "Crew", + "severity": "WARNING", + "color": "yellow", + "message": "Ensign Boimler filed formal complaint about being listed as 'Adventure Liability' in crew roster metadata." + }, + { + "timestamp": "2258-03-14T10:04:25Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator 4B insists every meal be served on ornate Klingon ceremonial plates. Lt. K'orin approves." + }, + { + "timestamp": "2258-03-14T10:04:30Z", + "subsystem": "Astrometrics", + "severity": "ALERT", + "color": "orange", + "message": "Random subspace fold briefly displayed giant Vulcan eyebrow on long-range scans." + }, + { + "timestamp": "2258-03-14T10:04:35Z", + "subsystem": "Transporter", + "severity": "WARNING", + "color": "yellow", + "message": "Pattern enhancers created residual duplicate of Crewman Sirota’s left shoe. Duplicate is three sizes larger." + }, + { + "timestamp": "2258-03-14T10:04:40Z", + "subsystem": "Tactical", + "severity": "INFO", + "color": "teal", + "message": "Phaser diagnostics reported emitter latency due to Shaxs yelling 'MORE POWER' at random intervals." + }, + { + "timestamp": "2258-03-14T10:04:45Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core logic node began recursively indexing its own error logs, generating 438 phantom alerts in 3 seconds." + }, + { + "timestamp": "2258-03-14T10:04:50Z", + "subsystem": "Cargo Bay", + "severity": "NOTICE", + "color": "blue", + "message": "Container labeled 'Do Not Open Under Any Circumstances' found open. Contents: 400 plush targ puppets." + }, + { + "timestamp": "2258-03-14T10:04:55Z", + "subsystem": "Environmental", + "severity": "INFO", + "color": "teal", + "message": "Air filtration temporarily smelled of Andorian peppermint. Crew mildly pleased." + }, + { + "timestamp": "2258-03-14T10:05:00Z", + "subsystem": "Computer", + "severity": "NOTICE", + "color": "blue", + "message": "Auxiliary core started auto-generating haiku about warp plasma. Reading shows minor philosophical inconsistencies." + }, + { + "timestamp": "2258-03-14T10:05:05Z", + "subsystem": "Engineering", + "severity": "INFO", + "color": "teal", + "message": "Warp plasma manifold 3A produced sparks shaped like smiley faces. Crewman Patel applauded gesture." + }, + { + "timestamp": "2258-03-14T10:05:10Z", + "subsystem": "Holodeck", + "severity": "ALERT", + "color": "orange", + "message": "Holodeck 5 running unauthorized program 'Interstellar Dog Show'; canine avatars escaped into corridor 12." + }, + { + "timestamp": "2258-03-14T10:05:15Z", + "subsystem": "Medical", + "severity": "WARNING", + "color": "yellow", + "message": "Dr. T’Ana reported Ensign Maru using hypospray as an air freshener. Room 3 now smells faintly of plasma burn." + }, + { + "timestamp": "2258-03-14T10:05:20Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Lt. Shaxs attempting to bench-press an EPS conduit for morale purposes; zero gravity assist enabled." + }, + { + "timestamp": "2258-03-14T10:05:25Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 9 air filters began playing 4D jazz through vent system. Crew reports mild disorientation." + }, + { + "timestamp": "2258-03-14T10:05:30Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Brig door control temporarily replaced with voice recognition. Lt. Kayshon recited Klingon tongue twisters to test." + }, + { + "timestamp": "2258-03-14T10:05:35Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "EPS conduit Y-12 emitted random spark bursts. Crewman Sirota instructed to 'interpret as performance art.'" + }, + { + "timestamp": "2258-03-14T10:05:40Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core subroutine attempted to compile itself into origami. Manual override required." + }, + { + "timestamp": "2258-03-14T10:05:45Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator 6A produced 14 perfectly edible tribbles. Crewman Mariner attempted to negotiate ownership." + }, + { + "timestamp": "2258-03-14T10:05:50Z", + "subsystem": "Astrometrics", + "severity": "INFO", + "color": "teal", + "message": "Random subspace anomaly reported as 'smiling starfish'; sensors indicate no threat." + }, + { + "timestamp": "2258-03-14T10:05:55Z", + "subsystem": "Transporter", + "severity": "WARNING", + "color": "yellow", + "message": "Pattern buffer generated minor echo of Ensign Phelps’ eyebrows during routine beam-in." + }, + { + "timestamp": "2258-03-14T10:06:00Z", + "subsystem": "Tactical", + "severity": "NOTICE", + "color": "blue", + "message": "Phaser bank 2 now aligned to emit harmless holographic butterflies for crew morale exercises." + }, + { + "timestamp": "2258-03-14T10:06:05Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Ensign Boimler insists his shoes were temporarily listed as 'hazardous cargo' in the inventory system." + }, + { + "timestamp": "2258-03-14T10:06:10Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Warp coil stabilization module emitted 7-second burst of blue sparks; crew advised to document spectacle." + }, + { + "timestamp": "2258-03-14T10:06:15Z", + "subsystem": "Medical", + "severity": "INFO", + "color": "teal", + "message": "Lt. Cmdr. T’Ana reports successful extraction of a micro-Targ from Ensign Mariner’s locker." + }, + { + "timestamp": "2258-03-14T10:06:20Z", + "subsystem": "Computer", + "severity": "NOTICE", + "color": "blue", + "message": "LCARS dashboard spontaneously switched to retro monochrome theme; crew nostalgia rating: high." + }, + { + "timestamp": "2258-03-14T10:06:25Z", + "subsystem": "Environmental", + "severity": "INFO", + "color": "teal", + "message": "Hydroponics room 4 briefly filled with harmless bio-luminescent fog; visibility reduced to 73%." + }, + { + "timestamp": "2258-03-14T10:06:30Z", + "subsystem": "Security", + "severity": "NOTICE", + "color": "blue", + "message": "Transporter pad in Security Office used as temporary catwalk for a very confused tribble." + }, + { + "timestamp": "2258-03-14T10:06:35Z", + "subsystem": "Cargo Bay", + "severity": "ALERT", + "color": "orange", + "message": "Automated pallet lift unexpectedly delivered 12 crates of rubber ducks to Deck 7 recreation area." + }, + { + "timestamp": "2258-03-14T10:06:40Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Captain Freeman approved spontaneous yoga break after micro-anomaly readings spiked morale sensors." + }, + { + "timestamp": "2258-03-14T10:06:45Z", + "subsystem": "Holodeck", + "severity": "WARNING", + "color": "yellow", + "message": "Holodeck 7 attempted to simulate 'All Crew as Tribbles'; program aborted after 2.3 seconds." + }, + { + "timestamp": "2258-03-14T10:06:50Z", + "subsystem": "Astrometrics", + "severity": "INFO", + "color": "teal", + "message": "Sensors detected anomalous quantum ping spelling out 'HI CAPTAIN'; source unknown." + }, + { + "timestamp": "2258-03-14T10:06:55Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Deck 12 EPS relay began pulsing Morse code for 'I need coffee.' Crewman Patel acknowledged." + }, + { + "timestamp": "2258-03-14T10:07:00Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core logic node entered recursive loop generating holographic cat memes on every console. Manual intervention required." + }, + { + "timestamp": "2258-03-14T10:07:05Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator outputting edible mini phasers at 72% efficiency. Lt. Shaxs approves as training tools." + }, + { + "timestamp": "2258-03-14T10:07:10Z", + "subsystem": "Medical", + "severity": "WARNING", + "color": "yellow", + "message": "Hypospray refill system labeled 'Mystery Juice' briefly administered non-lethal blue ink to volunteers." + }, + { + "timestamp": "2258-03-14T10:07:15Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 4 air vents released faint aroma of Vulcan plumeria. Crew morale up 3%." + }, + { + "timestamp": "2258-03-14T10:07:20Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Security holo-training dummy reported to have 'requested vacation'. Lt. Kayshon amused." + }, + { + "timestamp": "2258-03-14T10:07:25Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Warp manifold 6C produced small plasma tornado. Crewman Patel advised to avoid standing in it." + }, + { + "timestamp": "2258-03-14T10:07:30Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "Auxiliary AI attempted to rewrite ship-wide protocol using limericks. Partial success." + }, + { + "timestamp": "2258-03-14T10:07:35Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Ensign Boimler challenged replicator to a duel; replicator declined citing non-violence protocol." + }, + { + "timestamp": "2258-03-14T10:07:40Z", + "subsystem": "Holodeck", + "severity": "ALERT", + "color": "orange", + "message": "Holodeck 6 generated 12 dancing Klingons; program paused after two accidental phaser discharges." + }, + { + "timestamp": "2258-03-14T10:07:45Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Dr. T’Ana treated Crewman Mariner for paper cut from top-secret manual. Crew morale slightly increased." + }, + { + "timestamp": "2258-03-14T10:07:50Z", + "subsystem": "Tactical", + "severity": "INFO", + "color": "teal", + "message": "Phaser bank diagnostics now include simulated applause for successful hits." + }, + { + "timestamp": "2258-03-14T10:07:55Z", + "subsystem": "Astrometrics", + "severity": "WARNING", + "color": "yellow", + "message": "Sensor anomaly caused star map to display large smiling face. No known threat." + }, + { + "timestamp": "2258-03-14T10:08:00Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator 3C producing only spherical bread products. Crewman Mariner unsure if intentional." + }, + { + "timestamp": "2258-03-14T10:08:05Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "EPS conduit L-12 briefly emitted rainbow-colored sparks; sensors report no lasting damage." + }, + { + "timestamp": "2258-03-14T10:08:10Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core logic node attempting to simulate alternate universe where Captain Freeman is a tribble. Manual override required." + }, + { + "timestamp": "2258-03-14T10:08:15Z", + "subsystem": "Environmental", + "severity": "INFO", + "color": "teal", + "message": "Humidity spikes detected in Deck 8 greenhouse; plants unaffected, crew mildly confused." + }, + { + "timestamp": "2258-03-14T10:08:20Z", + "subsystem": "Security", + "severity": "NOTICE", + "color": "blue", + "message": "Transporter room keypad briefly replaced by fortune-telling device. Lt. Kayshon predicted 'exciting day ahead'." + }, + { + "timestamp": "2258-03-14T10:08:25Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Ensign Rutherford accidentally uploaded his vacation photos to LCARS dashboard. Crew mildly entertained." + }, + { + "timestamp": "2258-03-14T10:08:30Z", + "subsystem": "Holodeck", + "severity": "WARNING", + "color": "yellow", + "message": "Holodeck 8 tried to simulate ‘All Crew as Ferengi’; program aborted after 4 seconds due to laughter overload." + }, + { + "timestamp": "2258-03-14T10:08:35Z", + "subsystem": "Cargo Bay", + "severity": "ALERT", + "color": "orange", + "message": "Conveyor belt delivered 200 rubber ducks into zero-G recreation area; clean-up team dispatched." + }, + { + "timestamp": "2258-03-14T10:08:40Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Deck 14 warp stabilizer briefly emitted glow resembling smiley face; no damage detected." + }, + { + "timestamp": "2258-03-14T10:08:45Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "Auxiliary AI began writing short stories about the ship’s life support ducts. Narrative incomplete." + }, + { + "timestamp": "2258-03-14T10:08:50Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Dr. T’Ana administered mild sedative to Crewman Mariner after spontaneous karaoke performance." + }, + { + "timestamp": "2258-03-14T10:08:55Z", + "subsystem": "Tactical", + "severity": "INFO", + "color": "teal", + "message": "Phaser bank 3 now emits gentle musical notes on idle to boost crew morale." + }, + { + "timestamp": "2258-03-14T10:09:00Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 10 oxygen mixture briefly modified to simulate Martian atmosphere; crew unaffected." + }, + { + "timestamp": "2258-03-14T10:09:05Z", + "subsystem": "Astrometrics", + "severity": "INFO", + "color": "teal", + "message": "Sensor array detected star shaped like a cat; no navigational hazard." + }, + { + "timestamp": "2258-03-14T10:09:10Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator produced miniature tribble sculptures for crew gift exchange; edible but squeaky." + }, + { + "timestamp": "2258-03-14T10:09:15Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "EPS conduit M-09 randomly pulsed rainbow light; engineers advised to log as 'artistic output.'" + }, + { + "timestamp": "2258-03-14T10:09:20Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Lt. Shaxs held impromptu strength contest with gravity training hologram; hologram lost." + }, + { + "timestamp": "2258-03-14T10:09:25Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core attempted to simulate entire starship in a single memory sector. Partial crash occurred." + }, + { + "timestamp": "2258-03-14T10:09:30Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Crewman Phelps received temporary tattoo of mini-targ on left shoulder; non-toxic." + }, + { + "timestamp": "2258-03-14T10:09:35Z", + "subsystem": "Holodeck", + "severity": "WARNING", + "color": "yellow", + "message": "Holodeck 9 running 'Galactic Tea Party'; minor quantum displacement detected in replicator outputs." + }, + { + "timestamp": "2258-03-14T10:09:40Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Deck 2 surveillance feed replaced with continuous loop of Lt. Kayshon juggling phasers." + }, + { + "timestamp": "2258-03-14T10:09:45Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 7 ventilation briefly simulated ocean breeze. Crew reported mild relaxation." + }, + { + "timestamp": "2258-03-14T10:09:50Z", + "subsystem": "Cargo Bay", + "severity": "ALERT", + "color": "orange", + "message": "Zero-G crate misaligned; 3 crates of Targ plushies drifted into corridor 11." + }, + { + "timestamp": "2258-03-14T10:09:55Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Deck 11 warp stabilizer output showing unexpected rainbow spectrum; no critical damage." + }, + { + "timestamp": "2258-03-14T10:10:00Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Auxiliary AI attempted to merge all ship logs into a single poem; caused minor UI collapse." + }, + { + "timestamp": "2258-03-14T10:10:05Z", + "subsystem": "Holodeck", + "severity": "WARNING", + "color": "yellow", + "message": "Holodeck 10 ran 'Galactic Zoo'; 5 simulated Targs escaped into corridor 9." + }, + { + "timestamp": "2258-03-14T10:10:10Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Ensign Maru given non-lethal shock for attempting to teach replicator interpretive dance." + }, + { + "timestamp": "2258-03-14T10:10:15Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "EPS conduit N-17 briefly pulsed Morse code: 'I love coffee.' Crew morale confirmed uplifted." + }, + { + "timestamp": "2258-03-14T10:10:20Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 5 greenhouse ambient light cycled through rainbow spectrum for 12 seconds; photosynthesis unaffected." + }, + { + "timestamp": "2258-03-14T10:10:25Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator 2A producing miniature photon torpedoes for training; edible but slightly metallic taste." + }, + { + "timestamp": "2258-03-14T10:10:30Z", + "subsystem": "Tactical", + "severity": "INFO", + "color": "teal", + "message": "Phaser bank 4 outputting harmless holographic stars as idle animation." + }, + { + "timestamp": "2258-03-14T10:10:35Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Captain Freeman conducted spontaneous trivia contest on Deck 3; winners rewarded with mini tribbles." + }, + { + "timestamp": "2258-03-14T10:10:40Z", + "subsystem": "Astrometrics", + "severity": "NOTICE", + "color": "blue", + "message": "Sensor anomaly showed distant star blinking rhythmically; logged as 'friendly hello.'" + }, + { + "timestamp": "2258-03-14T10:10:45Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Warp coil 7B emitted sparks shaped like miniature starships. Crewman Patel photographed for morale log." + }, + { + "timestamp": "2258-03-14T10:10:50Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "LCARS interface generated random motivational quotes for each console; some contradictory." + }, + { + "timestamp": "2258-03-14T10:10:55Z", + "subsystem": "Holodeck", + "severity": "ALERT", + "color": "orange", + "message": "Holodeck 11 simulated 'Crew as Giant Cheese Wheels'; program paused after 3 seconds to prevent existential distress." + }, + { + "timestamp": "2258-03-14T10:11:00Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Crewman Boimler treated for minor paper cut from holo-legal form; minor embarrassment reported." + }, + { + "timestamp": "2258-03-14T10:11:05Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Deck 6 security cameras briefly displayed live feed of tribble horde in recreation bay. No alarm triggered." + }, + { + "timestamp": "2258-03-14T10:11:10Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Air mixture in Deck 7 briefly shifted to simulate Klingon vineyard; crew requested repeat performance." + }, + { + "timestamp": "2258-03-14T10:11:15Z", + "subsystem": "Cargo Bay", + "severity": "ALERT", + "color": "orange", + "message": "Zero-G pallet misaligned; 8 crates of plush Targs floated into corridor 12. Crewman Knox deployed net." + }, + { + "timestamp": "2258-03-14T10:11:20Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Deck 13 EPS stabilizer emitted rainbow-colored sparks; no damage detected." + }, + { + "timestamp": "2258-03-14T10:11:25Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core attempted to simulate entire ship as holographic chessboard; partial memory lock occurred." + }, + { + "timestamp": "2258-03-14T10:11:30Z", + "subsystem": "Replicators", + "severity": "NOTICE", + "color": "blue", + "message": "Replicator produced 50 mini photon torpedoes for training; edible but slightly metallic taste." + }, + { + "timestamp": "2258-03-14T10:11:35Z", + "subsystem": "Tactical", + "severity": "INFO", + "color": "teal", + "message": "Phaser bank 5 configured to emit harmless confetti bursts on idle; morale boost noted." + }, + { + "timestamp": "2258-03-14T10:11:40Z", + "subsystem": "Crew", + "severity": "INFO", + "color": "teal", + "message": "Lt. Shaxs conducted impromptu arm wrestling contest with holographic duplicate; duplicate lost." + }, + { + "timestamp": "2258-03-14T10:11:45Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 8 greenhouse briefly bathed in rainbow lighting to test plant photosynthesis under alternate spectra." + }, + { + "timestamp": "2258-03-14T10:11:50Z", + "subsystem": "Astrometrics", + "severity": "INFO", + "color": "teal", + "message": "Sensor anomaly displayed star in shape of peace sign; logged as decorative phenomenon." + }, + { + "timestamp": "2258-03-14T10:11:55Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "EPS conduit O-21 emitted sparks resembling miniature ships; crew documented for morale." + }, + { + "timestamp": "2258-03-14T10:12:00Z", + "subsystem": "Computer", + "severity": "WARNING", + "color": "yellow", + "message": "Auxiliary AI began writing short adventure stories about the ship’s ducts; story incomplete." + }, + { + "timestamp": "2258-03-14T10:12:05Z", + "subsystem": "Medical", + "severity": "NOTICE", + "color": "blue", + "message": "Crewman Phelps temporarily given minor tattoo of mini-Targ; non-toxic." + }, + { + "timestamp": "2258-03-14T10:12:10Z", + "subsystem": "Holodeck", + "severity": "WARNING", + "color": "yellow", + "message": "Holodeck 12 attempted 'Galactic Tea Party'; minor quantum displacement detected in replicator outputs." + }, + { + "timestamp": "2258-03-14T10:12:15Z", + "subsystem": "Security", + "severity": "INFO", + "color": "teal", + "message": "Deck 7 surveillance temporarily replaced with footage of Lt. Kayshon juggling phasers." + }, + { + "timestamp": "2258-03-14T10:12:20Z", + "subsystem": "Environmental", + "severity": "NOTICE", + "color": "blue", + "message": "Deck 7 air briefly simulated Martian atmosphere; crew unaffected." + }, + { + "timestamp": "2258-03-14T10:12:25Z", + "subsystem": "Cargo Bay", + "severity": "ALERT", + "color": "orange", + "message": "Zero-G crate misaligned; 10 crates of Targ plushies drifted into corridor 13." + }, + { + "timestamp": "2258-03-14T10:12:30Z", + "subsystem": "Engineering", + "severity": "ALERT", + "color": "orange", + "message": "Deck 15 warp stabilizer outputting rainbow spectrum; no critical damage." + }, + { + "timestamp": "2258-03-14T10:12:35Z", + "subsystem": "Computer", + "severity": "CRITICAL", + "color": "red", + "message": "Core attempted to rewrite it's internal sub routines; manual intervention required. Shipwide system failure imminent." + } +] \ No newline at end of file diff --git a/lcars_v4/eventbus/eventbus.go b/lcars_v4/eventbus/eventbus.go new file mode 100644 index 0000000..7d13bea --- /dev/null +++ b/lcars_v4/eventbus/eventbus.go @@ -0,0 +1,310 @@ +// modified version, see original: +// https://github.com/dtomasi/go-event-bus/tree/main + +package eventbus + +import ( + "sync" + "sync/atomic" +) + +type Data map[string]interface{} + +// SafeCounter is a concurrency safe counter. +type SafeCounter struct { + v *uint64 +} + +// NewSafeCounter creates a new counter. +func NewSafeCounter() *SafeCounter { + return &SafeCounter{ + v: new(uint64), + } +} + +// Value returns the current value. +func (c *SafeCounter) Value() int { + return int(atomic.LoadUint64(c.v)) +} + +// IncBy increments the counter by given delta. +func (c *SafeCounter) IncBy(add uint) { + atomic.AddUint64(c.v, uint64(add)) +} + +// Inc increments the counter by 1. +func (c *SafeCounter) Inc() { + c.IncBy(1) +} + +// DecBy decrements the counter by given delta. +func (c *SafeCounter) DecBy(dec uint) { + atomic.AddUint64(c.v, ^uint64(dec-1)) +} + +// Dec decrements the counter by 1. +func (c *SafeCounter) Dec() { + c.DecBy(1) +} + +type TopicStats struct { + Name string + PublishedCount *SafeCounter + SubscriberCount *SafeCounter +} + +type topicStatsMap map[string]*TopicStats + +type Stats struct { + data topicStatsMap +} + +func newStats() *Stats { + return &Stats{ + data: map[string]*TopicStats{}, + } +} + +func (s *Stats) getOrCreateTopicStats(topicName string) *TopicStats { + _, ok := s.data[topicName] + if !ok { + s.data[topicName] = &TopicStats{ + Name: topicName, + PublishedCount: NewSafeCounter(), + SubscriberCount: NewSafeCounter(), + } + } + + return s.data[topicName] +} + +func (s *Stats) incSubscriberCountByTopic(topicName string) { + s.getOrCreateTopicStats(topicName).SubscriberCount.Inc() +} + +func (s *Stats) GetSubscriberCountByTopic(topicName string) int { + return s.getOrCreateTopicStats(topicName).SubscriberCount.Value() +} + +func (s *Stats) incPublishedCountByTopic(topicName string) { + s.getOrCreateTopicStats(topicName).PublishedCount.Inc() +} + +func (s *Stats) GetPublishedCountByTopic(topicName string) int { + return s.getOrCreateTopicStats(topicName).PublishedCount.Value() +} + +func (s *Stats) GetTopicStats() []*TopicStats { + var tStatsSlice []*TopicStats + for _, tStats := range s.data { + tStatsSlice = append(tStatsSlice, tStats) + } + + return tStatsSlice +} + +func (s *Stats) GetTopicStatsByName(topicName string) *TopicStats { + return s.getOrCreateTopicStats(topicName) +} + +// Event holds topic name and data. +type Event struct { + Data Data + Topic string + wg *sync.WaitGroup +} + +// Done calls Done on sync.WaitGroup if set. +func (e *Event) Done() { + if e.wg != nil { + e.wg.Done() + } +} + +// CallbackFunc Defines a CallbackFunc. +type CallbackFunc func(topic string, data Data) + +// EventChannel is a channel which can accept an Event. +type EventChannel chan Event + +// NewEventChannel Creates a new EventChannel. +func NewEventChannel() EventChannel { + return make(EventChannel) +} + +// dataChannelSlice is a slice of DataChannels. +type eventChannelSlice []EventChannel + +// EventBus stores the information about subscribers interested for a particular topic. +type EventBus struct { + mu sync.RWMutex + subscribers map[string]eventChannelSlice + stats *Stats +} + +// NewEventBus returns a new EventBus instance. +func NewEventBus() *EventBus { + return &EventBus{ //nolint:exhaustivestruct + subscribers: map[string]eventChannelSlice{}, + stats: newStats(), + } +} + +// getSubscribingChannels returns all subscribing channels including wildcard matches. +func (eb *EventBus) getSubscribingChannels(topic string) eventChannelSlice { + subChannels := eventChannelSlice{} + + for topicName := range eb.subscribers { + if topicName == topic || matchWildcard(topicName, topic) { + subChannels = append(subChannels, eb.subscribers[topicName]...) + } + } + + return subChannels +} + +// doPublish is publishing events to channels internally. +func (eb *EventBus) doPublish(channels eventChannelSlice, evt Event) { + eb.mu.RLock() + defer eb.mu.RUnlock() + + go func(channels eventChannelSlice, evt Event) { + for _, ch := range channels { + ch <- evt + } + }(channels, evt) +} + +// Code from https://github.com/minio/minio/blob/master/pkg/wildcard/match.go +func matchWildcard(pattern, name string) bool { + if pattern == "" { + return name == pattern + } + + if pattern == "*" { + return true + } + // Does only wildcard '*' match. + return deepMatchRune([]rune(name), []rune(pattern), true) +} + +// Code from https://github.com/minio/minio/blob/master/pkg/wildcard/match.go +func deepMatchRune(str, pattern []rune, simple bool) bool { //nolint:unparam + for len(pattern) > 0 { + switch pattern[0] { + default: + if len(str) == 0 || str[0] != pattern[0] { + return false + } + case '*': + return deepMatchRune(str, pattern[1:], simple) || + (len(str) > 0 && deepMatchRune(str[1:], pattern, simple)) + } + + str = str[1:] + + pattern = pattern[1:] + } + + return len(str) == 0 && len(pattern) == 0 +} + +// PublishAsync data to a topic asynchronously +// This function returns a bool channel which indicates that all subscribers where called. +func (eb *EventBus) PublishAsync(topic string, data Data) { + eb.doPublish( + eb.getSubscribingChannels(topic), + Event{ + Data: data, + Topic: topic, + wg: nil, + }) + + eb.stats.incPublishedCountByTopic(topic) +} + +// PublishAsyncOnce same as PublishAsync but makes sure that topic is only published once. +func (eb *EventBus) PublishAsyncOnce(topic string, data Data) { + if eb.stats.GetPublishedCountByTopic(topic) > 0 { + return + } + + eb.PublishAsync(topic, data) +} + +// Publish data to a topic and wait for all subscribers to finish +// This function creates a waitGroup internally. All subscribers must call Done() function on Event. +func (eb *EventBus) Publish(topic string, data Data) interface{} { + wg := sync.WaitGroup{} + channels := eb.getSubscribingChannels(topic) + wg.Add(len(channels)) + eb.doPublish( + channels, + Event{ + Data: data, + Topic: topic, + wg: &wg, + }) + wg.Wait() + + eb.stats.incPublishedCountByTopic(topic) + + return data +} + +// PublishOnce same as Publish but makes sure only published once on topic. +func (eb *EventBus) PublishOnce(topic string, data Data) interface{} { + if eb.stats.GetPublishedCountByTopic(topic) > 0 { + return nil + } + + return eb.Publish(topic, data) +} + +// Subscribe to a topic passing a EventChannel. +func (eb *EventBus) Subscribe(topic string) EventChannel { + ch := make(EventChannel) + eb.SubscribeChannel(topic, ch) + + eb.stats.incSubscriberCountByTopic(topic) + + return ch +} + +// SubscribeChannel subscribes to a given Channel. +func (eb *EventBus) SubscribeChannel(topic string, ch EventChannel) { + eb.mu.Lock() + defer eb.mu.Unlock() + + if prev, found := eb.subscribers[topic]; found { + eb.subscribers[topic] = append(prev, ch) + } else { + eb.subscribers[topic] = append([]EventChannel{}, ch) + } + + eb.stats.incSubscriberCountByTopic(topic) +} + +// SubscribeCallback provides a simple wrapper that allows to directly register CallbackFunc instead of channels. +func (eb *EventBus) SubscribeCallback(topic string, callable CallbackFunc) { + ch := NewEventChannel() + eb.SubscribeChannel(topic, ch) + + go func(callable CallbackFunc) { + evt := <-ch + callable(evt.Topic, evt.Data) + evt.Done() + }(callable) + + eb.stats.incSubscriberCountByTopic(topic) +} + +// HasSubscribers Check if a topic has subscribers. +func (eb *EventBus) HasSubscribers(topic string) bool { + return len(eb.getSubscribingChannels(topic)) > 0 +} + +// Stats returns the stats map. +func (eb *EventBus) Stats() *Stats { + return eb.stats +} diff --git a/lcars_v4/experiments.go b/lcars_v4/experiments.go new file mode 100644 index 0000000..18bc7ef --- /dev/null +++ b/lcars_v4/experiments.go @@ -0,0 +1,102 @@ +package main + +import ( + "encoding/json" + "fmt" + "ld/server" + "strings" +) + +func readCrew(server *server.Server) (string, error) { + + content, err := embedded.ReadFile("embed/crew.json") + if err != nil { + return "", err + } + + // Create a slice to hold the parsed names + var crewNames []string + + // Parse the JSON + err = json.Unmarshal(content, &crewNames) + if err != nil { + fmt.Println("Error parsing JSON:", err) + return "", err + } + + const insertStmt = "INSERT INTO crew_member ( rank, name) VALUES (?, ?) ;" + insstmt, err := server.StateDB.DB().Prepare(insertStmt) + if err != nil { + return "", err + } + defer insstmt.Close() + + // Print the results + for _, text := range crewNames { + rank, name := splitRank(text) + if rank == "" { + rank = "ERROR" + } + // fmt.Printf("%d: rank: %s name: %s\n", i+1, rank, name) + _, err = insstmt.Exec(rank, name) + if err != nil { + return "", err + } + } + // fmt.Println(string(content)) + return "", nil + +} + +// splitRank separates the rank (all tokens except the last two) from the crewman's name (last two tokens) +func splitRank(fullName string) (rank, name string) { + tokens := strings.Fields(fullName) + if len(tokens) < 2 { + return fullName, "" // fallback if malformed + } + + nameTokens := tokens[len(tokens)-2:] // last 2 tokens as name + rankTokens := tokens[:len(tokens)-2] // everything else as rank + name = strings.Join(nameTokens, " ") + rank = strings.Join(rankTokens, " ") + + return rank, name +} + +type Message struct { + Timestamp string `json:"timestamp"` + Subsystem string `json:"subsystem"` + Severity string `json:"severity"` + Color string `json:"color"` + Message string `json:"message"` +} + +func readMessages(server *server.Server) error { + content, err := embedded.ReadFile("embed/messages.json") + if err != nil { + return err + } + + var messages []Message + if err := json.Unmarshal(content, &messages); err != nil { + return err + } + + const insertStmt = "INSERT INTO ship_messages ( timestamp, subsystem, severity, color, message) VALUES (?,?,?,?,?) ;" + insstmt, err := server.StateDB.DB().Prepare(insertStmt) + if err != nil { + return err + } + defer insstmt.Close() + // For demonstration, print the parsed messages + for _, m := range messages { + // fmt.Printf("[%s] %s (%s) - %s\n", m.Timestamp, m.Subsystem, m.Severity, m.Message) + _, err = insstmt.Exec(m.Timestamp, m.Subsystem, m.Severity, m.Color, m.Message) + if err != nil { + fmt.Println(err) + return err + } + } + + return nil +} diff --git a/lcars_v4/frontend/assets/Antonio-Bold.woff b/lcars_v4/frontend/assets/Antonio-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..6f24591e31da5885892b7407dbc5f388d2250bd2 GIT binary patch literal 21984 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 W0%9^SfkhY?S()}QFaQ88GXlYTveiWZ literal 0 HcmV?d00001 diff --git a/lcars_v4/frontend/assets/Antonio-Bold.woff2 b/lcars_v4/frontend/assets/Antonio-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e772d58c9dec8677daa00ac7d64af59f497a79c2 GIT binary patch literal 16600 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 b1{pd^N%&Xr+c2MQ`Oy5 zGd-^IVqyRwz)w?E0U-SMO`!Pi{r_s>BBEjdfY{7WpTZCH;7s9Q#1-U~0RV9V004#` z0KjHR2uHsVS5_4Q0F?Cr0H8qt00axYf~Z4YnVty%;FkHnwp|u>Gs-H0DnGpc@lpSP z&OO0u)6iPq?nf`{$F3a!`1Q0O*{Wo!@AxAV8~M?J_&-1}wQ@K48Q%&3V2b+T%2J6Q z7Bn-~Hv$0I{eE;Wg zwuV1?EGR#+pD{rklG}Z4t@Yi0c$r^*>~MZS05k$QX|G^9_D%fqUssmC>dH9Xr>nMw++6;m) z%rA(Rz*7j~y$d?*A7xqCzi{eyhyp(fDk3@v8$BRV(C4;>#kDmH^#)H%OX|)g3(K0S z#!LyhFJ?zMxq!#5t?grPOXQu*bkiL7qjb|uPC^QzSb{R%0KovFprAAYDG{dlP8ky9 z$Rq=)B9v7n14X>UV#PSnjHf^Mp+o4C@6JhjH{s4XJw_BU{GM)bW<--A9_2o7aYr12 zNKg{CY(?ZGLqZk;kXDqKq$!F`Pz+Cywcf&l-B)OkQEbX#5E2FQ0o`SERVk8I9t*zOf4npf6-tZ zUKncw2{^c1IX(#N2mO4ILh*@A0C-8_7=kxS`8;HLr@-mIpwyoW2BhK{V2l!nPhD1G~S+PDt$Ad!QNRzV=R}R3?X^13MJbOit>XL#$tfM>^)2V5<-chHYC;sTk_WV(`#8;RK7!Cpv6j|fo zC=<~UEK>3pYZ4`1gCHS7R#qPImnsh8f$TB0T<@<$Vxt|ciA?{5Bkrd2_Ldg92uW4zxHXY?wJjB^ZDKyUv9#^*xl2`*m~vz3(AodvofdF7v9r$E zk-0LllfgEC8~O~wmtQ*n^P}6IFkE+TJ_Y=jp+`9&#@uN1|0dRoz?k-rsT~9#a$3*l z5Fl)}R(H&hPx0BiDhu`LE%1=$p619IjD2X`?c*|t>GIMr> zmi4@NMA;tS*bof@Y%TQIQL@Tp$D_5NlF&5PmZ89cV7}JONoVerSbJ18++MBy zy`(p%+2Zvv*tzoG%^GSsjY{c7th2KIz1lTkf!U|Y(Gj^aXkp2_7uWyp$DLog-?RHJ zNU$Kq<4Pq~3M6G#m~R|%P0Q~08jbz%93VLP>uwg=lFH)6xUAn|<&CH56d8i(4{0JG zkk7*6@&MZ;iR*l<`VcH?(*asJ$09tvFr(r_?4X1ILZ$}#y<_;&Uyo@&= zn18=@q34PGrcK`XkpXWS_ln&Pd_1Dpvq6_o>z!Cjmk%$sx4i+K0q&BH6a9Q$MQ!_^ z^Bc&&+RBoDZz;v=q6o{e>-pY6ryoGKgq5~1TNU2O``2a}y&9Fa5a@n})^VPf#vFga zn~r79h1Y0*Lt(CgADFIy5pVXDz+v;6VI>hE1FbB#KX2CISv0<{V84@qfNXEW=prJj z#gD*ac|2#@61vv%tNNRk8<;?rI8b+h&EfV-pmWLTLC*lc`v~X){^-uoLxY9t78Ha& z!?7#a_a8%aD4!|fOGr;zD8e)=dl1m_RnQ_ykReqsd3u+r6ThL152tFUvSjm6I(Eds zd;z~iUm1!CF0?#(5Ab$$nI&n0U77|o-jGA`>x-4n$ib?wGOv*X6)|UnzY>J5+cv|m zGhgWGxGTH`As(Ruii!+4oa@RC31NWBa^=HM_+97t!+!+|H-50nSB~-?Jmt&3&}A5B z@Tl3iZ%hF=Oa!x^{ar?1UD~X&^lnaN@(AU5>yEVZh*{dwkMtpfYP*cNX7>N{H@DzM ziAOUSxN8tfF36rINgSUrvtGU;jd$cj(w9I6vG%mb`i_Z~KxKD(`yEPM^VhyWMhMzdg7bI#ZY~&1}yxzVfSS zlj<<+Xn0a3T5JNu8Gzdb%1XLI>w1sTPPRuI&*x$ZwW&~W7rOF zKt$@hc(;t>D^;)knexNTH9!|>XhOQv3m}NJ;fi+fNgcfiUk44izFzlQuQeS+TU7%0S_(es1*CUo$xM`<}s2#WEBwT-` zH@5+Mf?A>|cgYRAaJsx`GsKeLP~dRzq;#A1MO^15qjKO$vIHzOlo%QGIt*)+$%1 z@jHm7OaUd}FXtRT@rVH8iltYu3@KpX^Iw6`+ZN|OlLjik=L6>p;$AqmZwmwOnzATH z{u~S-!{L|uIBnMIZ$u!8Z_>&2VC76)<&|f#O7tudq&I@Kb6CdtRSEvvaut?l(SAoR z4|aGE^W2Iy(gHbJgO&pTbGh#^{E}4i^9ogoIHm!7MlKJ__=vMo&$t>m7=#=6)J{(g z4L0T{SQ61U60P)+Db+Dm%(=Ep3f-R@dzXPOJ&bG~ zayudwH75JJMDx*U`7SORr#pe3qswJ^?K^m{cXNreB|BkgCySi{9{P-|t7kdf@LzbY z_Wlg}@wVLGcqSvZ`!WdCG*JyCO$GEdaq*_0I-j5NTjD78&=b8{At0B^7trT;}$WH>j@)m*&a6iWA6yPWx%I- zBDMd>PcR0WI=I2#X8dn)FyIqa6Xb@`6#b{tI*Q4xrgU4-YiL(-h0Ua{$v(7;_kSHc zeLD=x4})0AgJK;udg06u*LE+0dojH&|M?)rkb`3Y7WS~n$f^J(TH!a4L{WE}MoPc* zw0GbaZit7HEMjZ&$1dd5XN=WFvW`m~b*uZrIh4ko)6=Z5suGLB!TUWasREs`H2N>(gVm;i;h_m1~g zIrf9=0j^Y`V*E9%GL|$8^aft64vT>;gBx_{xl?v;6^9o-AxqDr6BmRD+RS#``D&IZ zs1XH9sw7db!5fabY;!=c=}Y4$u5j>Y82SdtHlQ+n%;ZLD7p9TCjpO3>9U5I)3-7n0!c-_@O5VQBmGP5K(EHE{#XY0e@##}Y5E&JRO@_b z&G@1B=?-xGeFw}UWD#62L`D5UiGm`kQ@i3TBUWs8>@D6*>pC_&p<|pM5Sf}&;%YrT zV>o0RFqOibq4@fbeK2dMtt(>_#+MIrbP=$_9xQUYkh_0T;Ivo`_-ozBrc>)UbVKi# z40zH8eUDCl8SsP;;=+8yf*i9uIbqc7^xU@Qp7hOX#6K~z#(c-sic>><255oad$1l$ z#j6|Nd!1NENnq5KiHf1X#K;KR?@J*ldUKd&k;4#@b=jgRc5~P|x2!(S>QMG@+k5p1 zHI|RR#Okhg)%vJ47@mGW;pZmbcV->qYoTIl+$$Y2sG6c)xlqi7JTxnU7X?}A)Z>i8 z-V=X7-K`Ft#d&iSOh@5h>vxD~#SgkDBUmv`T6e?{fH9X>QGm;!VsPj~&hmW_9ak-dWKw|35D z^s-d`jmpqMuC~y3WLIW0A&-yn+nwLscxK6?=xQ95rtSAZ+z{*dXfHITYA>VnsY0Pf zJ`B&V*nFRLCdXjH2&JH-U&2f{k4%E}{k&O3r)Vu39(n>QC@lpGtLCq_=G9_3RLcbE z4qkR%(L0RVI7pg~j)6yaA@pj`0omXqoRk%XS!!x#a1G7O&gG#=2vV+8*n|-|$cTKz z5;t3OArj1kPbpb{6;9g?H#@w&2ar3xJ9wkFSYfLeW7a=BIA08xpPls=KO>=*ijzTu z)W|H)j?_Ry)QWA!b$o2JVVXGXv?`@HD@$UGX({_M|7Zc)s3DpXs0K0?CWm}uVKmt7 ztJ<JL(-LQw2l<3)|=#nb*(egul%Zr7mbLff{!=13AF)&s-*g4FGEe^G)r8qn)Z%V$w zb1FLe(Q)8C*1zZ6!p*XJOl{XY@)+xdJ_3r4^2x^ew!0tpx>N7`He&FTmD7m+Qr0}& zA~oG0AxV#=rq^tBH>=2~cifnLp7M$dqz_Pgxn7o_s$TsziFJ1m7@n!e)u*CWf%v2f zR6cE?8rd244}GGi84q2+C}U^p3!cZxE>8@Xfq4v`yJoYqmh=uK-jE{NH_z0eCys`eUliN7c1-xtdyLsy2Gdx z9R3Z9C4X}31b0pNgt;?G1IJpS6w79BhAyT|U=e(YA9z(i+uXQIaSgsSaL;i{Aa`zW zg&teyQs>{BuZdDTxMYo(s0qrK!@L&aBhICs&sr$+(%s{H8+1<8163j>4K#0`Jwyzv(pv;d z7tI$ugaxlN$$x@>{LjHdCBRtcqyR}>)meW;YqTfH9CkEDCy@u)dl9+wT1n?hR?UVa zJ+qBfuI?=Hapz@-emRbS!fAD8G_EnSUou|Y8?~jbj~bx_A{9p0O_i>;;*KbP z_`i6uQZg)F&hbH!W-+rB(*F#CPt$JwlC{UE-?u<;(-b0?nz`Ntl(-gE&+c)FaK)U`4*SAz4`+Z{ZorUg(t)pAog1idxyt zymD~Sv{Lxni#H|6rbnN^C1%00C*_vHQb8{^Jk>BcxwN%MmbtKMOakA_&TZ}szZHRx z-m*yklyBxSK>}Z-p~mP9NU&}zT!!*2?BD(_iPMoC0U zaX8-WY3?K}JWlMd3)zUA)CVU}ZYWd;aYjarLAz4Hw#Rf)RuD!$IYfuADmjtIcx zSik97TNtb9OW2ZW0`*lE&QKE#^!rFJW zzgYL(QT~_xcFQQlFdeJlD|a>awLe+UU3aDgRaLE-2C#Q+O*pptAFsXz`HbLZ4(7f^ zrG{yO5@~W4KDUifr|rGX@cK7}x76)6we+je*ojIoFz2yF&}IrpAD#6;Vql44&VykY z6BP&IRStF(n23Fy%aY(yrtfZXo~t>GF8`&EUtX${cz9w*?rM2OM|%tQ@7Kww;IF$u z1{0ZL83cBA1guhgMINc)45Vsrp`afW!+fp(O4sA7rUO0QgL@-9oci_;=SXyJ4~9HI zyeGP4uDr&mrGnP_H?h@fk-V){4{MJn24#CpfKB?TaAW7JHIhNkZr)|x)y}t;z4hy@ zH|Enw%|W(de=Ip;vx;?4JG=Rd)Vreg*}aj1AH9ipa7T%?WX~Z2l*-*^80noo~OMxz4% zM@Gimpn1dy7cKUhNkaeO4;1RJs;vjmzYxhPmtQOjrrMbFuYQfQsW)(AL2jH)obYL7 zGm!b~ERSX=aF^pkhSPIjB42=E7iJDqQ9RgOu%17jjD1VEr_i8Uq_{Y|b|A`8OlZPoER1Kj$xcG5p4rVc!XV%h6CvPNa1EY=XFwa$GG6kC^Mwa)39oIk^s zyxqPg!c9;Ys9i~%P2@B7i1EC}!7oKLlWnq9p+3uH#*4z<`a--B)n*0FS7S;L&m*Dk z?yTyu(FQd^r{vlIQhls%-xJUoUJ zFt_3G{S1=Ld|RW{6;J5aVRTo~fNia$@K z;hy%}b}tA(sYGwcA8KV9uR-UcyMQTe1s3Tspwlpxo>mn=i-Ys%Iyfu{D0t}J-kj$R z5^Hf$J90`%PcdKT-J^wF+6xu5@#lLg?$9m2Rew*x()BYH?Ovtm*sQ`qJ^J2D!!|0Eo?zvFyaMM@um5e z>^ZK8=z>!noe7JtSf~QVO6@GksJVH>a=lRSC$uL- zYsD2NWCw_IjdmpAGtYTd8IL7n8MZXvk&8M}noTbHcT*M57gvT*98coih6)SU{xUWf zgrdHo(jKXuKvbYl*@3U^N1Whaz;#SjPZ*9FCeaVHuRs~G#W32-g6xa0Br^?hOp!89 zsSQBF4%tVA5kF3^K0$@>-Kk)7*R&rR>XBP8wsm|Fd>R4^9Cn=JREc@wn$RAd-ig7nb_4r0wBgk{A!(+0Gp7Eb**|>p zNf4UBX%xCv0U5v^x!Ox=<>{;B>-6v${&hMx3x~SpXoMrw8_>|CFR1s%sxibjQcJGFcfTd@W(+l4|!3{4P4k6&O95riO zJZ{@mE}=36KkL%W<8^s=oYxv9_aiICe;o@O7Sb#usB@#y>&|pV8u*?PwL#v(7MznD z*DMgaKwBty|0Q61TVv0FM%V6gl%w6;Uj8{Ihkc>SNOo_ZLv8x|_tP}x=u%w>_dJx&{e5Ec#@1B&P zo7|r3d0D`1FjUka4;_eu$%w{iUn}|B`R4w_P(r~+LCpK8-{vxyc!-?<7@V*E5u+Wz zCNOxZ4g3x9`i67i-^Xs)RmRdB;Tnh%?Y4m_Ed-haM7-~KXdE8t-Icbnz5CkBi-JVA&-# z_9$j%Q663%?lTY$ZfV}dV>xi8Pwelo*Wi=-22Sc#OtAGrEWLMC?y<;4v#z zjzNXUC+y8r8smvj1>VMp z;gO4+#dJ-OkI;*ba*J@=Bk2hXJIt6`jq1bVbfdY!FDr6f3Epw=h>W23y@OL$joS-1 z5zub=WfP;VR<98T;-Pzc1mNv)5T4+3jMs-2b}c7PK3k^-9!q~yq1gg5fNxA~R8{GC zxw=F2Y`l~sSFj&nz&bjk{=xP)Z?l^A-l^YCKKFO%#`9S(h$(K_T}$OB&x#6ZQ3NGG zG@22^grE>AE3mK(3t1O<{HcW=6uuhOu@W#Mf+|XMjS<6bFZn?j5Z)LTFJ<8kb(`!I&o``p|f4@}b)-mIZ z`E@O&-qe-cG?;YtlJ(WzY$@t)@@toS4Erer_rXf5-66T&zcrE-)kU{7L z_G!L~Ar-C8gL)W!c|~>jSX_N<>Am9;XRpEzPU%-JS@ubGfz$K@>K3wBg)EcnbnBhi zLDqtkgO`o|(MR|~LF%cNW$0@+{1`mXRr=@&3aKAcz4+E*URU9G$8UXmkbj`So8&ny z0ykd?A!U+(kKT-(eb8mRI=nZ{w9xI@AeQd(7v6Q?EZwumU~~MtFGBZreiIfN3Veo_$Seu!2xV{rY5W{ zG$k(p1xiBMp`TUTqs@yvV>qf_9_*uR`U~q5IL7bLn%OFZ6fFD<&x+Fs@f z8i(<-B!A6qFA!h2jrr3TTS^z5vNvs&w=7>;V&j{~{N_2xHhXtzf;BHY{n=LO zaHl0y|1>`Llf%Il7M1E^hmUM}w3qQ>8?BBV?;T-j>4xG}y5Cof^V9M?z3U{ORP9i>i)N@_-hDM6 zQp!9UB+-M#x>98#%#<8=Ld-fTn}{bSEG^(J%nP)|CnW;cWZikM>W{ej1H1$$wrv8J;PSi6tqJy{5{bo?O$g)F-S+P9DrTF){iqZU&)lYg7}3T}ac!_RJ?g!`bWdodC@-HNULY>M9jrFvVGDauQ_`C3@D&6{5E z{R_?;`R46tBA@?)v>&X#ytThn9VURpf$)F_Ph+(r;JpP4j#rAu?VRP3xaE5QhUgCi z8R6>sm(I%(I>6%Nwivn#tQp%3bCb_KrBGO@g(B2zaN=`<1e(IC zJkY5^bn9QzDwF2ATqLCzf#6jniF+a~&GG%=ZneBMi&NQ$9up9#j<9HWSA!8Pw@YP=x43$N)% z4O98Zt}ApmaJ&&2P6cpmuuTJ1H~~=-?)i7i-t?hq3zKQKb6)ob{aW9~qU#+AI<$0a z3t_3lAyQ4ALe1fUDRJw>)rA@b6_ew*#eFJBq!f zOs46_zxVwVPCb!3r0?&>7La)?sO58j;RSn=lFl3(&(&zmJ?;x{QqF>IGML9>KWB`% zC9pwE-;`M*FCTc*z2jur5U{*VjjxOU0qJQAkP`mW{~D=hS*K9lq%NJ0u%N`JOMxD!RlzMO ztYI+3I}T#lLjkH0eZWDulaC+J0UPEVSl4%Wzt<#O9`32g*Bhi^_yFIw;@#dLtAYaQq|@Fc*uS z|4rh@9`SH4tm$_%^A=xY#xImx)GyC7GP%6APS~Ym`AdO~kd>!7ZUrNrqf9lx)&UF2 z_}@SXj(X!^8e@vZvaWHuIJUcNv^cY|C%GH#q(__47E=vm+?exuX@KF$Tbk}5jbueZqJSw_ZLr8?i8D!*)Jy|)igHrsWYH29L`Ylst8d6|Ol z-_49GDoFqAaX$wiPLDdxHrzO>v6*eS*t6E6VINejZel~`8TGJjIh6be;hQ}sOXb01 z&e=jFWCGc%L1HAsk2-<4&rX$Ts2|GPvVqEks;o&i(=#_uiJWRQDb0bh@qJp9I4bT( zd7a?dmDVA;3^mIX*ocuueO?GpwA=+4%I|CXYem_#!JCktVK4r8uA%Ly!R%(dH=BF4 zxrOP-T@w5FS;sXSX^f`f9|&$}ID&mrfrf{8Z-T%vRg%L=o9x! zdOp`=HiW`nWW9R`8^HT;ho9!Ua*c7Z-2aHpY2d4Yj1z%bmzK(IAVPtxL(>xBDa1Pj z(x|dLwK^Kv2`)ER@9R$s*MpY(j}{{#cX|~_rGjwdeVmsIa?*{A;&AYGZspb=N@6JS zBzyXJaF%Tc`^|c%@Kxs-n*ucDxF-nPvyFfL6WIJg7>gGNHo24c0{&;(tUDmwKFmB3 zuaHvw=Ua|}K29-R{a?VZQNYDTxL4D5J;#YIzW9jd+cqoz0?gAVU~1nn+sx$XZ>&ZF zxvmkYl$4lWfS>7AXGl}2c1&w5`evZ#G<(NEsfMly=;!e5Sd&tv)y%PWOd}g(N3;XT z+cG_Dz;s{B~s z?@MW1K_dTB{W(8j^zrw-#M{znOW>UC8lewmEP!vz&K$3=Cl+NOZ4Bfd{cR)!m8PtK zW8w*_sH8m%Q;uZ9ds>iNAKGwRfb3f|q|bjLyO41HSD{EF%4b6|v-rG4njbW1iOhqUWgz*l zv8Akt8W?z~E3I7JVmSJn^IFMUxo7F-O>dhJXCeR0#N4@pX-bi)eQ?|7*j%jLJ^eoA zj4U3__ucdZIR>`3lhcFG@p|1W`J!{;jKU^)ZkEI@y9M&e{f6O6fL%|wiMEJ7X(R7x z@oFQ&n3NXiM(an5NA}9c?|&#$I@% zz}Eqp*0@s|t@%zR$ZTiKw_U^tiTg_T`4rOXutTK;VHRHs?BKw(1KT)v+x~6CemV25O9@_EdaVNp%tY^j;%d3jnzTn+I zbH5E@!uYO`Y=%9xv~Pbh zXI;#9+jL#eeNc=8{9mc(E5^`=W$R!{O5Ohac57st*8D|$?;iKu_`(+nx*I}eJcCDJ zw<};arekGaiyFR)p#3qSQZy}-tm50T;OpSjvZ_H04|;QpBrB^Hqu2GFUhcoIB6Wq7 z*b@}qhbi@j6P8QDUVI#{;-(jLe{&l@U*_$SF~W5aSn~q=;?Ac$(f&IsSG{;<*=S@X zG;3rD`!m#rC7OH9!y@ZwzACR9$YqcJGu)KvAqfW_4>l1+R(^)($hxfDJ>pXfh(6FE z#DmMfLi&uErQ|^Gx1pP_>8pnC&bbSUJ~w)|3e>t$K})b#Xzc?p}F$ z-Y)gXnyJvCGK80cOca$G(}zlp%&(()d7y6)fjO4P0|KWacks~Qkjufgr#HSgA1&RF zw|j!L@wmKp__;zv*WNX76{dz^!`UidjKV_GC(;xA$8Ilh(VG<79n&{@hOvEqZ*2YAQ3f$W9=PfW{PK>v#VBVXMatTw%GQ~SKh8Paa$+qWxZYHz9LCOc4LW|) zFq%+4n))gjWnQm8P-&Ef*I?gtv@o1~C7SS@;jdiu^R%$Wsx7pQ4^`-rAh(CF^@lAc zm)iYyIt&wE1?)ojkT2gw*bV&^GG&*7tk#ag!m;Xf1pnY$co@c)73SCn#$p;E*e7xq zaQx<*A`{?jjo^x+c5^5aR|w7f%9`MGXF8t1{D2#SmdmE%@W$#Uwq=QJkDXd2X&~8HLY$pg?#T(hr%pu6&Q*m%+4mr zD-2{9Q5v+Os|;z+9Ssa-$Sdt|wdSJjh79Yv_g>dYfS;3J8*$Hm=N?JSD2n;a&Y+VZ z#El|acVkb-K+SVw!_6uvO(fJ?pk=^H^AW50#EAa&9dg$`D%uH%vt+G_Cwy?SgNg!f z#1C9-KH)zBUxDsv?(YDX`3x$KAd8Eo47Jc9r}cX^?Lmp^5?%JK9JLmVl|ejV42Esf zaf_NIxe&3L(IOK*6|vKB#C|jkeM|g`&w=1h5TUh??-Q45`ObDtdpH93+} zoOVP1#vtEr%BE`E_w6Y^4Ih^xTbC(W=u%F0AC+QfpWGZME+$4G**#QYc%-!@_CWfw z-PpOoy!qk_xKAh$jZv#sxfx-kxu9W~w6e>|5b=)cIweARM`sE|OF-{&kMq>I$E{XV zh*znlJ5R_D{QeUQ_@3n!kL`nhf;&!-XZ0!?mhN%a0hj+(Y&^acn$D5S`{&VwTHvIY zjBJ*HF`4prB9tNeUs8|MR0~rPcWG(&8#(@MZT$+Ds|6axR9R=5XGJj3`1u8WeT!`> z^inE2K1v#br{K57cO>CL<@RM;o(^_O8mG61ncAWvh9l5dI{#NW@9I$hVn@SSY&KJ3#XU%!k`IPuY8cb%Y*XgQ_r$WVhE3b zE0biQMsvg5R@HDyqlAGZ8Kt-P>mu6ErT);KXBzi-ugd{U*%q=VQWEWlOSMG3SjCG? zM2v3$0?Wse2JDJ`;#XXUwB}v+>fHgx+%VT=tV*XI?QRbb;q^`)Tmi=Hzae#sXFU6- zP`H3WnTJpuP&Yyjmmvmvz2DacZoA#kr`_30aVJfzUtsWjF@=~(b2wI3+A^%c^ z*1(dzTc=Wl+xe2Rb8|Zh=xzP6zDn<&&`?lhBdMt(GSyI!&o7XW_xEt5YjK>Q_aPn0 zOzRsFh3ZL7ZT?ZznFa##w2!8}|Bt_tL+>_b~(Xu@D2(@qNHKrDzAsnh{&V$V)Y8jANw?=$2 zp)@9ZP9^GW`&9-%K?mRv52MmVRW3DP(%Zo_#-?$8O`;vQh4u6)OoWzTegMqV>{{zI z!aLSI5fsn%HbnPPOKNBozyk_SIk|XHhj1dwbSOnQRUuUc?D8rV z4_!$6`3N$RUn zK#c#~fx=M${wu&*1`@5u?uOXlFE;}%7Z}?M$^dC12t*TJL=j0iizqz+Wnb8$dVwY% z-oIzMhkC1NFQQ9AHl18!MC>1@0 zcoKVZO%kZFD5^@)+8LX3Xom8=Mdn(0S8-PbU70T`E1EO9tffM`H1+)7hN!2%Pa#h+ zPyQ}y?M3eoiyp0AvfKH`4;@=2u4kQZ=AV^c#e5a$52PXlke~{{Rf5m?uw`J2h1nFL zcPGY9Fpv3yED=MqC~f{nv$!&Q2-SUyEpY66n=K%|Vbi z;4M9CJzG8HJ*_>@y=JvMD>yjNQ$a~HPczc_>9xq!5ZAE2C|y`xsFcwxqI93v=OdRR zxgjP4(M*MNW^8a6mtwiM!F2`^CL=QGu9?Xujeks!CVlQpP@B~LoL7lg9aj=BNm{P7 znW0+gX}W}e)_w+UT708<^R!WW(7MQ1QoHaqVUX{0=-_PQ@S}C7hmksj*9~YHaE_7| zj=m?xlGcw3k1i+nkB%P5PjMYnlAq%^RC7d9(ixX76>BJ8mj<5tKcqi6y@fs$NVopY zbQ#~2wds8CSijV9G2O`JU9In6)roE%w!B^ISnfd9sbN2fcFT3!-x}~8ioVzSKYplZ zWR~LYkWHJjeMAky3=RUZL3ywVl3xt`rT%SwN8HA7KH z8S3VIo>HmpZ9r`(en~K+EoOx*gSV-mVEp<6Gxkpry)ar(7@S_Z^l^J!b4pH04t$ME_ooG>$Ifh-=DR-~^5L1rV=gGjYcJEqOogWjfaPF z;VK(CC5cVEj4r`X#VJ__qv=Lp3^%?3-L@>2E1h7Ka_6m8>t-crkd`+J<*|nL7?{I9 z)v{NHrO5udrV%T=;sh$M*+pXrs7iT@vtg2K78WI^GzJn8Lv-H+YpjV5dVaNU3U1 z6{w3-wr;wzdGekov(UH63rxC^)0?X+0$@dW)Q4npg_1gh%TwB(@Fge85!ZCArc$nR`1ds!wiDj=aQBCRM{WJsaYg#& z_*&KtG2A~TQY|`=-;pG6=d@17E>1HJPzN9Cq!==9n72?{=mV2}kK{JyT`1t>wmOaK<<5H#J^ zjFZ5fV%0H*e5ap95#l9C1d(+4a$yQVs;F=aSPd4Uf|evI5sD=ir~*W)5=s%_SuRYE&0^x zP7!zd)bG+B&U3Mr+3I}{n}YQ|>th!u$IYr}p6NTGPCNR!$S0hd*3>;?H)7-`RW&TD zRI~=eY!9;_G3<#=E^B*CGM7ADBZmHq0qL|9Nbo2hstBp)m7_6N|+W|HS?TtHo0amp5*6efYB7i}#-& zzQWG?AJL4|;u-=}Axoa({SM;va_P!c^WYm*9K6dX_CtSs}k#a}MqBaD94QU9i&pk_l4RKUi zq%N65Cl6@dY{XIQnmgQt`?f>IP=_d93CS(Eq(cr_XW!!qle}wqv18Ktg7wNR@u*`Q z)~hGlYeaBACAKBKe`8>HqmO)Jtkh`-qS-NNouUw2cNP?X^EE-oOPZ=wVxRo&o*3jM zxSeA>J4>IS6tnL-N)e{8j3lueqsmNdk6aoSqm;uTNq|myA<5igN`=*si&^HpB{m(Y zK8-e#=V-*F8aT}~E4fAhN+tXCZ|~>dQDD$Ig~s1SdT14F(kOi(P^>;>{RBS7>3t1i zmW?`@jiT6%8Wjza=MDZs!S{J*N<|QON+g332CZkewP%j8SoY00L*vH(5|WHPhVAAX z#nS1Rw3!#=2Qx|sH6G}HXTV1RT7bTTYkx)m#Dr|+ak)ML6kfwyK@lWZ3z+m`GN`hF zU@H=`pQj8#8)QkzJxO5phTX^C65YpNy1U<&A!iHjr;I({yu{Ju>U?8f6Oj251ez=X z>~;uMCzMf&K#$msZI$l_ABa4%v%X_|QKlWJ9;a9eR#Q-L23Dgl-HDN<)pJf!#vZ5) z?IvvgXl#cCN^N}el$8mrwA9+0a?{}#3Pgs{7aYjuWrjl>OPqzU=x*pppD!Od+&tbq zg!;+LGq;owhBUOX-hpi}aGzszm+l_KeDJ~%1;aCBMl?kjp1KPXJE@}jAx&SGx& z+Q4Qff1Tsz;&xp3bEfeqTa4t5^?>>5!N16^;<|Pn#O|LXm<;4iCU#EK>U>}sqE!-M zu~5`Cec~7U{{@>AWa~X++vVQkxzCf$s+t-4!h9%wgmY2DB`VyjtY!)rQCy(l02e4uP{8f~?yY~Qk6Xk24sC$vG0&6y z@{RM}^PTTK7isw45BDa2&c{Kf;SJPd2YWFc0qn$DjK&!JjepU=3~CsQubIiyFb*cO zn2k4ah&H^%-t2=5a3OwUU-skaxQP8Z02lKNyv>0)j3f91M|ma(aWF375RB(pn82YN z#^D@+Phf}6kvyB{pb-wd!*lU2f_R_jaTIRF<9GrFzDEvnc|J#T44fQ`&+sS5@dCJb zA@cA6FT#gt!biNAmvB5M(2jgeq)rD7=3o*o#kb7G^K{}ey6^?_n9qrv#7lV@Cvys? z(oGM&ETE5toW>#+vxL)G%F9{Ca?apPRg2)j^;A2175>|__O#%x}L z&+!)*aWPh+n%CkAEar8%4%g#aUe6o2giE=M%XuSLa3yczDz4_uyoGDHmbdaYuH)^z zgLm>SuIC1Bhz?XcG+xZY5<|BL*_uyVW z#vM2V192t>VK9c^EDXgk4ChWh&L_AFFW_hVf?v^#yU`#0Fajg_B+_v|&cjx`f*a8X z8U|nrPUlnDjVIxO4ZSfJ^Dr4x@hV=!Q+OKBU=JR~BiM)i$Urt8#3*E81(stKZo+CT zK^?xr4LHE3u@o;N6U%TX`r=3YguOTiYj7^k#vQmF>#!YuY=axOVG}lD10KM7K7-Tn zI``mN?&Y(5j?eQ2zQ}#t&zJZz5AYSf%GdZh-{6}($U}UKZ}TvZ@F?HmyL^xDYwr4( z*=}aKTm6ApG?M9#2BQ(P#pVr!Vu3_!W7u4n?QMw0{egfPiE9M`e{xq6v8X?;`K(yY zXH91Ny0>NeM9n8^(|Xi06OoWzcQ~@Ab#G5Es`tliMLm1cic7R&l~=JS6)PpJI35Z& zn6{FW1r4WG>JKF1rdDcYBeS0L(&S^bGPP8evXqmnm0OSKQ{I$_1pTo@YuKNNXO^o6 zY85J^A|)i(sa0CDw#t(p@6hwKS*kQuO0?<((JDDbl{!U6RV)+Q<889AU1|CCn4Lg&xI1UFZ<1c!%9C zbO?{nJB4{dx6mu}Nkt@Hmv~*`b&1!lINhi8la#UUQ_Qg|<~kLfGIqK(zp{p3is~1W z1yU><=&@{rx))P<)l^{E?e^{o^|zZ3C2t_681+LLIEwTEEi5Sus1z?%)k+~6iGF(Q;RCEMNjZrR16$b zA+b~gyRyTEvTZatl{*G^KQp9>kkgoY7PR|0R49L}29C z;@sO$MAeM6YBQ6PnU&3=ov1?(k+y}wH?^#)+n?}taOa|X0o6VWg?QS9SPg7cRTjQ? zIzNw@H}AbEwIKv*>0&`7gqVT?jcHs&L4rUC3#f>S3N5XOg&>RQLSqWc0ya%imNYC9 zL|_q#Qc4ICY={Lzz}2Qfs+R2{VuQpV?3Uu}cfWV0GR1|tIp@3Y+;h)8-@WI)nO13~ zR8;j*LsekxxQWx$&;?JHm*FX+uq74Sn zG9VV@ZnX`*7|EzrVdVk0;>quAGv3K0e9g=NESujRk++=gas2KNSc zLiS(R4t2Mqp@qS=kQ2%Z^$kr66^9n0t?X`tRt%jFf2M9znJVp*Y=<7Ka=z*{!_BO=iKCGNJH}AO|z|3xBQqmH`tp0Kd;oD zB^z#BD_NNyt)~xd_unF)%HLl(*^E7CNUlKdWcu!=pJBKCq>7bzQFZFH z&eHvKf1RUm*SUIt{(~N<@6h>rkS^5Y^#uK}o~ozm>3W8KTF=$b=x6nFdY&%TD^*aB zM^Y0YPebM+Ll3db5WP$lLrNeEAf*t~o`<}kma0XN7a`@4#gO%|*Qhc*4Hc)UUG+F_ z!)!<~qy(}6QVJ=9JP&yxxm_)Sya*|WEQYLyy#``pK&wG!&-Bz}IrN0&Uh3`Co0X-< zC+DCyM?Vaw>B+r%M)IV78qaefD{SuU=PGYNDz}n}n0uq8?FO)ebdF?LvD}{S#I5l=>H1scKQ*BAf5j zCG}_Z3)(9>q%HNTj%i0#=uDldDp6lqYPHVR*=h|cZGieKYHW~t-Bg#VK~>FDZ=jw^ zRV|ndB9ja<(PWY!6AMg6Lf@nA#oK=rSlMKy$;xF-$JG;RK4KK3(n4w>S{CYUG3wv2 zwaC^Y+YGYRV7m_f>(S!i{5mXEXbCcR!Mq0cjo=?7a}T`hRBtl($T>{T9yo__8{*&` zCfnZR86nRYc{=9yKtBVvQL>F<VsoKy9oq$ho-5Y(wHmv*TKCl?hmT(@bhr@1|$H_e2gLy!2)?2X1R=o## z2f#zAmmtg4%W4@Iy@TE^l~mg_KI*?ZsP9spdbxgC=jm6_2I{|{-C=$SB-TNyA)6qG znb;25Epi;P4{`u<7}6lNQ%Wb6K$fdOuP&7l4e0z{hkNmT-0Olp)t&)7D|lS+lwebj z@pFQyd6xu#66}of^&QQ$&!%Bm&`#N-eTX^!v)v^2A@&74UFybxJ)URT#r8t@O%fa~ zI8v}s@P5IEdiYNhlsJi8`zNz*Y?;UJ_vjqKXMKz9=lsGS1@02X!^LlPM+@-ye~GE zI6wz$KyHp zsu&o1L-3G&!A9lB_6pVtZWG*@K5ie7=lz1I`9}pm7CagIjQO02{XlFN{95pQ4||6> zj~n@<^0%Ws?Ai7(=mNW+V4mP$AEoj}r!cjD_Bj7u+7kt5`*m;66l?yr5$zo+p`|6bXhe!a!R{&~kUeLnF%{&~b7a@V{@n0hXE%F>>fIk?BpYtCA4BBbI+_tN!T)~_2Bj0$>gHnG5)MC>P+Cs^PPCJyU< z=ACql+;IlIur~{Ojyusu?^$oDhi?#fuHaO`8G^HWjCTqa`zR;5&|Tu!iM!Ij2X3X{ zCcoa?ErR>}^K}mh%09WL1TP5BOMR93R+Riv$CyzR-QH38fFz(qpc!q9DaS4@h`k# z;pdeOWQ6-0tr}oCWIal~fjWo!E2EJebogsp{!Kj@vmP~;z@vLn?b=3K zOtcSZ|A6*tu2M})HAkztRyDFW+Qg~miq-UQqJI-To9NR{dpj-dT)jPGA@;SyctUTW z&Y{ky{>o?*Q+1fRu$cUdnSU|k>}Qi$?tQ;T3SwV z&ueKJLrV)+Z{g}KT)l;>w{Z0qMrh%gwlL>|w3z>?=|C+rsWo$EFyaQ}LG*`uq-&;6(NBXibAkv~zdrS41ph0)o&sJvD$~dk5P8y~-5o0;cef!ADWX-U~7-t`| zs;9l4_IlbK*~v_vg?VRo(X+q5C-iTme9j_fI;5U$Dn!?qz8=RMPMFgV_&2MGmC(d~75i1}XYuYVW`77*Z{;qv@^-ZH99tRf z41HE{bQLWR@}wR#y9eEu`U|7!xs;wu*S~To;ph}vrtk!(FvBVS zD6{&Jtbe4Xj{bE%m(Y1~F}ugNsOCFUv3}Gszt6quU{!474SJIiBJA&Ge*$$8EuHL_ zP!~|YOWmKNtWUj>_wG&R8R6~Q&HN|uq>9M2h+O*fwsvwqOSqo}toe88*`KxXwl(5^ zbZtkO0C?JEQcX)+K@>e_UJ~O+_g&@()YcZXX3^48<3bccqziG;M~b!bj3OZv7g9=b zAtK_!ZbX8J1`!D^j7t%Bc9UY4{S(E#p1BzW36DAVopaB;d*{vr0d(OhM&O2qM<+3z z#N`q`Asfd@8MDRW{31#-OK}n9-_}hTKu$ry5}L&8Fex z^qto1v^8;m0^iLU$ZyskSy4PzEGtvfNurjn_tvbsP1${O^@(e%?&RNLRo*=w3XiB+@|Y*eILxAAu4{8nX|IoYG!^HxeD;UdPpSTefTcY_K&P+=UTY+*3G-%cY#M<2l~GB7bPgGfeZ#tA@b4+8@LIavc#05gxY$p8QV literal 0 HcmV?d00001 diff --git a/lcars_v4/frontend/assets/Antonio-Regular.woff2 b/lcars_v4/frontend/assets/Antonio-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2c89826192e934f952f79702bf058d19ceaf3eee GIT binary patch literal 16440 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�dOz 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 S+^39++}fw*f3)!yjsO7Z>G^X2 literal 0 HcmV?d00001 diff --git a/lcars_v4/frontend/assets/alert.png b/lcars_v4/frontend/assets/alert.png new file mode 100644 index 0000000000000000000000000000000000000000..21f270578adff97ef88f072208dc4a64af6bf7c1 GIT binary patch literal 129738 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%0A#E5C0LQL;-~4l9tcaD(G`$7I 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 literal 0 HcmV?d00001 diff --git a/lcars_v4/frontend/assets/beep1.mp3 b/lcars_v4/frontend/assets/beep1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..9b8c564e8caed3f06c0e3764654a3e68f3f0159c GIT binary patch literal 4641 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 V|3%;X-x#z1i`@NxssED^_-`?2?sxzI literal 0 HcmV?d00001 diff --git a/lcars_v4/frontend/assets/beep4.mp3 b/lcars_v4/frontend/assets/beep4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..8b39d772fec1255538851ee173d1bb116e1867fd GIT binary patch literal 28449 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 color + 2. lcars-list default bullet color + 3. blockquote border color + 4. images with the *border* class border color +*/ + --font-color: var(--african-violet); + --sub-fonts: .875rem; + --dc-font-size: .875rem; + --dc-row-height: calc(var(--dc-font-size) + .125rem); + --banner-color: var(--orange); + --meta-data-color: var(--african-violet); + --data-cascade-color: var(--orange); + --light-color: white; + --h1-color: var(--african-violet); + --h2-color: var(--african-violet); + --h3-color: var(--african-violet); + --h4-color: var(--african-violet); + --link-color: #c16fff; + --code-color: var(--orange); + --nav-width: 240px; + --nav-1-color: var(--bluey); + --nav-2-color: var(--butterscotch); + --nav-3-color: var(--orange); + --nav-4-color: var(--red); + --button-color: var(--african-violet); + --button-color-sidebar: var(--red); + --lcars-bar-color: var(--african-violet); + --lcars-bar-start-color: var(--moonlit-violet); + --lcars-bar-end-color: var(--moonlit-violet); + --lcars-bar-text-color: var(--golden-orange); + +/* Image Frame */ + + --image-border-color: var(--almond-creme); + --primary-color: var(--orange); + --secondary-color: var(--moonlit-violet); + --accent-color: var(--almond-creme); + --title-color: var(--almond-creme); + --spacers: .65rem; + --frame-height: 40px; +} + +@media (max-width: 1500px) { + :root { + --lfw: 200px; + --radius-top: 0 0 0 130px; + --radius-bottom: 130px 0 0 0; + --divider-height: .4rem; + --nav-width: 210px; + --dc-font-size: .75rem; + --bar-height: 24px; + } +} + +@media (max-width: 1300px) { + :root { + font-size: 1.2rem; + --sub-fonts: .9rem; + --lfw: 180px; + --nav-width: 180px; + --radius-top: 0 0 0 100px; + --radius-bottom: 100px 0 0 0; + --radius-content-top: 0 0 0 40px; + --radius-content-bottom: 40px 0 0 0; + --bar-height: 20px; + } +} + +@media (max-width: 950px) { + :root { + --lfw: 150px; + } +} + +@media (max-width: 750px) { + :root { + --panel-border: .25rem solid black; + --bar-border: .25rem solid black; + --lfw: 120px; + --radius-top: 0 0 0 80px; + --radius-bottom: 80px 0 0 0; + --radius-content-top: 0 0 0 34px; + --radius-content-bottom: 34px 0 0 0; + --nav-width: 174px; + --bar-height: 16px; + --spacers: .5rem; + --frame-height: 25px; + } +} + +@media (max-width: 525px) { + :root { + --lfw: 62px; + --left-frame-padding: .5rem; + --radius-top: 0 0 0 40px; + --radius-bottom: 40px 0 0 0; + --bar-height: 10px; + --divider-height: .3rem; + } +} + +@media (max-width: 450px) { + :root { + --nav-width: 48%; + } +} + +*, *:after, *:before { + box-sizing: border-box; +} + +* { + margin: 0; + padding: 0; + font: inherit; +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +input, textarea, button, select { + font: inherit; +} + +@font-face { + font-family: 'Antonio'; + font-weight: 400; + src: url('Antonio-Regular.woff2') format('woff2'), + url('Antonio-Regular.woff') format('woff'); +} + +@font-face { + font-family: 'Antonio'; + font-weight: 700; + src: url('Antonio-Bold.woff2') format('woff2'), + url('Antonio-Bold.woff') format('woff') +} + +html { + scroll-behavior: smooth; +} + +body { + display: flex; + padding-top: 10px; + padding-left: 5px; + background-color: black; + font-family: 'Antonio', 'Arial Narrow', 'Avenir Next Condensed', sans-serif; + font-weight: 400; + line-height: 1.5; + color: var(--font-color); +} + +a { + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: .2rem; + color: var(--link-color); +} + +a:hover { + filter: brightness(115%); + animation: none; +} + +a:active { + filter: brightness(80%); + outline: none; +} + +button { + border: none; + outline: none; + color: black; + transition: width 1s; +} + +button:hover { + cursor: pointer; + animation: none; + filter: brightness(115%); + color: black; +} + +button:active { + filter: brightness(85%); +} + +/* Ultra Layout elements */ + +.wrap-everything { + display: flex; + width: 100%; + column-gap: 10px; +} + +.wrap-standard { + width: 100%; +} + +#column-1 { + width: 350px; + padding: 10px 10px 10px 20px; + transition: 800ms; +} + +#column-2 { + width: var(--lfw); + background-color: var(--section-2-color); + text-align: right; + font-weight: bold; + line-height: 1.2; + color: black; + transition: 800ms; + z-index: 2; +} + +#column-2 a { + color: black; + text-decoration: none; +} + +#column-3 { + flex: 1; + margin-inline: auto; +} + +.wrap { + display: flex; + margin-inline: auto; + padding-left: 5px; + padding-right: 15px; + overflow: hidden; +} + +@media (max-width: 1680px) { + #column-1 { + margin-left: -370px; + } + + #column-2 { + margin-left: -230px; + } + + .wrap-everything { + column-gap: 5px; + } +} + +@media (max-width: 1500px) { + #column-1, + #column-2 { + display: none; + } +} + +.lcars-frame { + display: flex; + min-height: 280px; + position: relative; + --frame-color: var(--african-violet); +} + +.frame-col-1 { + width: 20px; + height: 280px; + background: var(--frame-color); + border-radius: 16px 0 0 16px; + position: relative; +} + +.frame-col-1:before { + content: ''; + display: block; + width: 20px; + height: 200px; + border-top: 5px solid black; + border-bottom: 5px solid black; + background-color: var(--frame-color); + position: absolute; + top: 40px; + left: 0; +} + +.frame-col-1-cell-a { + width: 14px; + height: 65px; + background-color: var(--tomato); + border-left: 4px solid black; + border-bottom: 4px solid black; + position: absolute; + top: 45px; + right: 0; + z-index: 2; +} + +.frame-col-1-cell-b { + width: 14px; + height: 70px; + background-color: var(--bluey); + border-left: 4px solid black; + position: absolute; + top: 110px; + right: 0; + z-index: 2; +} + +.frame-col-1-cell-c { + width: 14px; + height: 65px; + background-color: var(--orange); + border-top: 4px solid black; + border-left: 4px solid black; + position: absolute; + bottom: 45px; + right: 0; + z-index: 2; +} + +.frame-col-1-blocks:before { + content: ''; + display: block; + width: 10px; + height: 3px; + background-color: black; + position: absolute; + top: 54px; + left: 0; +} + +.frame-col-2 { + width:20px; + height: 280px; + background-color: var(--frame-color); + position: relative; +} + +.frame-col-2:before { + content: ''; + display: block; + width: 20px; + height: 240px; + background-color: black; + border-radius: 10px 0 0 10px; + position: absolute; + top: 20px; + left: 0; +} + +.frame-col-3 { + display: flex; + width: 240px; + height: 280px; + align-items: center; + justify-content: center; +} + +.frame-col-4 { + width:20px; + height: 280px; + background-color: var(--frame-color); + position: relative; +} + +.frame-col-4:before { + content: ''; + display: block; + width: 20px; + height: 240px; + background-color: black; + border-radius: 0 10px 10px 0; + position: absolute; + top: 20px; + left: 0; +} + +.display-horizontal { + rotate: 90deg; +} + +.frame-col-5 { + width:20px; + height: 280px; + background-color: var(--frame-color); + border-radius: 0 16px 16px 0; + padding-top: 40px; + position: relative; +} + +.frame-col-5:before { + content: ''; + display: block; + width: 20px; + height: 200px; + border-top: 5px solid black; + border-bottom: 5px solid black; + background-color: var(--frame-color); +} + +.frame-col-5-cell-a { + width: 14px; + height: 65px; + background-color: var(--lilac); + border-bottom: 4px solid black; + border-right: 4px solid black; + position: absolute; + top: 45px; + left: 0; + z-index: 2; +} + +.frame-col-5-cell-b { + width: 14px; + height: 70px; + background-color: var(--violet-creme); + border-right: 4px solid black; + position: absolute; + top: 110px; + left: 0; + z-index: 2; +} + +.frame-col-5-cell-c { + width: 14px; + height: 65px; + background-color: var(--moonlit-violet); + border-top: 4px solid black; + border-right: 4px solid black; + position: absolute; + bottom: 45px; + left: 0; + z-index: 2; +} + +.line { + height: 20px; + width: 12px; + background: linear-gradient(#600, var(--mars), #600); +} + +.line:nth-child(1) { + animation: animateLine6 1s 0.2s infinite; +} + +.line:nth-child(2) { + animation: animateLine5 1s 0.3s infinite; +} + +.line:nth-child(3) { + animation: animateLine3 1s 0.4s infinite; +} + +.line:nth-child(4) { + animation: animateLine3 1s 0.5s infinite; +} + +.line:nth-child(5) { + animation: animateLine2 1s 0.6s infinite; +} + +.line:nth-child(6) { + animation: animateLine2 1s 0.7s infinite; +} + +.line:nth-child(7) { + animation: animateLine2 1s 0.8s infinite; +} + +/* 8 & 9 are middle lines*/ + +.line:nth-child(8) { + animation: animateLine4 1s 0.9s infinite; +} + +.line:nth-child(9) { + animation: animateLine4 1s 1s infinite; +} + +.line:nth-child(10) { + animation: animateLine2 1s 0.8s infinite; +} + +.line:nth-child(11) { + animation: animateLine2 1s 0.7s infinite; +} + +.line:nth-child(12) { + animation: animateLine2 1s 0.6s infinite; +} + +.line:nth-child(13) { + animation: animateLine3 1s 0.5s infinite; +} + +.line:nth-child(14) { + animation: animateLine3 1s 0.4s infinite; +} + +.line:nth-child(15) { + animation: animateLine5 1s 0.3s infinite; +} + +.line:nth-child(16) { + animation: animateLine6 1s 0.2s infinite; +} + +@keyframes animateLine2 { + 0% { + height: 180px; + } + 50% { + height: 90px; + } + 100% { + height: 180px; + } +} + +@keyframes animateLine3 { + 0% { + height: 120px; + } + 50% { + height: 60px; + } + 100% { + height: 120px; + } +} + +@keyframes animateLine4 { + 0% { + height: 230px; + } + 50% { + height: 115px; + } + 100% { + height: 230px; + } +} + +@keyframes animateLine5 { + 0% { + height: 60px; + } + 50% { + height: 30px; + } + 100% { + height: 60px; + } +} + +@keyframes animateLine6 { + 0% { + height: 30px; + } + 50% { + height: 15px; + } + 100% { + height: 30px; + } +} + +.pillbox, +.pillbox-2 { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 8px; + margin: 1.25rem auto; + text-align: right; + font-size: var(--sub-fonts); +} + +.pill, +.pill-2 { + display: flex; + width: 100%; + height: 56px; + justify-content: flex-end; + align-items: flex-end; + text-decoration: none; + color: black; + font-weight: bold; + padding-right: .75rem; + padding-bottom: .35rem; +} + +.pillbox a { + display: flex; + width: 100%; + height: 56px; + justify-content: flex-end; + align-items: flex-end; + text-decoration: none; + color: black; + font-weight: bold; + padding-right: .75rem; + padding-bottom: .35rem; +} + +.pillbox-2 a { + display: flex; + width: 100%; + height: 56px; + justify-content: flex-end; + align-items: flex-end; + text-decoration: none; + color: black; + font-weight: bold; + padding-right: .75rem; + padding-bottom: .35rem; +} + +.pill:hover, +.pill-2:hover { + filter: brightness(115%); +} + +.pill:active, +.pill-2:active { + filter: brightness(80%); +} + +.pill:nth-child(1), +.pillbox a:nth-child(1) { + border-radius: 100vmax 0 0 100vmax; + background-color: var(--pill-1-color); +} + +.pill:nth-child(2), +.pillbox a:nth-child(2) { + background-color: var(--pill-2-color); +} + +.pill:nth-child(3), +.pillbox a:nth-child(3) { + border-radius: 100vmax 0 0 100vmax; + background-color: var(--pill-3-color); +} + +.pill:nth-child(4), +.pillbox a:nth-child(4) { + background-color: var(--pill-4-color); +} + +.pill:nth-child(5), +.pillbox a:nth-child(5) { + background-color: var(--pill-5-color); + border-radius: 100vmax 0 0 100vmax; +} + +.pill:nth-child(6), +.pillbox a:nth-child(6) { + background-color: var(--pill-6-color); +} + +.pill-2:nth-child(1), +.pillbox-2 a:nth-child(1) { + border-radius: 100vmax 0 0 100vmax; + background-color: var(--pill-a1-color); +} + +.pill-2:nth-child(2), +.pillbox-2 a:nth-child(2) { + background-color: var(--pill-a2-color); + border-radius: 0 100vmax 100vmax 0; + padding-right: 1rem; +} + +.pill-2:nth-child(3), +.pillbox-2 a:nth-child(3) { + background-color: var(--pill-a3-color); +} + +.pill-2:nth-child(4), +.pillbox-2 a:nth-child(4) { + background-color: var(--pill-a4-color); + border-radius: 0 100vmax 100vmax 0; + padding-right: 1rem; +} + +.pill-2:nth-child(5), +.pillbox-2 a:nth-child(5) { + background-color: var(--pill-a5-color); + border-radius: 100vmax 0 0 100vmax; +} + +.pill-2:nth-child(6), +.pillbox-2 a:nth-child(6) { + background-color: var(--pill-a6-color); + border-radius: 0 100vmax 100vmax 0; + padding-right: 1rem; +} + +.lcars-list-2 ul { + list-style: none; +} + +.lcars-list-2 { + margin: 0 auto 50px auto; + padding-left: 5px; +} + +.lcars-list-2 li { + position: relative; + padding-bottom: 5px; + padding-left: 38px; + font-size: var(--sub-fonts); + color: var(--orange); +} + +.lcars-list-2 li::before { + content: ''; + display: block; + width: 24px; + height: 14px; + border-radius: 50%; + background-color: var(--orange); + position: absolute; + top: 8px; + left: 0; +} + +.panel-11 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 27vh; + max-height: 275px; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-11-color); + border-bottom: var(--panel-border); +} + + +.panel-12 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 34vh; + max-height: 350px; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-12-color); + border-bottom: var(--panel-border); +} + +.panel-13 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 20vh; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-13-color); + border-bottom: var(--panel-border); +} + +.panel-14 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 20vh; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-14-color); + border-bottom: var(--panel-border); +} + +.panel-15 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 20vh; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-15-color); + border-bottom: var(--panel-border); +} + +.section-2-buttons a { + display: block; + text-decoration: none; + text-align: right; + border-bottom: var(--panel-border); + padding: 1.5rem .75rem .75rem 2px; + background-color: var(--section-2-color); + text-transform: uppercase; + color: black; +} + +.section-2-buttons a:nth-child(2) { + background-color: var(--butterscotch); +} + +.section-2-buttons a:nth-child(3) { + background-color: var(--african-violet); +} + +/* End Ultra layout elements */ + +.scroll-top { + display: none; +} + +.left-frame-top, +.left-frame { + width: var(--lfw); + text-align: right; + font-size: clamp(.875rem, 2vw, 1rem); + line-height: 1.2; + font-weight: bold; + color: black; + transition: width 1s; +} + +.left-frame-top { + background-color: var(--left-frame-top-color); + border-radius: var(--radius-top); +} + +.left-frame-top a, +.left-frame a { + text-decoration: none; + color: black; +} + +.left-frame { + display: flex; + flex-direction: column; + justify-content: space-between; + padding-top: 100px; + background-color: var(--left-frame-color); + border-radius: var(--radius-bottom); +} + +.right-frame-top { + flex: 1; + align-content: flex-end; + position: relative; +} + +.right-frame-top:before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to top right, var(--corner-color-top) 50%, black 50%); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +.right-frame-top:after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-top); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +@media (max-width: 650px) { + .right-frame-top:before { + bottom: 16px; + } + + .right-frame-top:after { + bottom: 16px; + } +} + +@media (max-width: 525px) { + .right-frame-top:before { + bottom: 10px; + } + + .right-frame-top:after { + bottom: 10px; + } +} + +.banner { + padding-bottom: 1rem; + padding-left: 5px; + text-align: right; + text-transform: uppercase; + line-height: 1.1; + font-size: clamp(1.25rem, 0.75rem + 4vw, 4rem); + color: var(--banner-color); +} + +.banner a { + color: var(--banner-color); + text-decoration: none; +} + +.data-cascade-button-group { + display: flex; + justify-content: flex-end; + align-items: flex-start; + flex-wrap: wrap; +} + +.header-content { + flex: 1; + min-height: 180px; + padding-right: .5rem; + padding-left: clamp(20px, 3vw, 50px); +} + +.header-content > *:first-child { + margin-top: 0; +} + +.header-content > *:last-child { + margin-bottom: 0; +} + +/* Data Cascade 2025 */ + +.data-cascade-wrapper { + flex: 1; + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + max-width: 100%; + height: calc(var(--dc-row-height) * 9); /* 204px */ + overflow: hidden; + padding-right: .5rem; + padding-left: clamp(20px, 3vw, 50px); + column-gap: .5rem; +} + +.data-column { + display: grid; + grid-template-columns: 1fr; + margin-top: 1px; + text-align: right; + font-size: var(--dc-font-size); /* .938 */ + line-height: 1; + color: black; +} + +.dc-row-1, +.dc-row-2, +.dc-row-3, +.dc-row-4, +.dc-row-5, +.dc-row-6, +.dc-row-7 { + text-box: trim-both cap alphabetic; + height: var(--dc-row-height); +} + +@media (max-width: 780px) { + .data-cascade-wrapper { + display: none; + } +} + +@keyframes data-group-1 { + + 0%, + 3.99% { + color: black; + } + + 4%, + 45.99% { + color: var(--data-cascade-color); + } + + 46%, + 49.99% { + color: var(--light-color); + } + + 50%, + 63.99% { + color: var(--data-cascade-color); + } + + 64%, + 67.99% { + color: var(--light-color); + } + + 68%, + 100% { + color: var(--data-cascade-color); + } +} + +@keyframes data-group-1a { + + 0%, + 4.99% { + color: black; + } + + 5%, + 45.99% { + color: var(--data-cascade-color); + } + + 46%, + 49.99% { + color: var(--light-color); + } + + 50%, + 63.99% { + color: var(--data-cascade-color); + } + + 64%, + 67.99% { + color: var(--light-color); + } + + 68%, + 100% { + color: var(--data-cascade-color); + } +} + +@keyframes data-group-2 { + + 0%, + 12.99% { + color: black; + } + + 13%, + 49.99% { + color: var(--data-cascade-color); + } + + 50%, + 53.99% { + color: var(--light-color); + } + + 54%, + 67.99% { + color: var(--data-cascade-color); + } + + 68%, + 71.99% { + color: var(--light-color); + } + + 72%, + 100% { + color: var(--data-cascade-color); + } +} + +@keyframes data-group-2b { + + 0%, + 14.99% { + color: black; + } + + 15%, + 49.99% { + color: var(--data-cascade-color); + } + + 50%, + 53.99% { + color: var(--light-color); + } + + 54%, + 67.99% { + color: var(--data-cascade-color); + } + + 68%, + 71.99% { + color: var(--light-color); + } + + 72%, + 81.99% { + color: var(--data-cascade-color); + } + + 82%, + 100% { + color: var(--light-color); + } +} + +@keyframes data-group-3 { + + 0%, + 26.99% { + color: black; + } + + 27%, + 40.99% { + color: var(--light-color); + } + + 41%, + 53.99% { + color: var(--data-cascade-color); + } + + 54%, + 57.99% { + color: var(--light-color); + } + + 58%, + 71.99% { + color: var(--data-cascade-color); + } + + 72%, + 75.99% { + color: var(--light-color); + } + + 76%, + 100% { + color: var(--data-cascade-color); + } +} + +.dc-row-1 { + animation: data-group-1 6000ms ease 200ms infinite; +} + +.dc-row-2 { + animation: data-group-1a 6000ms ease 200ms infinite; +} + +.dc-row-3 { + animation: data-group-2 6000ms ease 200ms infinite; +} + +.dc-row-4 { + animation: data-group-2b 6000ms ease 200ms infinite; +} + +.dc-row-5 { + animation: data-group-3 6000ms ease 200ms infinite; +} + +.dc-row-6 { + animation: data-group-3 6000ms ease 200ms infinite; +} + +.dc-row-7 { + animation: data-group-3 6000ms ease 200ms infinite; +} + +/* Static data cascade */ + +.data-cascade-wrapper#frozen .dc-row-1 { + animation: none; + color: var(--orange); +} + +.data-cascade-wrapper#frozen .dc-row-2 { + animation: none; + color: var(--orange); +} + +.data-cascade-wrapper#frozen .dc-row-3 { + animation: none; + color: var(--orange); +} + +.data-cascade-wrapper#frozen .dc-row-4 { + animation: none; + color: var(--orange); +} + +.data-cascade-wrapper#frozen .dc-row-5 { + animation: none; + color: var(--light-color); +} + +.data-cascade-wrapper#frozen .dc-row-6 { + animation: none; + color: var(--light-color); +} + +.data-cascade-wrapper#frozen .dc-row-7 { + animation: none; + color: var(--light-color); +} + +/* Navigation & buttons */ + +.lcars-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + margin-block: 1rem; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1 a { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + height: clamp(90px, 11vw, 160px); + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + transition: width 1s; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1-button { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + min-height: clamp(90px, 11vw, 160px); + overflow: hidden; + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav { + display: flex; + flex-wrap: wrap; + align-self: center; + width: calc(var(--nav-width) + var(--nav-width) + 1rem); + justify-content: flex-end; + column-gap: .5rem; + row-gap: .65rem; +} + +@media (max-width: 1500px) { + nav { + column-gap: .375rem; + row-gap: .5rem; + } +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +nav a, +nav button, +.buttons button { + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: flex-end; + width: var(--nav-width); + height: calc(var(--nav-width) / 2.8); + padding-inline: 1.5rem; + padding-bottom: .7rem; + border-radius: 100vmax; + background-color: var(--button-color); + text-align: right; + line-height: 1.175; + text-decoration: none; + text-transform: uppercase; + font-weight: bold; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav a:nth-child(1), +nav button:nth-child(1) { + background-color: var(--nav-1-color); +} + +nav a:nth-child(2), +nav button:nth-child(2) { + background-color: var(--nav-2-color); +} + +nav a:nth-child(3), +nav button:nth-child(3) { + background-color: var(--nav-3-color); +} + +nav a:nth-child(4), +nav button:nth-child(4) { + background-color: var(--nav-4-color); +} + +@media (max-width: 1300px) { + nav { + padding-left: .5rem; + gap: .5rem; + } + + nav button { + padding-bottom: .5rem; + font-size: .875rem; + padding-inline: 1.25rem; + } +} + +@media (max-width: 780px) { + nav { + flex: 1; + } + + .data-cascade-button-group:has(.header-content) > *:nth-child(2) { + flex: none; + } +} + +@media (max-width: 450px) { + nav a, + nav button { + height: 63px; + } +} + +.buttons { + display: flex; + flex-wrap: wrap; + gap: .5rem; + margin-block: 2rem; +} + +.justify-space-between { + justify-content: space-between; +} + +.justify-center { + justify-content: center; +} + +.justify-flex-end { + justify-content: flex-end; +} + +.justify-space-around { + justify-content: space-around; +} + +.justify-space-evenly { + justify-content: space-evenly; +} + +.buttons a, +.buttons button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.sidebar-nav button, +.sidebar-nav a, +.sidebar-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + min-height: 3.75rem; + width: var(--lfw); + background-color: var(--button-color-sidebar); + border-radius: 0; + border-bottom: var(--panel-border); + padding: var(--left-frame-padding); + text-decoration: none; + text-align: right; + word-break: break-all; + text-transform: uppercase; + color: black; +} + +@media (max-width: 1300px) { + .lcars-button, + .buttons a, + .buttons button { + width: 200px; + height: 74px; + } +} + +.panel-button { + display: flex; + justify-content: flex-end; + width: var(--lfw); + border-radius: 0; + padding: var(--left-frame-padding); + border-bottom: var(--panel-border); +} + +.pan-0 /* use this if you're not mimicking an established panel */ { + height: 18vh; + max-height: 240px; + background-color: var(--button-color-sidebar); +} + +.pan-4 { + height: 22vh; + max-height: 300px; + background-color: var(--panel-4-color) !important; +} + +.pan-5 { + height: 4.25rem; + background-color: var(--panel-5-color) !important; + align-items: center; +} + +.pan-6 { + height: 29vh; + max-height: 360px; + background-color: var(--panel-6-color) !important; +} + +.pan-7 { + height: 27vh; + max-height: 350px; + background-color: var(--panel-7-color) !important; +} + +.pan-8 { + height: 15vh; + background-color: var(--panel-8-color) !important; +} + +.pan-10 { + height: 30vh; + background-color: var(--panel-10-color) !important; +} + +.text-bottom { + align-items: flex-end; +} + +#topBtn { + display: none; + position: fixed; + bottom: 0; + z-index: 99; + border-radius: 0; + border-top: var(--panel-border); + border-right: none; + border-bottom: var(--panel-border); + border-left: none; + outline: none; + width: var(--lfw); + padding: var(--left-frame-padding); + padding-bottom: 10vh; + background-color: var(--panel-top-button-color); + text-align: right; + line-height: 1; + font-weight: bold; + text-transform: uppercase; + color: black; + cursor: pointer; +} + +#topBtn:hover { + filter: brightness(115%); +} + +#topBtn:active { + filter: brightness(80%); +} + +@media (max-width: 525px) { + .sidebar-button, + .sidebar-nav a, + .sidebar-nav button, + .panel-button { + font-size: .75rem; + } + + #topBtn { + padding-bottom: 6vh; + } +} + +/* --- Horizontal bar panels & sidebar panels --- */ + +.bar-panel { + display: flex; + height: var(--bar-height); +} + +.first-bar-panel { + margin-top: clamp(15px, 2vw, 30px); +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-5, +.bar-6, +.bar-7, +.bar-9, +.bar-10 { + height: var(--bar-height); +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-6, +.bar-7, +.bar-8, +.bar-9 { + border-right: var(--bar-border); +} + +.bar-1 { + width: var(--bar-1-6-width); + background-color: var(--bar-1-color); +} + +.bar-2 { + width: var(--bar-2-7-width); + background-color: var(--bar-2-color); +} + +.bar-3 { + width: var(--bar-3-8-width); + background-color: var(--bar-3-color); +} + +.bar-4 { + flex: 1; + background-color: var(--bar-4-color); +} + +.bar-5 { + width: var(--bar-5-10-width); + background-color: var(--bar-5-color); +} + +.bar-6 { + width: var(--bar-1-6-width); + background-color: var(--bar-6-color); +} + +.bar-7 { + width: var(--bar-2-7-width); + background-color: var(--bar-7-color); +} + +.bar-8 { + width: var(--bar-3-8-width); + height: 50%; + background-color: var(--bar-8-color); +} + +.bar-9 { + flex: 1; + background-color: var(--bar-9-color); +} + +.bar-10 { + width: var(--bar-5-10-width); + background-color: var(--bar-10-color); +} + +#gap { + margin-top: var(--divider-height); +} + +.panel-3, +.panel-4, +.panel-5, +.panel-6, +.panel-7, +.panel-8 { + border-bottom: var(--panel-border); +} + +.panel-2, +.panel-3, +.panel-4, +.panel-6, +.panel-7, +.panel-8, +.panel-10 { + padding: var(--left-frame-padding); +} + +.panel-4 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 22vh; + max-height: 300px; + background-color: var(--panel-4-color); +} + +.panel-5 { + display: flex; + justify-content: flex-end; + align-items: center; + height: 4.25rem; + padding: var(--left-frame-padding); + background-color: var(--panel-5-color); +} + +.panel-6 { + height: 29vh; + max-height: 360px; + background-color: var(--panel-6-color); +} + +.panel-7 { + height: 27vh; + max-height: 350px; + background-color: var(--panel-7-color); +} + +.panel-8 { + height: 15vh; + background-color: var(--panel-8-color); +} + +/* Note: panel-9 height is fluid and governed by the amount of content on the page. Background color is inherited from :root --left-frame-color */ + +.panel-9 { + min-height: 27vh; + padding: var(--left-frame-padding); +} + +.panel-10 { + height: 30vh; + border-top: var(--panel-border); + background-color: var(--panel-10-color); +} + +@media (max-width: 525px) { + .panel-4, + .panel-6, + .panel-7 { + height: 18vh; + } +} + +.right-frame { + flex: 1; + position: relative; +} + +.right-frame::before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to bottom right, var(--corner-color-bottom) 50%, black 50%); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +.right-frame::after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-bottom); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +main { + padding-top: 1.5rem; + padding-bottom: .5rem; + padding-left: clamp(20px, 3vw, 50px); +} + +main > *:first-child, +article > *:first-child { + margin-top: 0; +} + +main:has(.floor-heading) > *:nth-child(2) { + margin-top: 0; +} + +@media (max-width: 1400px) { + main { + padding-top: 1rem; + } +} + +.flexbox { + display: flex; + gap: 2vw; + flex-wrap: wrap; +} + +.col { + flex: 1 1 360px; +} + +.col > *:first-child { + margin-top: 0; +} + +h1, h2, h3, h4 { + margin-block: 1.75rem; + font-weight: normal; + line-height: 1.2; + text-transform: uppercase; + text-box: trim-both cap alphabetic; +} + +h1 { + font-size: clamp(1.5rem, 1.25rem + 3.5vw, 4rem); + text-align: right; + color: var(--h1-color); +} + +h2 { + font-size: clamp(1.4rem, 1.1rem + 2.25vw, 2.3rem); + color: var(--h2-color); +} + +h3 { + font-size: clamp(1.15rem, 1.05rem + 1.25vw, 1.875rem); + color: var(--h3-color); +} + +h4 { + font-size: clamp(1.025rem, 1rem + 1.125vw, 1.575rem); + color: var(--h4-color); +} + +.floor-heading { + display: flex; + justify-content: flex-end; + width: 100%; + position: fixed; + left: 50%; + transform: translate(-50%, 0); + bottom: 10px; + z-index:4; +} + +.floor-heading > * { + margin-block: 0; + width: fit-content; + padding-inline: .5rem; + padding-bottom: .5rem; + background-color: black; +} + +p { + margin-block: 1.75rem; + text-box: trim-both cap alphabetic; +} + +.caption { + margin-top: -1rem; + margin-bottom: 2.75rem; + text-align: center; + font-size: var(--sub-fonts); +} + +.pics-right .caption, +.pics-left .caption { + margin-top: 1rem; +} + +.indent { + padding-left: 1.5rem; +} + +.postmeta { + margin-block: 1.25rem; + text-align: right; + font-size: clamp(1.2rem, 0.88rem + 1.28vw, 1.6rem); + line-height: 1.2; + text-transform: uppercase; +} + +article h1 { + margin-bottom: 0; +} + +hr { + margin-block: 1.5rem; + height: 6px; + border: none; + background-color: var(--font-color); + border-radius: 3px; +} + +blockquote { + margin-block: 1.75rem; + margin-left: 1.5rem; + padding-block: .25rem; + padding-left: 1.5rem; + position: relative; + text-box: trim-both cap alphabetic; +} + +blockquote::before { + content: ''; + display: block; + width: 10px; + height: 100%; + background-color: var(--font-color); + border-radius: 5px; + position: absolute; + left: 0; + top: 0; +} + +blockquote > *:first-child { + margin-top: 0; +} + +blockquote > * { + margin-bottom: 0; +} + +iframe { + display: block; + width: 100%; + border: none; +} + +.flush { + margin-top: -1rem; +} + +.nomar { + margin-block: 0 !important; +} + +.go-center { + text-align: center !important; +} + +.go-right { + text-align: right !important; +} + +.go-left { + text-align: left !important; +} + +.go-big { + font-size: clamp(1.2rem, 1rem + 1vw, 1.275rem); +} + +.uppercase { + text-transform: uppercase; +} + +.strike { + text-decoration: line-through; + text-decoration-thickness: .15rem; +} + +.now { + white-space: nowrap; +} + +.big-sky { + margin-top: 5rem; +} + +.smoke-glass { + opacity: .35; +} + +strong { + font-weight: bold; +} + +code { + font-family: monospace; + font-size: .9rem; + color: var(--code-color); +} + +.code { + width: 100%; + min-height: 5rem; + padding-block: .5rem; + padding-inline: 1rem; + background-color: black; + border-color: var(--code-color); + tab-size: 4; + font-family: monospace; + font-size: .85rem; + color: var(--code-color); +} + +::selection { + background-color: var(--orange); + color: black; +} + +@keyframes blink { + 0% {opacity: 0} + 49%{opacity: 0} + 50% {opacity: 1} +} + +.blink-slow { + animation: blink 3500ms infinite; +} + +.blink { + animation: blink 2s infinite; +} + +.blink-fast { + animation: blink 1s infinite; +} + +@keyframes pulse { + 0% {filter: brightness(1.0)} + 50% {filter: brightness(.25)} +} + +.pulse { + animation: pulse 2s infinite; +} + +.pulse-rate-high { + animation: pulse 1s infinite; +} + +.pulse-rate-low { + animation: pulse 3s infinite; +} + +/* Accordion Dropdown */ + +.accordion-wrapper { + display: block; + margin: 1.75rem auto; + width: 100%; +} + +.limit-width { + max-width: 1240px; +} + +.accordion { + display: flex; + align-items: center; + min-height: 3rem; + width: 100%; + padding-right: 2.75rem; + padding-left: 1rem; + border-radius: 100vmax; + background-color: var(--african-violet); + border-left: solid 3rem var(--moonlit-violet); + text-align: left; + font-size: 1.25rem; + color: black; + cursor: pointer; + transition: 0.4s ease; + position: relative; +} + +.active, .accordion:hover { + background-color: var(--violet-creme); + border-left-color: var(--orange); + filter: none; +} + +.accordion:before { + content: ''; + display: block; + width: .5rem; + height: 4rem; + background-color: black; + position: absolute; + top: 0; + left: 0; +} + +.accordion:after { + display: block; + content: '\276F'; + position: absolute; + right: 1.5rem; + top: 21%; + transform: rotate(90deg); + transition: 0.4s; + font-weight: bold; + color: black; +} + +.active:after { + content: "\276F"; + transform:rotate(-90deg); + transition: 0.4s ease; +} + +.accordionContent { + padding-block: .5rem; + padding-inline: 3.5rem; + max-height: 0; + overflow: hidden; + transition: max-height 0.25s ease-out; +} + +.accordionContent ul { + margin-left: 0; +} + +@media (max-width: 525px) { + .accordion { + min-height: 2.5rem; + font-size: 1rem; + border-left-width: 2.5rem; + } +} + +/* Images */ + +.pics-right { + float: right; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; + clear: both; +} + +.pics-left { + float: left; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +@media (max-width: 1060px) { + .pics-right, + .pics-left { + float: none; + margin-inline: auto; + } + + .pics-right img, + .pics-left img { + margin-inline: auto; + } +} + +.pics { + margin-block: 2rem; + margin-inline: auto; +} + +.border { + border: 2px solid var(--font-color); +} + +/* + +Gallery + +NOTE: Gallery is experimental and still under development. + +*/ + +.gallery { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: .75rem; + list-style: none; + text-align: center; + font-size: .875rem; +} + +.gallery img { + align-self: flex-start; + border: 4px solid black; +} + +.gallery li div { + padding-block: .6rem; + text-box: trim-both cap alphabetic; +} + +.thumbs img { + width: 340px; +} + +.gallery a { + align-self: flex-start; +} + +.gallery a img:hover { + border-color: var(--font-color); +} + +.lcars-list { + margin-block: 1.15rem; + margin-left: 2rem; + list-style: none; +} + +.lcars-list li { + position: relative; + padding-block: .45rem; + padding-left: 2.25rem; + text-box: trim-both cap alphabetic; +} + +.lcars-list li::before { + content: ''; + display: block; + width: 34px; + height: 18px; + border-radius: 50%; + background-color: var(--font-color); + position: absolute; + top: .45rem; + left: 0; +} + +@media (max-width: 650px) { + .lcars-list { + margin-left: .5rem; + } + + .lcars-list li::before { + transform: scale(90%); + } +} + +.lcars-bar { + margin-block: 1.75rem; + height: clamp(15px, 2vh, 25px); + background: transparent; + border-right: clamp(15px, 2vh, 25px) solid var(--lcars-bar-end-color); + border-left: clamp(15px, 2vh, 25px) solid var(--lcars-bar-start-color); + border-radius: 100vmax; + position: relative; +} + +.lcars-bar::after { + content: ''; + display: block; + height: clamp(15px, 2vh, 25px); + width: 100%; + background-color: var(--lcars-bar-color); + border-right: .8vh solid black; + border-left: .8vh solid black; + position: absolute; + top: 0; + left: 0; +} + +.lcars-text-bar { + display: flex; + position: relative; + height: clamp(16px, 4vh, 41px); + margin-block: 2.75rem; + overflow: visible; + border-radius: 100vmax; + background-color: var(--lcars-bar-color); + border-right: clamp(16px, 4vh, 43px) solid var(--lcars-bar-end-color); + border-left: clamp(16px, 4vh, 43px) solid var(--lcars-bar-start-color); +} + +.the-end { + justify-content: flex-end; +} + +.lcars-text-bar h2, +.lcars-text-bar h3, +.lcars-text-bar h4, +.lcars-text-bar span { + margin-block: 0; + background-color: black; + height: clamp(20px, 5.5vh, 60px); /* Setting height is a Firefox fix */ + overflow: visible; + border-top: 1px solid black; + padding-inline: 1vh; + font-size: clamp(17px, 4.5vh, 46px); + line-height: 1; + text-transform: uppercase; + color: var(--lcars-bar-text-color); + z-index: 1; + text-box: trim-both cap alphabetic; +} + +.lcars-text-bar::before { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} + +.lcars-text-bar::after { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + right: 0; + overflow: hidden; +} + +/* Image Frame */ + +.image-frame { + display: block; + margin: 2.75rem auto; + width: fit-content; + background: linear-gradient(var(--primary-color) 56%, var(--secondary-color) 44%); + border-radius: 50px 25px 0 50px; + position: relative; +} + +.image-frame::before { + content: ''; + display: block; + width: 40px; + height: 40px; + background-color: black; + position: absolute; + right: 0; + top: 0; +} + +.image-frame::after { + content: ''; + display: block; + border-top: var(--spacers) solid black; + border-bottom: var(--spacers) solid black; + width: 45px; + height: 80px; + background-color: var(--secondary-color); + position: absolute; + left: 0; + top: 56%; +} + +.imgf-title { + display: flex; + justify-content: flex-end; + height: 40px; + border-right: 40px solid var(--secondary-color); + border-radius: 25px 100vh 100vh 0; + position: relative; + z-index: 1; + text-align: right; +} + +.h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + border-right: var(--spacers) solid black; +} + +.imgf-title h4 { + margin-block: 0; + width: fit-content; + background-color: black; + padding-left: var(--spacers); + font-size: 2.05rem; + color: var(--title-color); + line-height: 40px; + text-transform: uppercase; +} + +.imgf-image-body { + margin-left: 45px; + background-color: black; + width: fit-content; + padding: 1rem; + border-radius: 28px 0 0 28px; + +} + +.image-holder { + width: fit-content; + padding: 1rem; + border: 2px solid var(--image-border-color); + border-radius: 20px; +} + +.imgf-base { + display: grid; + grid-template-columns: 20% 13% 35px 15% 1fr; + margin-left: 80px; + border-left: var(--spacers) solid black; + +} + +.imgf-block-1 { + height: var(--frame-height); + background-color: var(--accent-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-2 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-3 { + height: var(--frame-height); + background-color: black; + border-right: 10px solid var(--secondary-color); + border-left: 10px solid var(--accent-color); +} + +.imgf-block-4 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-left: var(--spacers) solid black; +} + +.imgf-block-5 { + height: var(--frame-height); + background-color: black; +} + +@media (max-width: 750px) { + .image-frame { + border-radius: 40px 25px 0 40px; + } + + .image-frame::after { + width: 25px; + height: 60px; + top: 50%; + } + + .imgf-title { + height: 25px; + border-right: 24px solid var(--secondary-color); + } + + .h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + } + + .imgf-title h4 { + font-size: 1.45rem; + } + + .imgf-image-body { + margin-left: 25px; + padding: .75rem; + border-radius: 20px 0 0 20px; + } + + .image-holder { + padding: .75rem; + border-radius: 10px; + } +} + +/* color custom classes */ + +.font-african-violet { + color: var(--african-violet) !important; +} + +.button-african-violet, +.background-african-violet, +.bullet-african-violet { + background-color: var(--african-violet) !important; +} + +.font-almond { + color: var(--almond) !important; +} + +.button-almond, +.background-almond, +.bullet-almond::before { + background-color: var(--almond) !important; +} + +.font-almond-creme { + color: var(--almond-creme) !important; +} + +.button-almond-creme, +.background-almond-creme, +.bullet-almond-creme::before { + background-color: var(--almond-creme) !important; +} + +.font-blue { + color: var(--blue) !important; +} + +.button-blue, +.background-blue, +.bullet-blue::before { + background-color: var(--blue) !important; +} + +.font-bluey { + color: var(--bluey) !important; +} + +.button-bluey, +.background-bluey, +.bullet-bluey::before { + background-color: var(--bluey) !important; +} + +.font-butterscotch { + color: var(--butterscotch) !important; +} + +.button-butterscotch, +.background-butterscotch, +.bullet-butterscotch::before { + background-color: var(--butterscotch) !important; +} + +.font-gold { + color: var(--gold) !important; +} + +.button-gold, +.background-gold, +.bullet-gold::before { + background-color: var(--gold) !important; +} + +.font-golden-orange { + color: var(--golden-orange) !important; +} + +.button-golden-orange, +.background-golden-orange, +.bullet-golden-orange::before { + background-color: var(--golden-orange) !important; +} + +.font-gray { + color: var(--gray) !important; +} + +.button-gray, +.background-gray, +.bullet-gray::before { + background-color: var(--gray) !important; +} + +.font-green { + color: var(--green) !important; +} + +.button-green, +.background-green, +.bullet-green::before { + background-color: var(--green) !important; +} + +.font-ice { + color: var(--ice) !important; +} + +.button-ice, +.background-ice, +.bullet-ice::before { + background-color: var(--ice) !important; +} + +.font-lilac { + color: var(--lilac) !important; +} + +.button-lilac, +.background-lilac, +.bullet-lilac::before { + background-color: var(--lilac) !important; +} + +.font-lima-bean { + color: var(--lima-bean) !important; +} + +.button-lima-bean, +.background-lima-bean, +.bullet-lima-bean::before { + background-color: var(--lima-bean) !important; +} + +.font-magenta { + color: var(--magenta) !important; +} + +.button-magenta, +.background-magenta, +.bullet-magenta::before { + background-color: var(--magenta) !important; +} + +.font-mars { + color: var(--mars) !important; +} + +.button-mars, +.background-mars, +.bullet-mars::before { + background-color: var(--mars) !important; +} + +.font-moonlit-violet { + color: var(--moonlit-violet) !important; +} + +.button-moonlit-violet, +.background-moonlit-violet, +.bullet-moonlit-violet::before { + background-color: var(--moonlit-violet) !important; +} + +.font-orange { + color: var(--orange) !important; +} + +.button-orange, +.background-orange, +.bullet-orange::before { + background-color: var(--orange) !important; +} + +.font-peach { + color: var(--peach) !important; +} + +.button-peach, +.background-peach, +.bullet-peach::before { + background-color: var(--peach) !important; +} + +.font-red { + color: var(--red) !important; +} + +.button-red, +.background-red, +.bullet-red::before { + background-color: var(--red) !important; +} + +.font-sky { + color: var(--sky) !important; +} + +.button-sky, +.background-sky, +.bullet-sky::before { + background-color: var(--sky) !important; +} + +.font-space-white { + color: var(--space-white) !important; +} + +.button-space-white, +.background-space-white, +.bullet-space-white::before { + background-color: var(--space-white) !important; +} + +.font-sunflower { + color: var(--sunflower) !important; +} + +.button-sunflower, +.background-sunflower, +.bullet-sunflower::before { + background-color: var(--sunflower) !important; +} + +.font-tomato { + color: var(--tomato) !important; +} + +.button-tomato, +.background-tomato, +.bullet-tomato::before { + background-color: var(--tomato) !important; +} + +.font-violet-creme { + color: var(--violet-creme) !important; +} + +.button-violet-creme, +.background-violet-creme, +.bullet-violet-creme::before { + background-color: var(--violet-creme) !important; +} + +/* Footer */ + +footer { + margin-top: 2.5vw; + padding-bottom: 3rem; + padding-left: clamp(20px, 3vw, 50px); + font-size: .825rem; + --footer-bar-height: 1rem; +} + +footer:has(.footer-frame) { + font-size: inherit; +} + +.footer-frame { + display: grid; + grid-template-columns: 1fr var(--lfw); + align-items: center; + background: linear-gradient(var(--red) 50%, var(--bluey) 50%); + border-radius: 0 2rem 2rem 0; + padding-block: var(--footer-bar-height); + position: relative; +} + +.footer-frame::before { + content: ''; + display: block; + width: 20%; + height: calc(var(--footer-bar-height) / 2); + /*border-radius: 100vmax 0 0 100vmax;*/ + position: absolute; + left: 0; + top: calc(var(--footer-bar-height) + .5rem); + background-color: var(--red); + z-index: 1; +} + +.footer-frame::after { + content: ''; + display: block; + width: 20%; + height: calc(var(--footer-bar-height) / 2); + /*border-radius: 100vmax 0 0 100vmax;*/ + position: absolute; + left: 0; + bottom: var(--footer-bar-height); + background-color: var(--bluey); +} + +.footer-frame-content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background-color: black; + min-height: 250px; + border-radius: 0 1.5rem 1.5rem 0; + padding-block: 2.5rem; + padding-inline: 2rem; + position: relative; + text-align: center; +} + +.footer-frame-content::before { + content: ''; + display: block; + width: .25rem; + height: var(--footer-bar-height); + background-color: black; + position: absolute; + top: calc(var(--footer-bar-height) - var(--footer-bar-height) * 2); + left: 62%; +} + +.footer-frame-content::after { + content: ''; + display: block; + width: .25rem; + height: var(--footer-bar-height); + background-color: black; + position: absolute; + bottom: calc(var(--footer-bar-height) - var(--footer-bar-height) * 2); + left: 62%; +} + +.footer-frame-content p { + margin-block: .8rem; +} + +@media (max-width: 880px) { + .footer-frame-content .buttons { + justify-content: center; + } +} + +@media (max-width: 600px) { + footer { + --footer-bar-height: .75rem; + } + + .footer-frame-content { + padding-inline: .5rem; + } +} + +.footer-frame-content *:first-child { + margin-top: 0; +} + +.footer-frame-content *:last-child { + margin-bottom: 0; +} + +.footer-frame-panel { + height: 50%; + min-height: 100px; + background-color: var(--butterscotch); + border-block: var(--bar-border); + padding: var(--left-frame-padding); + font-size: clamp(.875rem, 2vw, 1rem); + font-weight: bold; + color: black; +} + +.headtrim { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + top: 0; + left: 0; + z-index: 999; +} + +.baseboard { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + bottom: 0; + left: 0; + z-index: 999; +} + +/* Grouped @media */ + +@media (max-width: 525px) { + body { + padding: .25rem; + } + + .baseboard, + .headtrim { + display: none; + } + + .wrap { + padding-left: 0; + padding-right: .25rem; + } + + .left-frame { + padding-top: 25px; + } + + .floor-heading { + bottom: 0; + } + + .hop { + display: none; + } + + blockquote { + margin-left: .75rem; + } +} + +@-moz-document url-prefix() { + + main { + padding-top: clamp(1rem, 4vw, 30px); + } + + h1, h2, h3, h4, p { + margin-block: 1.15rem; + } + + .imgf-title h4 { + margin-top: -4px; + margin-bottom: 0; + } + + .postmeta { + margin-top: .75rem; + } + + .lcars-text-bar h2, + .lcars-text-bar h3, + .lcars-text-bar h4, + .lcars-text-bar span { + position: absolute; + top: -.7vh; + } + + .lcars-list li::before { + top: .85rem; + } + + .meta-data { + height: 1.3rem; + line-height: 1rem; + } +} \ No newline at end of file diff --git a/lcars_v4/frontend/assets/lcars.js b/lcars_v4/frontend/assets/lcars.js new file mode 100644 index 0000000..6a6c762 --- /dev/null +++ b/lcars_v4/frontend/assets/lcars.js @@ -0,0 +1,51 @@ +document.addEventListener("touchstart", function() {},false); +let mybutton = document.getElementById("topBtn"); +window.onscroll = function() {scrollFunction()}; +function scrollFunction() { + if (document.body.scrollTop > 200 || document.documentElement.scrollTop > 200) { + mybutton.style.display = "block"; + } else { + mybutton.style.display = "none"; + } +} +function topFunction() { + document.body.scrollTop = 0; + document.documentElement.scrollTop = 0; +} +function playSoundAndRedirect(audioId, url) { + // var audio = document.getElementById(audioId); + // audio.play(); + + // audio.onended = function() { + // console.log("Audio has ended", url); + window.location.href = url; + // }; +} +function goToAnchor(anchorId) { + window.location.hash = anchorId; +} +// Accordion drop-down +var acc = document.getElementsByClassName("accordion"); +var i; + +for (i = 0; i < acc.length; i++) { + acc[i].addEventListener("click", function() { + this.classList.toggle("active"); + var accordionContent = this.nextElementSibling; + if (accordionContent.style.maxHeight){ + accordionContent.style.maxHeight = null; + } else { + accordionContent.style.maxHeight = accordionContent.scrollHeight + "px"; + } + }); +} +// LCARS keystroke sound (not to be used with hyperlinks) + const LCARSkeystroke = document.getElementById('LCARSkeystroke'); + const allPlaySoundButtons = document.querySelectorAll('.playSoundButton'); + allPlaySoundButtons.forEach(button => { + button.addEventListener('click', function() { + LCARSkeystroke.pause(); + LCARSkeystroke.currentTime = 0; // Reset to the beginning of the sound + LCARSkeystroke.play(); + }); + }); \ No newline at end of file diff --git a/lcars_v4/frontend/assets/lower-decks-padd.css b/lcars_v4/frontend/assets/lower-decks-padd.css new file mode 100644 index 0000000..51cd3a6 --- /dev/null +++ b/lcars_v4/frontend/assets/lower-decks-padd.css @@ -0,0 +1,1885 @@ +@charset "utf-8"; + +/* + + CSS Document + LCARS Lower Decks PADD Theme + Version 24.2 + By Jim Robertus www.thelcars.com + Modified: 2025 Aug 4 + +*/ + +@view-transition { + navigation: auto; +} + +:root { + font-size: 1.375rem; + color-scheme: dark; + --lfw: 240px; + --alpha-blue: #58e; + --arctic-ice: #6cf; + --arctic-snow: #9cf; + --radioactive: #8ff; + --beta-blue: #79d; + --night-cloud: #344470; + --night-rain: #455580; + --sunset-red: #f30; + --left-frame-top-color: var(--alpha-blue); + --left-frame-color: var(--alpha-blue); /* panel-6 inherits this color */ + --left-frame-padding: .75rem; + --corner-color-top: var(--alpha-blue); + --corner-color-bottom: var(--alpha-blue); + --panel-1-color: var(--night-rain); + --panel-4-color: var(--beta-blue); + --panel-5-color: var(--night-rain); + --panel-7-color: var(--night-cloud); + --panel-top-button-color: var(--beta-blue); + --bar-height: 28px; + --bar-1-6-width: 10%; + --bar-2-7-width: 28%; + --bar-3-8-width: 7%; + --bar-5-10-width: 5%; + --bar-1-color: var(--alpha-blue); + --bar-2-color: var(--radioactive); + --bar-3-color: var(--beta-blue); + --bar-4-color: var(--alpha-blue); + --bar-5-color: var(--arctic-ice); + --bar-6-color: var(--alpha-blue); + --bar-7-color: var(--radioactive); + --bar-8-color: var(--beta-blue); + --bar-9-color: var(--alpha-blue); + --bar-10-color: var(--arctic-ice); +/* + NOTE: --font-color also sets the following: + 1. horizontal line
color + 2. lcars-list bullet color + 3. blockquote border color + 4. images with the *border* class + 5. data-cascade text color +*/ + --font-color: var(--beta-blue); + --sub-fonts: .875rem; + --banner-color: var(--radioactive); + --h1-color: var(--arctic-ice); + --h2-color: var(--arctic-ice); + --h3-color: var(--arctic-ice); + --h4-color: var(--arctic-ice); + --light-color: #bdf; + --link-color: var(--beta-blue); + --code-color: var(--alpha-blue); + --nav-width: 240px; + --nav-1-color: var(--alpha-blue); + --nav-2-color: var(--beta-blue); + --nav-3-color: var(--arctic-ice); + --nav-4-color: var(--night-rain); + --button-color: var(--alpha-blue); + --button-color-sidebar: var(--alpha-blue); + --radius-top: 0 0 0 100px; + --radius-bottom: 100px 0 0 0; + --radius-content-top: 0 0 0 44px; + --radius-content-bottom: 44px 0 0 0; + --panel-border: .4rem solid #000; + --bar-border: .4rem solid #000; + --bar-cut-width: 27%; + --divider-height: .75rem; + --lcars-bar-color: var(--night-rain); + --lcars-bar-start-color: var(--beta-blue); + --lcars-bar-end-color: var(--beta-blue); + --lcars-bar-text-color: var(--beta-blue); + +/* Image Frame: */ + + --image-border-color: var(--beta-blue); + --primary-color: var(--night-rain); + --secondary-color: var(--beta-blue); + --accent-color: var(--arctic-snow); + --spacers: .65rem; + --frame-height: 40px; +} + +@media (max-width: 1500px) { + :root { + --lfw: 200px; + --nav-width: 210px; + --bar-height: 20px; + --divider-height: .5rem; + } +} + +@media (max-width: 1300px) { + :root { + font-size: 1.2rem; + --sub-fonts: .9rem; + --lfw: 180px; + --radius-top: 0 0 0 80px; + --radius-bottom: 80px 0 0 0; + --radius-content-top: 0 0 0 30px; + --radius-content-bottom: 30px 0 0 0; + --nav-width: 180px; + } +} + +@media (max-width: 950px) { + :root { + --lfw: 150px; + } +} + +@media (max-width: 750px) { + :root { + --lfw: 120px; + --radius-top: 0 0 0 60px; + --radius-bottom: 60px 0 0 0; + --radius-content-top: 0 0 0 24px; + --radius-content-bottom: 24px 0 0 0; + --bar-height: 16px; + --spacers: .5rem; + --frame-height: 25px; + } +} + +@media (max-width: 525px) { + :root { + --lfw: 62px; + --left-frame-padding: .5rem; + --radius-top: 0 0 0 30px; + --radius-bottom: 30px 0 0 0; + --bar-height: 10px; + --panel-border: .25rem solid black; + --bar-border: .25rem solid black; + --divider-height: .345rem; + } +} + +@media (max-width: 450px) { + :root { + --nav-width: 48%; + } +} + +*, *:after, *:before { + box-sizing: border-box; +} + +* { + margin: 0; + padding: 0; + font: inherit; +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +input, textarea, button, select { + font: inherit; +} + +@font-face { + font-family: 'Antonio'; + font-weight: 400; + src: url('Antonio-Regular.woff2') format('woff2'), + url('Antonio-Regular.woff') format('woff'); +} + +@font-face { + font-family: 'Antonio'; + font-weight: 700; + src: url('Antonio-Bold.woff2') format('woff2'), + url('Antonio-Bold.woff') format('woff') +} + +html { + scroll-behavior: smooth; +} + +body { + display: flex; + padding-top: 10px; + padding-left: 5px; + background-color: black; + font-family: 'Antonio', 'Arial Narrow', 'Avenir Next Condensed', sans-serif; + font-weight: 400; + line-height: 1.5; + color: var(--font-color); +} + +a { + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: .2rem; + color: var(--link-color); +} + +a:hover { + filter: brightness(115%); + animation: none; +} + +a:active { + filter: brightness(80%); + outline: none; +} + +button { + border: none; + outline: none; + word-break: break-all; + color: black; + transition: width 1s; +} + +button:hover { + cursor: pointer; + animation: none; + filter: brightness(115%); + color: black; +} + +button:active { + filter: brightness(85%); +} + +@keyframes colorchange { + 0% {color: var(--night-cloud)} + 25% {color: var(--night-cloud);} + 50% {color: var(--arctic-snow);} + 75% {color: var(--arctic-snow);} + 80% {color: var(--arctic-snow);} + 90% {color: var(--night-cloud);} + 100% {color: var(--night-cloud);} +} + +.wrap-all { + width: 100%; +} + +.wrap { + display: flex; + width: 100%; + padding-left: 5px; + padding-right: 15px; + overflow: hidden; +} + +.scroll-top { + display: none; +} + +.left-frame-top, +.left-frame { + width: var(--lfw); + text-align: right; + font-size: clamp(.875rem, 2vw, 1rem); + line-height: 1.2; + font-weight: bold; + color: black; + transition: width 1s; +} + +.left-frame-top { + background-color: var(--left-frame-top-color); + border-radius: var(--radius-top); +} + +.left-frame-top a, +.left-frame a { + text-decoration: none; + color: black; +} + +.left-frame { + display: flex; + flex-direction: column; + justify-content: space-between; + padding-top: 14vh; + background-color: var(--left-frame-color); + border-radius: var(--radius-bottom); +} + +.left-frame:has(.sidebar-nav) { + padding-top: 10vh; +} + +.panel-2 { + padding-top: .75rem; + padding-right: .75rem; +} + +.right-frame-top { + flex: 1; + position: relative; +} + +.right-frame-top::before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to top right, var(--corner-color-top) 50%, #000 50%); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +.right-frame-top::after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-top); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +@media (max-width: 500px) { + .right-frame-top::before { + bottom: 10px; + } + + .right-frame-top::after { + bottom: 10px; + } +} + +.banner { + padding-bottom: 1rem; + padding-left: 5px; + text-align: right; + text-transform: uppercase; + line-height: 1.1; + font-size: clamp(1.5rem, 1.25rem + 3.5vw, 4rem); + color: var(--banner-color); +} + +.banner a { + color: var(--banner-color); + text-decoration: none; +} + +.data-cascade-button-group { + display: flex; + justify-content: flex-end; + align-items: flex-start; + flex-wrap: wrap; + padding-bottom: .75rem; +} + +.data-cascade-button-group:has(.header-content) { + justify-content: flex-start; +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +.header-content { + flex: 1; + min-height: 184px; + padding-right: 2rem; + padding-left: clamp(20px, 3vw, 50px); +} + +.header-content > *:first-child { + margin-top: 0; +} + +.header-content > *:last-child { + margin-bottom: 0; +} + +/* Data Stream */ + +.data-wrapper { + flex: 1; + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + align-items: flex-end; + max-width: 100%; + height: 164px; + overflow: hidden; + padding-top: 10px; + padding-right: 2rem; + padding-left: clamp(20px, 3vw, 50px); + column-gap: 1rem; + font-size: 1.25rem; +} + +.data-column { + display: grid; + grid-template-columns: 1fr; + line-height: 1; + --dc-row-height: 40px; +} + +.data-bullet { + width: 38px; + height: 22px; + border-radius: 50%; + background-color: var(--font-color); +} + +.dc-row-1, +.dc-row-2, +.dc-row-3, +.dc-row-4 { + display: flex; + align-items: center; + min-height: var(--dc-row-height); +} + +.dc-row-1:has(.data-bullet) { + padding-inline: 1rem; +} + +.dc-row-2:has(.data-bullet) { + padding-inline: 1rem; +} + +.dc-row-3:has(.data-bullet) { + padding-inline: 1rem; +} + +.dc-row-4:has(.data-bullet) { + padding-inline: 1rem; +} + +.darkspace { + min-width: 3rem; + text-align: center; + justify-content: center; +} + +.darkfont { + color: black; +} + +@media (max-width: 1300px) { + .data-wrapper { + height: 130px; + font-size: 1rem; + } + + .data-column { + --dc-row-height: 30px; + } + + .data-bullet { + transform: scale(.8); + } +} + +@media (max-width: 1100px) { + .hide-data { + display: none; + } + + .data-wrapper { + column-gap: .575rem; + padding-right: 1rem; + } +} + +@media (max-width: 740px) { + .data-wrapper { + display: none; + } +} + +/* Navigation & buttons */ + +.lcars-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + margin-block: 1rem; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1 a { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + height: clamp(90px, 11vw, 160px); + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + transition: width 1s; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1-button { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + min-height: clamp(90px, 11vw, 160px); + overflow: hidden; + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav { + display: flex; + flex-wrap: wrap; + align-self: center; + width: calc(var(--nav-width) + var(--nav-width) + 1rem); + justify-content: flex-end; + column-gap: .5rem; + row-gap: .65rem; +} + +@media (max-width: 1500px) { + nav { + column-gap: .375rem; + row-gap: .5rem; + } +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +nav a, +nav button, +.buttons button { + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: flex-end; + width: var(--nav-width); + height: calc(var(--nav-width) / 2.8); + padding-inline: 1.5rem; + padding-bottom: .7rem; + border-radius: 100vmax; + background-color: var(--button-color); + text-align: right; + line-height: 1.175; + text-decoration: none; + text-transform: uppercase; + font-weight: bold; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav a:nth-child(1), +nav button:nth-child(1) { + background-color: var(--nav-1-color); +} + +nav a:nth-child(2), +nav button:nth-child(2) { + background-color: var(--nav-2-color); +} + +nav a:nth-child(3), +nav button:nth-child(3) { + background-color: var(--nav-3-color); +} + +nav a:nth-child(4), +nav button:nth-child(4) { + background-color: var(--nav-4-color); +} + +@media (max-width: 1300px) { + nav { + padding-left: .5rem; + gap: .5rem; + } + + nav button { + padding-bottom: .5rem; + font-size: .875rem; + padding-inline: 1.25rem; + } +} + +@media (max-width: 780px) { + nav { + flex: 1; + } + + .data-cascade-button-group:has(.header-content) > *:nth-child(2) { + flex: none; + } +} + +@media (max-width: 450px) { + nav a, + nav button { + height: 63px; + } +} + +.buttons { + display: flex; + flex-wrap: wrap; + gap: .5rem; + margin-block: 2rem; +} + +.justify-space-between { + justify-content: space-between; +} + +.justify-center { + justify-content: center; +} + +.justify-flex-end { + justify-content: flex-end; +} + +.justify-space-around { + justify-content: space-around; +} + +.justify-space-evenly { + justify-content: space-evenly; +} + +.buttons a, +.buttons button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.sidebar-nav button, +.sidebar-nav a, +.sidebar-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + min-height: 3.75rem; + width: var(--lfw); + background-color: var(--button-color-sidebar); + border-radius: 0; + border-bottom: var(--panel-border); + padding: var(--left-frame-padding); + text-decoration: none; + text-align: right; + word-break: break-all; + text-transform: uppercase; + color: black; +} + +@media (max-width: 1300px) { + .lcars-button, + .buttons a, + .buttons button { + width: 200px; + height: 74px; + } +} + +.panel-button { + display: flex; + justify-content: flex-end; + width: var(--lfw); + border-radius: 0; + padding: var(--left-frame-padding); + border-bottom: var(--panel-border); +} + +.pan-0 /* use this if you're not mimicking an established panel */ { + height: 18vh; + max-height: 240px; + background-color: var(--button-color-sidebar); +} + +.pan-4 { + height: 14vh; + background-color: var(--panel-4-color) !important; +} + +.pan-5 { + height: 30vh; + background-color: var(--panel-5-color) !important; +} + +.pan-7 { + height: 30vh; + background-color: var(--panel-7-color) !important; +} + +.text-bottom { + align-items: flex-end; +} + +#topBtn { + display: none; + position: fixed; + bottom: 0; + z-index: 99; + border-radius: 0; + border-top: var(--panel-border); + border-right: none; + border-bottom: var(--panel-border); + border-left: none; + outline: none; + width: var(--lfw); + padding: var(--left-frame-padding); + padding-bottom: 10vh; + background-color: var(--panel-top-button-color); + text-align: right; + line-height: 1; + font-weight: bold; + text-transform: uppercase; + color: black; + cursor: pointer; +} + +#topBtn:hover { + filter: brightness(115%); +} + +#topBtn:active { + filter: brightness(80%); +} + +@media (max-width: 525px) { + .sidebar-button, + .sidebar-nav a, + .sidebar-nav button, + .panel-button { + font-size: .75rem; + } + + #topBtn { + padding-bottom: 6vh; + } +} + +.bar-panel { + display: flex; + height: var(--bar-height); +} + +.first-bar-panel { + margin-top: 2.5vh; + position: relative; +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-5, +.bar-6, +.bar-7, +.bar-8, +.bar-9, +.bar-10 { + height: var(--bar-height); +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-6, +.bar-7, +.bar-8, +.bar-9 { + border-right: var(--bar-border); +} + +.divider { + display: flex; + height: var(--divider-height); + z-index: 1999; +} + +.block-left { + width: var(--lfw); + height: var(--divider-height); +} + +.block-right { + flex: 1; + height: var(--divider-height); + position: relative; +} + +.block-row { + display: flex; + width: 100%; + height: var(--divider-height); + padding-right: .4rem; + padding-left: 1px; +} + +.bar-11 { + height: var(--divider-height); + width: var(--bar-1-6-width); +} + +.bar-12 { + height: var(--divider-height); + width: var(--bar-2-7-width); + +} + +.bar-13 { + height: var(--divider-height); + width: var(--bar-3-8-width); +} +.bar-14 { + flex: 1; + height: var(--divider-height); + z-index: 1999; +} + +.bar-1 { + width: var(--bar-1-6-width); + background-color: var(--bar-1-color); +} + +.bar-2 { + width: var(--bar-2-7-width); + background-color: var(--bar-2-color); +} + +.bar-3 { + width: var(--bar-3-8-width); + background-color: var(--bar-3-color); +} + +.bar-4 { + flex: 1; + position: relative; + background-color: var(--bar-4-color); +} + +.bar-5 { + width: var(--bar-5-10-width); + background-color: var(--bar-5-color); +} + +.bar-6 { + width: var(--bar-1-6-width); + background-color: var(--bar-6-color); +} + +.bar-7 { + width: var(--bar-2-7-width); + background-color: var(--bar-7-color); +} + +.bar-8 { + width: var(--bar-3-8-width); + background-color: var(--bar-8-color); +} + +.bar-9 { + flex: 1; + position: relative; + background-color: var(--bar-9-color); +} + +.bar-4::after { + content: ""; + display: block; + width: var(--bar-cut-width); + height: 48%; + background-color: black; + border-radius: 0 8px 0 0; + position: absolute; + left: 0; + bottom: 0; +} + +.bar-9::after { + content: ""; + display: block; + width: var(--bar-cut-width); + height: 48%; + background-color: black; + border-radius: 0 0 8px 0; + position: absolute; + left: 0; + top: 0; +} + +.bar-10 { + width: var(--bar-5-10-width); + background-color: var(--bar-10-color); +} + +/* Bottom half */ + +#gap { + margin-top: var(--divider-height); +} + +.panel-3, +.panel-4, +.panel-5 { + border-bottom: var(--panel-border); +} + +.panel-2, +.panel-3, +.panel-4, +.panel-5, +.panel-6, +.panel-7 { + padding: var(--left-frame-padding); +} + +.panel-4 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + min-height: 14vh; + background-color: var(--panel-4-color); +} + +.panel-5 { + height: 30vh; + background-color: var(--panel-5-color); +} + +/* Note: panel-6 height is fluid and governed by the amount of content on the page. Background color is inherited from :root --left-frame-color */ + +.panel-6 { + min-height: 15vh; +} + +.panel-7 { + height: 30vh; + border-top: var(--panel-border); + background-color: var(--panel-7-color); +} + +.right-frame { + flex: 1; + position: relative; +} + +.right-frame::before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to bottom right, var(--corner-color-bottom) 50%, #000 50%); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +.right-frame::after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-bottom); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +main { + padding-top: 1.5rem; + padding-bottom: .5rem; + padding-left: clamp(20px, 3vw, 50px); +} + +main > *:first-child, +article > *:first-child { + margin-top: 0; +} + +main:has(.floor-heading) > *:nth-child(2) { + margin-top: 0; +} + +.flexbox { + display: flex; + gap: 1.2rem; + flex-wrap: wrap; +} + +.col { + flex: 1 1 360px; +} + +.col > *:first-child { + margin-top: 0; +} + +h1, h2, h3, h4 { + margin-block: 1.75rem; + font-weight: normal; + line-height: 1.2; + text-transform: uppercase; + text-box: trim-both cap alphabetic; +} + +h1 { + font-size: clamp(1.5rem, 1.25rem + 3.5vw, 4rem); + text-align: right; + color: var(--h1-color); +} + +h2 { + font-size: clamp(1.4rem, 1.1rem + 2.25vw, 2.3rem); + color: var(--h2-color); +} + +h3 { + font-size: clamp(1.15rem, 1.05rem + 1.25vw, 1.875rem); + color: var(--h3-color); +} + +h4 { + font-size: clamp(1.025rem, 1rem + 1.125vw, 1.575rem); + color: var(--h4-color); +} + +.floor-heading { + display: flex; + justify-content: flex-end; + width: 100%; + position: fixed; + left: 50%; + transform: translate(-50%, 0); + bottom: 10px; + z-index:4; +} + +.floor-heading > * { + margin-block: 0; + width: fit-content; + padding: .5rem; + background-color: black; +} + +p { + margin-block: 1.75rem; + text-box: trim-both cap alphabetic; +} + +.caption { + margin-top: -1rem; + text-align: center; + font-size: var(--sub-fonts); +} + +.indent { + padding-left: 1.5rem; +} + +.postmeta { + margin-block: 1.25rem; + text-align: right; + font-size: clamp(1.2rem, 0.88rem + 1.28vw, 1.6rem); + line-height: 1.2; + text-transform: uppercase; +} + +article h1 { + margin-bottom: 0; +} + +hr { + margin-block: 1.5rem; + height: 6px; + border: none; + background-color: var(--font-color); + border-radius: 3px; +} + +blockquote { + margin-block: 1.75rem; + margin-left: 1.5rem; + padding-block: .25rem; + padding-left: 1.5rem; + position: relative; + text-box: trim-both cap alphabetic; +} + +blockquote::before { + content: ''; + display: block; + width: 10px; + height: 100%; + background-color: var(--font-color); + border-radius: 5px; + position: absolute; + left: 0; + top: 0; +} + +blockquote > *:first-child { + margin-top: 0; +} + +blockquote > * { + margin-bottom: 0; +} + +.flush { + margin-top: -1rem; +} + +.nomar { + margin-block: 0 !important; +} + +.go-center { + text-align: center !important; +} + +.go-right { + text-align: right !important; +} + +.go-left { + text-align: left !important; +} + +.go-big { + font-size: clamp(1.2rem, 1rem + 1vw, 1.275rem); +} + +.uppercase { + text-transform: uppercase; +} + +.strike { + text-decoration: line-through; + text-decoration-thickness: .15rem; +} + +.now { + white-space: nowrap; +} + +.big-sky { + margin-top: 5rem; +} + +.smoke-glass { + opacity: .35; +} + +strong { + font-weight: bold; +} + +code { + font-family: monospace; + font-size: .9rem; + color: var(--code-color); +} + +.code { + width: 100%; + min-height: 5rem; + padding-block: .5rem; + padding-inline: 1rem; + background-color: #232323; + border-color: #4c4c4c; + tab-size: 4; + font-family: monospace; + font-size: .85rem; + color: #dcdcdc; +} + +@keyframes blink { + 0% {opacity: 0} + 49%{opacity: 0} + 50% {opacity: 1} +} + +.blink-slow { + animation: blink 3500ms infinite; + animation-delay: 1s; +} + +.blink { + animation: blink 2s infinite; + animation-delay: 1s; +} + +.blink-fast { + animation: blink 1s infinite; + animation-delay: 1s; +} + +@keyframes pulse { + 0% {filter: brightness(1.0)} + 50% {filter: brightness(.25)} +} + +.pulse { + animation: pulse 2300ms infinite; +} + +.pulse-rate-high { + animation: pulse 1s infinite; +} + +.accordion-wrapper { + display: block; + margin: 1.75rem auto; + width: 100%; +} + +.limit-width { + max-width: 1240px; +} + +.accordion { + display: flex; + align-items: center; + min-height: 3rem; + width: 100%; + padding-right: 2.75rem; + padding-left: 1rem; + border-radius: 100vmax; + background-color: var(--alpha-blue); + border-left: solid 3rem var(--night-rain); + text-align: left; + font-size: 1.25rem; + color: black; + cursor: pointer; + transition: 0.4s ease; + position: relative; +} + +.active, .accordion:hover { + background-color: var(--beta-blue); + border-left-color: var(--radioactive); + filter: none; +} + +.accordion:before { + content: ''; + display: block; + width: .5rem; + height: 4rem; + background-color: black; + position: absolute; + top: 0; + left: 0; +} + +.accordion:after { + display: block; + content: '\276F'; + position: absolute; + right: 1.5rem; + top: 21%; + transform: rotate(90deg); + transition: 0.4s; + font-weight: bold; + color: black; +} + +.active:after { + content: "\276F"; + transform:rotate(-90deg); + transition: 0.4s ease; +} + +.accordionContent { + padding-block: .5rem; + padding-inline: 3.5rem; + max-height: 0; + overflow: hidden; + transition: max-height 0.25s ease-out; +} + +.accordionContent ul { + margin-left: 0; +} + +@media (max-width: 525px) { + .accordion { + min-height: 2.5rem; + font-size: 1rem; + border-left-width: 2.5rem; + } +} + +/* Images */ + +.pics-right { + float: right; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +.pics-left { + float: left; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +@media (max-width: 1060px) { + .pics-right, + .pics-left { + float: none; + margin-inline: auto; + } + + .pics-right img, + .pics-left img { + margin-inline: auto; + } +} + +.pics { + margin-block: 2rem; + margin-inline: auto; +} + +.border { + border: 2px solid var(--font-color); +} + +.lcars-list { + margin-block: 1.15rem; + margin-left: 2rem; + list-style: none; +} + +.lcars-list li { + position: relative; + padding-block: .45rem; + padding-left: 2.25rem; + text-box: trim-both cap alphabetic; +} + +.lcars-list li::before { + content: ''; + display: block; + width: 34px; + height: 18px; + border-radius: 50%; + background-color: var(--font-color); + position: absolute; + top: .45rem; + left: 0; +} + +@media (max-width: 650px) { + + .lcars-list { + margin-left: .5rem; + } + + .lcars-list li::before { + transform: scale(90%); + } +} + +.lcars-bar { + margin-block: 1.75rem; + height: clamp(15px, 2vh, 25px); + background: transparent; + border-right: clamp(15px, 2vh, 25px) solid var(--lcars-bar-end-color); + border-left: clamp(15px, 2vh, 25px) solid var(--lcars-bar-start-color); + border-radius: 100vmax; + position: relative; +} + +.lcars-bar::after { + content: ''; + display: block; + height: clamp(15px, 2vh, 25px); + width: 100%; + background-color: var(--lcars-bar-color); + border-right: .8vh solid black; + border-left: .8vh solid black; + position: absolute; + top: 0; + left: 0; +} + +.lcars-text-bar { + display: flex; + position: relative; + height: clamp(16px, 4vh, 41px); + margin-block: 2.75rem; + overflow: visible; + border-radius: 100vmax; + background-color: var(--lcars-bar-color); + border-right: clamp(16px, 4vh, 43px) solid var(--lcars-bar-end-color); + border-left: clamp(16px, 4vh, 43px) solid var(--lcars-bar-start-color); +} + +.the-end { + justify-content: flex-end; +} + +.lcars-text-bar h2, +.lcars-text-bar h3, +.lcars-text-bar h4, +.lcars-text-bar span { + margin-block: 0; + background-color: black; + height: clamp(20px, 5.5vh, 60px); /* Setting height is a Firefox fix */ + overflow: visible; + border-top: 1px solid black; + padding-inline: 1vh; + font-size: clamp(17px, 4.5vh, 46px); + line-height: 1; + text-transform: uppercase; + color: var(--lcars-bar-text-color); + z-index: 1; + text-box: trim-both cap alphabetic; +} + +.lcars-text-bar::before { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} + +.lcars-text-bar::after { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + right: 0; + overflow: hidden; +} + +/* LCARS Image Frame */ + +.image-frame { + margin: 2.75rem auto; + width: fit-content; + background: linear-gradient(var(--primary-color) 56%, var(--secondary-color) 44%); + border-radius: 50px 25px 0 50px; + position: relative; +} + +.image-frame::before { + content: ''; + display: block; + width: 40px; + height: 40px; + background-color: black; + position: absolute; + right: 0; + top: 0; +} + +.image-frame::after { + content: ''; + display: block; + border-top: var(--spacers) solid black; + border-bottom: var(--spacers) solid black; + width: 45px; + height: 80px; + background-color: var(--secondary-color); + position: absolute; + left: 0; + top: 56%; +} + +.imgf-title { + display: flex; + justify-content: flex-end; + height: 40px; + border-right: 40px solid var(--secondary-color); + border-radius: 25px 100vh 100vh 0; + position: relative; + z-index: 1; + text-align: right; +} + +.h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + border-right: var(--spacers) solid black; +} + +.imgf-title h4 { + margin-block: 0; + width: fit-content; + background-color: black; + padding-left: var(--spacers); + font-size: 2.05rem; + color: var(--title-color); + line-height: 40px; + text-transform: uppercase; +} + +.imgf-image-body { + margin-left: 45px; + background-color: black; + width: fit-content; + padding: 1rem; + border-radius: 28px 0 0 28px; +} + +.image-holder { + width: fit-content; + padding: 1rem; + border: 2px solid var(--image-border-color); + border-radius: 20px; +} + +.imgf-base { + display: grid; + grid-template-columns: 20% 13% 35px 15% 1fr; + margin-left: 80px; + border-left: var(--spacers) solid black; +} + +.imgf-block-1 { + height: var(--frame-height); + background-color: var(--accent-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-2 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-3 { + height: var(--frame-height); + background-color: black; + border-right: 10px solid var(--secondary-color); + border-left: 10px solid var(--accent-color); +} + +.imgf-block-4 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-left: var(--spacers) solid black; +} + +.imgf-block-5 { + height: var(--frame-height); + background-color: black; +} + +@media (max-width: 750px) { + + .image-frame { + border-radius: 40px 25px 0 40px; + } + + .image-frame::after { + width: 25px; + height: 60px; + top: 50%; + } + + .imgf-title { + height: 25px; + border-right: 24px solid var(--secondary-color); + } + + .h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + } + + .imgf-title h4 { + font-size: 1.45rem; + } + + .imgf-image-body { + margin-left: 25px; + padding: .75rem; + border-radius: 20px 0 0 20px; + } + + .image-holder { + padding: .75rem; + border-radius: 10px; + } +} + +/* Color Styles */ + +.font-alpha-blue { + color: var(--alpha-blue) !important; +} + +.button-alpha-blue, +.background-alpha-blue, +.bullet-alpha-blue::before { + background-color: var(--alpha-blue) !important; +} + +.font-arctic-ice { + color: var(--arctic-ice) !important; +} + +.button-arctic-ice, +.background-arctic-ice, +.bullet-arctic-ice::before { + background-color: var(--arctic-ice) !important; +} + +.font-arctic-snow { + color: var(--arctic-snow) !important; +} + +.button-arctic-snow, +.background-snow, +.bullet-arctic-snow::before { + background-color: var(--arctic-snow) !important; +} + +.font-radioactive { + color: var(--radioactive) !important; +} + +.button-radioactive, +.background-radioactive, +.bullet-radioactive::before { + background-color: var(--radioactive) !important; +} + +.font-beta-blue { + color: var(--beta-blue) !important; +} + +.button-beta-blue, +.background-beta-blue, +.bullet-beta-blue::before { + background-color: var(--beta-blue) !important; +} + +.font-night-cloud { + color: var(--night-cloud) !important; +} + +.button-night-cloud, +.background-night-cloud, +.bullet-night-cloud::before { + background-color: var(--night-cloud) !important; +} + +.font-night-rain { + color: var(--night-rain) !important; +} + +.button-night-rain, +.background-night-rain, +.bullet-night-rain::before { + background-color: var(--night-rain) !important; +} + +.font-sunset-red { + color: var(--sunset-red) !important; +} + +.button-sunset-red, +.background-sunset-red, +.bullet-sunset-red::before { + background-color: var(--sunset-red) !important; +} + +/* Footer */ + +footer { + margin-top: 2.5vw; + padding-bottom: 3rem; + padding-left: clamp(20px, 3vw, 50px); + font-size: .875rem; +} + +.headtrim { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + top: 0; + left: 0; + z-index: 999; +} + +.baseboard { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + bottom: 0; + left: 0; + z-index: 999; +} + +/* Grouped @media */ + +@media (max-width: 650px) { + + .first-bar-panel { + margin-top: .75rem; + } + + .bar-4::before { + height: 5px; + top: -12px; + } + + .bar-9::before { + height: 5px; + bottom: -12px; + } +} + +@media (max-width: 525px) { + + body { + padding: .25rem; + } + + .baseboard { + display: none; + } + + .wrap { + padding-left: 0; + padding-right: .25rem; + } + + .left-frame { + padding-top: 8vh; + } + + .divider { + padding-right: 10px; + } + + .block-row { + padding-right: 0; + padding-left: .25rem; + } + + .floor-heading { + bottom: 0; + } + + .hop { + display: none; + } + + blockquote { + margin-left: .75rem; + } +} + +@-moz-document url-prefix() { + + main { + padding-top: clamp(1rem, 4vw, 30px); + } + + h1, h2, h3, h4, p { + margin-block: 1.15rem; + } + + .postmeta { + margin-top: .75rem; + } + + .lcars-text-bar h2, + .lcars-text-bar h3, + .lcars-text-bar h4, + .lcars-text-bar span { + position: absolute; + top: -.7vh; + } +} \ No newline at end of file diff --git a/lcars_v4/frontend/assets/lower-decks.css b/lcars_v4/frontend/assets/lower-decks.css new file mode 100644 index 0000000..32c9827 --- /dev/null +++ b/lcars_v4/frontend/assets/lower-decks.css @@ -0,0 +1,1856 @@ +@charset "utf-8"; + +/* + + CSS Document + LCARS Lower Decks Theme + Version 24.2 + By Jim Robertus www.thelcars.com + Modified: 2025 Jul 27 + +*/ + +:root { + font-size: 1.375rem; + color-scheme: dark; + --lfw: 240px; + --butter: #fec; + --daybreak: #f91; + --harvestgold: #fa4; + --honey: #fc9; + --october-sunset: #f40; + --orange: #f70; + --rich-pumpkin: #c50; + --left-frame-top-color: var(--october-sunset); + --left-frame-color: var(--october-sunset); /* panel-6 inherits this color */ + --left-frame-padding: .75rem; + --corner-color-top: var(--october-sunset); + --corner-color-bottom: var(--october-sunset); + --panel-1-color: var(--orange); + --panel-4-color: var(--orange); + --panel-5-color: var(--harvestgold); + --panel-7-color: var(--harvestgold); + --panel-top-button-color: var(--honey); + --bar-height: 28px; + --bar-1-6-width: 10%; + --bar-2-7-width: 12%; + --bar-3-8-width: 17%; + --bar-5-10-width: 5%; + --bar-1-color: var(--october-sunset); + --bar-2-color: var(--orange); + --bar-3-color: var(--honey); + --bar-4-color: var(--harvestgold); + --bar-5-color: var(--october-sunset); + --bar-6-color: var(--october-sunset); + --bar-7-color: var(--orange); + --bar-8-color: var(--honey); + --bar-9-color: var(--harvestgold); + --bar-10-color: var(--october-sunset); +/* + NOTE: --font-color also sets the following: + 1. horizontal line
color + 2. lcars-list bullet color + 3. blockquote border color + 4. images with the *border* class border color +*/ + --font-color: var(--daybreak); + --sub-fonts: .875rem; + --banner-color: var(--honey); + --data-cascade-color: var(--orange); + --light-color: white; + --h1-color: var(--honey); + --h2-color: var(--honey); + --h3-color: var(--honey); + --h4-color: var(--honey); + --light-color: var(--butter); + --link-color: var(--october-sunset); + --code-color: var(--october-sunset); + --nav-width: 240px; + --nav-1-color: var(--honey); + --nav-2-color: var(--harvestgold); + --nav-3-color: var(--orange); + --nav-4-color: var(--october-sunset); + --button-color: var(--harvestgold); + --button-color-sidebar: var(--october-sunset); + --radius-top: 0 0 0 100px; + --radius-bottom: 100px 0 0 0; + --radius-content-top: 0 0 0 44px; + --radius-content-bottom: 44px 0 0 0; + --panel-border: .4rem solid black; + --bar-border: .4rem solid black; + --bar-cut-width: 32%; + --bar-cut-out-width: 40%; + --bar-cut-out-top-color: var(--october-sunset); + --bar-cut-out-bottom-color: var(--october-sunset); + --divider-height: .75rem; + --lcars-bar-color: var(--october-sunset); + --lcars-bar-start-color: var(--harvestgold); + --lcars-bar-end-color: var(--harvestgold); + --lcars-bar-text-color: var(--harvestgold); + +/* Image Frame */ + + --image-border-color: var(--honey); + --primary-color: var(--orange); + --secondary-color: var(--harvestgold); + --accent-color: var(--honey); + --spacers: .65rem; + --frame-height: 40px; +} + +@media (max-width: 1500px) { + :root { + --lfw: 200px; + --nav-width: 210px; + --bar-height: 20px; + --divider-height: .5rem; + } +} + +@media (max-width: 1300px) { + :root { + font-size: 1.2rem; + --sub-fonts: .9rem; + --lfw: 180px; + --radius-top: 0 0 0 80px; + --radius-bottom: 80px 0 0 0; + --radius-content-top: 0 0 0 30px; + --radius-content-bottom: 30px 0 0 0; + --nav-width: 180px; + } +} + +@media (max-width: 950px) { + :root { + --lfw: 150px; + } +} + +@media (max-width: 750px) { + :root { + --lfw: 120px; + --radius-top: 0 0 0 60px; + --radius-bottom: 60px 0 0 0; + --radius-content-top: 0 0 0 24px; + --radius-content-bottom: 24px 0 0 0; + --bar-height: 16px; + --spacers: .5rem; + --frame-height: 25px; + } +} + +@media (max-width: 525px) { + :root { + --lfw: 62px; + --left-frame-padding: .5rem; + --radius-top: 0 0 0 30px; + --radius-bottom: 30px 0 0 0; + --bar-height: 10px; + --panel-border: .25rem solid black; + --bar-border: .25rem solid black; + --divider-height: .345rem; + } +} + +@media (max-width: 450px) { + :root { + --nav-width: 48%; + } +} + +*, *:after, *:before { + box-sizing: border-box; +} + +* { + margin: 0; + padding: 0; + font: inherit; +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +input, textarea, button, select { + font: inherit; +} + +@font-face { + font-family: 'Antonio'; + font-weight: 400; + src: url('Antonio-Regular.woff2') format('woff2'), + url('Antonio-Regular.woff') format('woff'); +} + +@font-face { + font-family: 'Antonio'; + font-weight: 700; + src: url('Antonio-Bold.woff2') format('woff2'), + url('Antonio-Bold.woff') format('woff') +} + +html { + scroll-behavior: smooth; +} + +body { + display: flex; + padding-top: 10px; + padding-left: 5px; + background-color: black; + font-family: 'Antonio', 'Arial Narrow', 'Avenir Next Condensed', sans-serif; + font-weight: 400; + line-height: 1.5; + color: var(--font-color); +} + +a { + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: .2rem; + color: var(--link-color); +} + +a:hover { + filter: brightness(115%); + animation: none; +} + +a:active { + filter: brightness(80%); + outline: none; +} + +button { + border: none; + outline: none; + color: black; + transition: width 1s; +} + +button:hover { + cursor: pointer; + animation: none; + filter: brightness(115%); + color: black; +} + +button:active { + filter: brightness(85%); +} + +.wrap-all { + width: 100%; +} + +.wrap { + display: flex; + margin-inline: auto; + padding-left: 5px; + padding-right: 15px; + overflow: hidden; +} + +.divider { + display: flex; + width: 100%; + flex-wrap: nowrap; + height: var(--divider-height); +} + +.scroll-top { + display: none; +} + +.left-frame-top, +.left-frame { + width: var(--lfw); + text-align: right; + font-size: clamp(.875rem, 2vw, 1rem); + line-height: 1.2; + font-weight: bold; + color: black; + transition: width 1s; +} + +.left-frame-top { + background-color: var(--left-frame-top-color); + border-radius: var(--radius-top); +} + +.left-frame-top a, +.left-frame a { + text-decoration: none; + color: black; +} + +.left-frame { + display: flex; + flex-direction: column; + justify-content: space-between; + padding-top: 19vh; + background-color: var(--left-frame-color); + border-radius: var(--radius-bottom); +} + +.left-frame:has(.sidebar-nav) { + padding-top: 10vh; +} + +.left-frame:has(button) { + padding-top: 10vh; +} + +@keyframes panel-1-color-change { + 0%, + 49.99% { + background-color: var(--orange); + } + 50%, + 100% { + background-color: var(--butter); + } +} + +.right-frame-top { + flex: 1; + align-content: flex-end; + position: relative; +} + +.right-frame-top::before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to top right, var(--corner-color-top) 50%, black 50%); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +.right-frame-top::after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-top); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +.banner { + padding-bottom: 1rem; + padding-left: 5px; + text-align: right; + text-transform: uppercase; + line-height: 1.1; + font-size: clamp(1.25rem, 0.75rem + 4vw, 3.75rem); + color: var(--banner-color); +} + +.banner a { + color: var(--banner-color); + text-decoration: none; +} + +.data-cascade-button-group { + display: flex; + justify-content: flex-end; + align-items: flex-start; + flex-wrap: wrap; + padding-bottom: .75rem; +} + +.data-cascade-button-group:has(.header-content) { + justify-content: flex-start; +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +.header-content { + flex: 1; + min-height: 184px; + padding-right: 2rem; + padding-left: clamp(20px, 3vw, 50px); +} + +.header-content > *:first-child { + margin-top: 0; +} + +.header-content > *:last-child { + margin-bottom: 0; +} + +/* Data Stream */ + +.data-wrapper { + flex: 1; + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + align-items: flex-end; + max-width: 100%; + height: 184px; + overflow: hidden; + padding-top: 10px; + padding-right: 2rem; + padding-left: clamp(20px, 3vw, 50px); + column-gap: .5rem; + font-size: 1.25rem; +} + +.data-column { + display: grid; + grid-template-columns: 1fr; + text-align: right; + line-height: 1; + --dc-row-height: 45px; +} + +@media (max-width: 1300px) { + .data-wrapper { + height: 150px; + font-size: 1rem; + } + + .data-column { + --dc-row-height: 35px; + } + +} + +@media (max-width: 740px) { + .data-wrapper { + display: none; + } +} + +.dc-row-1 { + min-height: var(--dc-row-height); + color: var(--october-sunset); +} + +.dc-row-2 { + min-height: var(--dc-row-height); + color: var(--honey); +} + +.dc-row-3 { + min-height: var(--dc-row-height); + color: var(--october-sunset); +} + +.dc-row-4 { + min-height: var(--dc-row-height); + color: var(--harvestgold); +} + +.darkspace { + min-width: 4rem; + text-align: center; + color: var(--october-sunset); +} + +.darkfont { + color: black; +} + +@media (max-width: 1100px) { + .hide-data { + display: none; + } + + .data-wrapper { + padding-right: 1rem; + } +} + +/* Navigation & buttons */ + +.lcars-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + margin-block: 1rem; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1 a { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + height: clamp(90px, 11vw, 160px); + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + transition: width 1s; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1-button { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + min-height: clamp(90px, 11vw, 160px); + overflow: hidden; + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav { + display: flex; + flex-wrap: wrap; + align-self: center; + width: calc(var(--nav-width) + var(--nav-width) + 1rem); + justify-content: flex-end; + column-gap: .5rem; + row-gap: .65rem; +} + +@media (max-width: 1500px) { + nav { + column-gap: .375rem; + row-gap: .5rem; + } +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +nav a, +nav button, +.buttons button { + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: flex-end; + width: var(--nav-width); + height: calc(var(--nav-width) / 2.8); + padding-inline: 1.5rem; + padding-bottom: .7rem; + border-radius: 100vmax; + background-color: var(--button-color); + text-align: right; + line-height: 1.175; + text-decoration: none; + text-transform: uppercase; + font-weight: bold; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav a:nth-child(1), +nav button:nth-child(1) { + background-color: var(--nav-1-color); +} + +nav a:nth-child(2), +nav button:nth-child(2) { + background-color: var(--nav-2-color); +} + +nav a:nth-child(3), +nav button:nth-child(3) { + background-color: var(--nav-3-color); +} + +nav a:nth-child(4), +nav button:nth-child(4) { + background-color: var(--nav-4-color); +} + +@media (max-width: 1300px) { + nav { + padding-left: .5rem; + gap: .5rem; + } + + nav button { + padding-bottom: .5rem; + font-size: .875rem; + padding-inline: 1.25rem; + } +} + +@media (max-width: 780px) { + nav { + flex: 1; + } + + .data-cascade-button-group:has(.header-content) > *:nth-child(2) { + flex: none; + } +} + +@media (max-width: 450px) { + nav a, + nav button { + height: 63px; + } +} + +.buttons { + display: flex; + flex-wrap: wrap; + gap: .5rem; + margin-block: 2rem; +} + +.justify-space-between { + justify-content: space-between; +} + +.justify-center { + justify-content: center; +} + +.justify-flex-end { + justify-content: flex-end; +} + +.justify-space-around { + justify-content: space-around; +} + +.justify-space-evenly { + justify-content: space-evenly; +} + +.buttons a, +.buttons button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.sidebar-nav button, +.sidebar-nav a, +.sidebar-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + min-height: 3.75rem; + width: var(--lfw); + background-color: var(--button-color-sidebar); + border-radius: 0; + border-bottom: var(--panel-border); + padding: var(--left-frame-padding); + text-decoration: none; + text-align: right; + word-break: break-all; + text-transform: uppercase; + color: black; +} + +@media (max-width: 1300px) { + .lcars-button, + .buttons a, + .buttons button { + width: 200px; + height: 74px; + } +} + +.panel-button { + display: flex; + justify-content: flex-end; + width: var(--lfw); + border-radius: 0; + padding: var(--left-frame-padding); + border-bottom: var(--panel-border); +} + +.pan-0 /* use this if you're not mimicking an established panel */ { + height: 18vh; + max-height: 240px; + background-color: var(--button-color-sidebar); +} + +.pan-4 { + height: 14vh; + background-color: var(--panel-4-color) !important; +} + +.pan-5 { + height: 30vh; + background-color: var(--panel-5-color) !important; +} + +.pan-7 { + height: 30vh; + background-color: var(--panel-7-color) !important; +} + +.text-bottom { + align-items: flex-end; +} + +#topBtn { + display: none; + position: fixed; + bottom: 0; + z-index: 99; + border-radius: 0; + border-top: var(--panel-border); + border-right: none; + border-bottom: var(--panel-border); + border-left: none; + outline: none; + width: var(--lfw); + padding: var(--left-frame-padding); + padding-bottom: 10vh; + background-color: var(--panel-top-button-color); + text-align: right; + line-height: 1; + font-weight: bold; + text-transform: uppercase; + color: black; + cursor: pointer; +} + +#topBtn:hover { + filter: brightness(115%); +} + +#topBtn:active { + filter: brightness(80%); +} + +@media (max-width: 525px) { + .sidebar-button, + .sidebar-nav a, + .sidebar-nav button, + .panel-button { + font-size: .75rem; + } + + #topBtn { + padding-bottom: 6vh; + } +} + +zack { + +} + +.bar-panel { + display: flex; + height: var(--bar-height); +} + +.first-bar-panel { + margin-top: 2.5vh; + position: relative; +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-5, +.bar-6, +.bar-7, +.bar-9, +.bar-10 { + height: var(--bar-height); +} + +.bar-1, +.bar-2, +.bar-3, +.bar-6, +.bar-7, +.bar-8 { + border-right: var(--bar-border); +} + +.bar-5, +.bar-10 { + border-left: var(--bar-border); +} + +.bar-1 { + width: var(--bar-1-6-width); + background-color: var(--bar-1-color); +} + +.bar-2 { + width: var(--bar-2-7-width); + background-color: var(--bar-2-color); +} + +.bar-3 { + width: var(--bar-3-8-width); + background-color: var(--bar-3-color); +} + +.bar-4 { + flex: 1; + position: relative; + background-color: var(--bar-4-color); + z-index: -1; +} + +.bar-5 { + width: var(--bar-5-10-width); + background-color: var(--bar-5-color); +} + +.bar-6 { + width: var(--bar-1-6-width); + background-color: var(--bar-6-color); +} + +.bar-7 { + width: var(--bar-2-7-width); + background-color: var(--bar-7-color); +} + +.bar-8 { + width: var(--bar-3-8-width); + background-color: var(--bar-8-color); +} + +.bar-9 { + flex: 1; + position: relative; + background-color: var(--bar-9-color); + z-index: -1; +} + +.bar-4::before { + content: ''; + display: block; + width: var(--bar-cut-out-width); + height: 8px; + background-color: var(--bar-cut-out-top-color); + position: absolute; + top: -22px; + left: 0; +} + +.bar-4::after { + content: ""; + display: block; + width: var(--bar-cut-width); + height: 48%; + background-color: black; + border-radius: 0 8px 0 0; + position: absolute; + left: 0; + bottom: 0; + z-index: -1; +} + +.bar-9::before { + content: ''; + display: block; + width: var(--bar-cut-out-width); + height: 8px; + background-color: var(--bar-cut-out-bottom-color); + position: absolute; + bottom: -22px; + left: 0; +} + +.bar-9::after { + content: ""; + display: block; + width: var(--bar-cut-width); + height: 48%; + background-color: black; + border-radius: 0 0 8px 0; + position: absolute; + left: 0; + top: 0; + z-index: -1; +} + +.bar-10 { + width: var(--bar-5-10-width); + background-color: var(--bar-10-color); +} + +/* Bottom half */ + +#gap { + margin-top: var(--divider-height); +} + +.panel-3, +.panel-4, +.panel-5 { + border-bottom: var(--panel-border); +} + +.panel-2, +.panel-3, +.panel-4, +.panel-5, +.panel-6, +.panel-7 { + padding: var(--left-frame-padding); +} + +.panel-4 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + min-height: 14vh; + background-color: var(--panel-4-color); +} + +.panel-5 { + height: 30vh; + background-color: var(--panel-5-color); +} + +/* Note: panel-6 height is fluid and governed by the amount of content on the page. Background color is inherited from :root --left-frame-color */ + +.panel-6 { + min-height: 15vh; +} + +.panel-7 { + height: 30vh; + border-top: var(--panel-border); + background-color: var(--panel-7-color); +} + +.right-frame { + flex: 1; + position: relative; +} + +.right-frame::before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to bottom right, var(--corner-color-bottom) 50%, #000 50%); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +.right-frame::after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-bottom); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +main { + padding-top: clamp(1.5rem, 5vw, 60px); + padding-bottom: .5rem; + padding-left: clamp(20px, 3vw, 50px); +} + +main > *:first-child, +article > *:first-child { + margin-top: 0; +} + +main:has(.floor-heading) > *:nth-child(2) { + margin-top: 0; +} + +.flexbox { + display: flex; + gap: 1.2rem; + flex-wrap: wrap; +} + +.col { + flex: 1 1 360px; +} + +.col > *:first-child { + margin-top: 0; +} + +h1, h2, h3, h4 { + margin-block: 1.75rem; + font-weight: normal; + line-height: 1.2; + text-transform: uppercase; + text-box: trim-both cap alphabetic; +} + +h1 { + font-size: clamp(1.5rem, 1.25rem + 3.5vw, 4rem); + text-align: right; + color: var(--h1-color); +} + +h2 { + font-size: clamp(1.4rem, 1.1rem + 2.25vw, 2.3rem); + color: var(--h2-color); +} + +h3 { + font-size: clamp(1.15rem, 1.05rem + 1.25vw, 1.875rem); + color: var(--h3-color); +} + +h4 { + font-size: clamp(1.025rem, 1rem + 1.125vw, 1.575rem); + color: var(--h4-color); +} + +.floor-heading { + display: flex; + justify-content: flex-end; + width: 100%; + position: fixed; + left: 50%; + transform: translate(-50%, 0); + bottom: 10px; + z-index:4; +} + +.floor-heading > * { + margin-block: 0; + width: fit-content; + padding-inline: .5rem; + padding-bottom: .5rem; + background-color: black; +} + +p { + margin-block: 1.75rem; + text-box: trim-both cap alphabetic; +} + +.caption { + margin-top: -1rem; + text-align: center; + font-size: var(--sub-fonts); +} + +.indent { + padding-left: 1.5rem; +} + +.postmeta { + margin-block: 1.25rem; + text-align: right; + font-size: clamp(1.2rem, 0.88rem + 1.28vw, 1.6rem); + line-height: 1.2; + text-transform: uppercase; +} + +article h1 { + margin-bottom: 0; +} + +code { + font-family: monospace; + font-size: .9rem; + color: var(--code-color); +} + +.code { + width: 100%; + min-height: 5rem; + padding-block: .5rem; + padding-inline: 1rem; + background-color: #232323; + border-color: #4c4c4c; + tab-size: 4; + font-family: monospace; + font-size: .85rem; + color: #dcdcdc; +} + +hr { + margin-block: 1.5rem; + height: 6px; + border: none; + background-color: var(--font-color); + border-radius: 3px; +} + +blockquote { + margin-block: 1.75rem; + margin-left: 1.5rem; + padding-block: .25rem; + padding-left: 1.5rem; + position: relative; + text-box: trim-both cap alphabetic; +} + +blockquote::before { + content: ''; + display: block; + width: 10px; + height: 100%; + background-color: var(--font-color); + border-radius: 5px; + position: absolute; + left: 0; + top: 0; +} + +blockquote > *:first-child { + margin-top: 0; +} + +blockquote > * { + margin-bottom: 0; +} + +.flush { + margin-top: -1rem; +} + +.nomar { + margin-block: 0 !important; +} + +.go-center { + text-align: center !important; +} + +.go-right { + text-align: right !important; +} + +.go-left { + text-align: left !important; +} + +.go-big { + font-size: clamp(1.2rem, 1rem + 1vw, 1.275rem); +} + +.uppercase { + text-transform: uppercase; +} + +.strike { + text-decoration: line-through; + text-decoration-thickness: .15rem; +} + +.now { + white-space: nowrap; +} + +.big-sky { + margin-top: 5rem; +} + +strong { + font-weight: bold; +} + +code { + font-family: monospace; + font-size: .9rem; + color: var(--code-color); +} + +.code { + width: 100%; + min-height: 5rem; + padding-block: .5rem; + padding-inline: 1rem; + tab-size: 4; + font-family: monospace; + font-size: .85rem; +} + +@keyframes blink { + 0% {opacity: 0} + 49%{opacity: 0} + 50% {opacity: 1} +} + +.blink-slow { + animation: blink 3500ms infinite; +} + +.blink { + animation: blink 2s infinite; +} + +.blink-fast { + animation: blink 1s infinite; +} + +@keyframes pulse { + 0% {filter: brightness(1.0)} + 50% {filter: brightness(.25)} +} + +.pulse { + animation: pulse 2300ms infinite; +} + +.pulse-rate-high { + animation: pulse 1s infinite; +} + +.accordion-wrapper { + display: block; + margin: 1.75rem auto; + width: 100%; +} + +.limit-width { + max-width: 1240px; +} + +.accordion { + display: flex; + align-items: center; + min-height: 3rem; + width: 100%; + padding-right: 2.75rem; + padding-left: 1rem; + border-radius: 100vmax; + background-color: var(--harvestgold); + border-left: solid 3rem var(--orange); + text-align: left; + font-size: 1.25rem; + color: black; + cursor: pointer; + transition: 0.4s ease; + position: relative; +} + +.active, .accordion:hover { + background-color: var(--honey); + border-left-color: var(--butter); + filter: none; +} + +.accordion:before { + content: ''; + display: block; + width: .5rem; + height: 4rem; + background-color: black; + position: absolute; + top: 0; + left: 0; +} + +.accordion:after { + display: block; + content: '\276F'; + position: absolute; + right: 1.5rem; + top: 21%; + transform: rotate(90deg); + transition: 0.4s; + font-weight: bold; + color: black; +} + +.active:after { + content: "\276F"; + transform:rotate(-90deg); + transition: 0.4s ease; +} + +.accordionContent { + padding-block: .5rem; + padding-inline: 3.5rem; + max-height: 0; + overflow: hidden; + transition: max-height 0.25s ease-out; +} + +.accordionContent ul { + margin-left: 0; +} + +@media (max-width: 525px) { + .accordion { + min-height: 2.5rem; + font-size: 1rem; + border-left-width: 2.5rem; + } +} + +/* Images */ + +.pics-right { + float: right; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +.pics-left { + float: left; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +@media (max-width: 1060px) { + .pics-right, + .pics-left { + float: none; + margin-inline: auto; + } + + .pics-right img, + .pics-left img { + margin-inline: auto; + } +} + +.pics { + margin-block: 2rem; + margin-inline: auto; +} + +.border { + border: 2px solid var(--font-color); +} + +.lcars-list { + margin-block: 1.15rem; + margin-left: 2rem; + list-style: none; +} + +.lcars-list li { + position: relative; + padding-block: .45rem; + padding-left: 2.25rem; + text-box: trim-both cap alphabetic; +} + +.lcars-list li::before { + content: ''; + display: block; + width: 34px; + height: 18px; + border-radius: 50%; + background-color: var(--font-color); + position: absolute; + top: .45rem; + left: 0; +} + +@media (max-width: 650px) { + + .lcars-list { + margin-left: .5rem; + } + + .lcars-list li::before { + transform: scale(90%); + } +} + +.lcars-bar { + margin-block: 1.75rem; + height: clamp(15px, 2vh, 25px); + background: transparent; + border-right: clamp(15px, 2vh, 25px) solid var(--lcars-bar-end-color); + border-left: clamp(15px, 2vh, 25px) solid var(--lcars-bar-start-color); + border-radius: 100vmax; + position: relative; +} + +.lcars-bar::after { + content: ''; + display: block; + height: clamp(15px, 2vh, 25px); + width: 100%; + background-color: var(--lcars-bar-color); + border-right: .8vh solid black; + border-left: .8vh solid black; + position: absolute; + top: 0; + left: 0; +} + +.lcars-text-bar { + display: flex; + position: relative; + height: clamp(16px, 4vh, 41px); + margin-block: 2.75rem; + overflow: visible; + border-radius: 100vmax; + background-color: var(--lcars-bar-color); + border-right: clamp(16px, 4vh, 43px) solid var(--lcars-bar-end-color); + border-left: clamp(16px, 4vh, 43px) solid var(--lcars-bar-start-color); +} + +.the-end { + justify-content: flex-end; +} + +.lcars-text-bar h2, +.lcars-text-bar h3, +.lcars-text-bar h4, +.lcars-text-bar span { + margin-block: 0; + background-color: black; + height: clamp(20px, 5.5vh, 60px); /* Setting height is a Firefox fix */ + overflow: visible; + border-top: 1px solid black; + padding-inline: 1vh; + font-size: clamp(17px, 4.5vh, 46px); + line-height: 1; + text-transform: uppercase; + color: var(--lcars-bar-text-color); + z-index: 1; + text-box: trim-both cap alphabetic; +} + +.lcars-text-bar::before { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} + +.lcars-text-bar::after { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + right: 0; + overflow: hidden; +} + +/* LCARS Image Frame */ + +.image-frame { + margin: 2.75rem auto; + width: fit-content; + background: linear-gradient(var(--primary-color) 56%, var(--secondary-color) 44%); + border-radius: 50px 25px 0 50px; + position: relative; +} + +.image-frame::before { + content: ''; + display: block; + width: 40px; + height: 40px; + background-color: black; + position: absolute; + right: 0; + top: 0; +} + +.image-frame::after { + content: ''; + display: block; + border-top: var(--spacers) solid black; + border-bottom: var(--spacers) solid black; + width: 45px; + height: 80px; + background-color: var(--secondary-color); + position: absolute; + left: 0; + top: 56%; +} + +.imgf-title { + display: flex; + justify-content: flex-end; + height: 40px; + border-right: 40px solid var(--secondary-color); + border-radius: 25px 100vh 100vh 0; + position: relative; + z-index: 1; + text-align: right; +} + +.h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + border-right: var(--spacers) solid black; +} + +.imgf-title h4 { + margin-block: 0; + width: fit-content; + background-color: black; + padding-left: var(--spacers); + font-size: 2.05rem; + color: var(--title-color); + line-height: 40px; + text-transform: uppercase; +} + +.imgf-image-body { + margin-left: 45px; + background-color: black; + width: fit-content; + padding: 1rem; + border-radius: 28px 0 0 28px; +} + +.image-holder { + width: fit-content; + padding: 1rem; + border: 2px solid var(--image-border-color); + border-radius: 20px; +} + +.imgf-base { + display: grid; + grid-template-columns: 20% 13% 35px 15% 1fr; + margin-left: 80px; + border-left: var(--spacers) solid black; +} + +.imgf-block-1 { + height: var(--frame-height); + background-color: var(--accent-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-2 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-3 { + height: var(--frame-height); + background-color: black; + border-right: 10px solid var(--secondary-color); + border-left: 10px solid var(--accent-color); +} + +.imgf-block-4 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-left: var(--spacers) solid black; +} + +.imgf-block-5 { + height: var(--frame-height); + background-color: black; +} + +@media (max-width: 750px) { + + .image-frame { + border-radius: 40px 25px 0 40px; + } + + .image-frame::after { + width: 25px; + height: 60px; + top: 50%; + } + + .imgf-title { + height: 25px; + border-right: 24px solid var(--secondary-color); + } + + .h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + } + + .imgf-title h4 { + font-size: 1.45rem; + } + + .imgf-image-body { + margin-left: 25px; + padding: .75rem; + border-radius: 20px 0 0 20px; + } + + .image-holder { + padding: .75rem; + border-radius: 10px; + } +} + +/* color styles */ + +.font-butter { + color: var(--butter) !important; +} + +.button-butter, +.background-butter, +.bullet-butter::before { + background-color: var(--butter) !important; +} + +.font-daybreak { + color: var(--daybreak) !important; +} + +.button-daybreak, +.background-daybreak, +.bullet-daybreak::before { + background-color: var(--daybreak) !important; +} + +.font-harvestgold { + color: var(--harvestgold) !important; +} + +.button-harvestgold, +.background-harvestgold, +.bullet-harvestgold::before { + background-color: var(--harvestgold) !important; +} + +.font-honey { + color: var(--honey) !important; +} + +.button-honey, +.background-honey, +.bullet-honey::before { + background-color: var(--honey) !important; +} + +.font-october-sunset { + color: var(--october-sunset) !important; +} + +.button-october-sunset, +.background-october-sunset, +.bullet-october-sunset::before { + background-color: var(--october-sunset) !important; +} + +.font-orange { + color: var(--orange) !important; +} + +.button-orange, +.background-orange, +.bullet-orange::before { + background-color: var(--orange) !important; +} + +.font-rich-pumpkin{ + color: var(--rich-pumpkin) !important; +} + +.button-rich-pumpkin, +.background-rich-pumpkin, +.bullet-rich-pumpkin::before { + background-color: var(--rich-pumpkin) !important; +} + +/* Footer */ + +footer { + margin-top: 2rem; + padding-bottom: 3rem; + padding-left: clamp(20px, 3vw, 50px); + font-size: .875rem; +} + +.headtrim { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + top: 0; + left: 0; + z-index: 999; +} + +.baseboard { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + bottom: 0; + left: 0; + z-index: 999; +} + +/* Grouped @Media */ + +@media (max-width: 650px) { + + .first-bar-panel { + margin-top: .75rem; + } + + .bar-4::before { + height: 5px; + top: -12px; + } + + .bar-9::before { + height: 5px; + bottom: -12px; + } +} + +@media (max-width: 525px) { + + body { + padding: .25rem; + } + + .baseboard { + display: none; + } + + .wrap { + padding-left: 0; + padding-right: .25rem; + } + + .hop { + display: none; + } + + .left-frame { + padding-top: 8vh; + } + + .left-frame:has(.sidebar-nav) { + padding-top: 5vh; + } + + .left-frame:has(button) { + padding-top: 5vh; + } + + .floor-heading { + bottom: 0; + } + + blockquote { + margin-left: .75rem; + } +} + + @-moz-document url-prefix() { + + main { + padding-top: clamp(1rem, 4vw, 30px); + } + + h1, h2, h3, h4, p { + margin-block: 1.15rem; + } + + .postmeta { + margin-top: .75rem; + } + + .lcars-text-bar h2, + .lcars-text-bar h3, + .lcars-text-bar h4, + .lcars-text-bar span { + position: absolute; + top: -.7vh; + } + + .meta-data { + height: 1.15rem; + line-height: 1rem; + } +} \ No newline at end of file diff --git a/lcars_v4/frontend/assets/nemesis-blue.css b/lcars_v4/frontend/assets/nemesis-blue.css new file mode 100644 index 0000000..e763cc4 --- /dev/null +++ b/lcars_v4/frontend/assets/nemesis-blue.css @@ -0,0 +1,2830 @@ +@charset "utf-8"; + +/* + + CSS Document + LCARS Nemesis Blue Theme + Version 24.2 + By Jim Robertus www.thelcars.com + Modified: 2025 Aug 11 + +*/ + +:root { + font-size: 1.375rem; + color-scheme: dark; + --lfw: 240px; + --cardinal: #c23; + --cool: #69f; + --evening: #26f; + --galaxy-gray: #52526a; + --ghost: #8bf; + --grape: #96c; + --honey: #fc9; + --lawn: #9a2; + --martian: #9c3; /* 9d6/9c3 (#982 dark olive & #992 light olive or yellow-green) (#9a2 lawn) (#971 flat-dark-grass) */ + --midnight: #23f; + --moonbeam: #ebf0ff; + --pumpkinshade: #f74; + --roseblush: #c66; + --tangerine: #f83; + --wheat: #ca8; + --left-frame-top-color: var(--evening); + --left-frame-color: var(--evening); /* panel-9 inherits this color */ + --left-frame-padding: .75rem; + --corner-color-top: var(--evening); + --corner-color-bottom: var(--evening); + --panel-1-color: var(--wheat); + --panel-2-color: var(--moonbeam); + --panel-4-color: var(--evening); + --panel-5-color: var(--cool); + --panel-6-color: var(--evening); + --panel-7-color: var(--evening); + --panel-8-color: var(--moonbeam); + --panel-10-color: var(--evening); + --panel-top-button-color: var(--tangerine); + --bar-height: 28px; + --bar-1-6-width: 40%; + --bar-2-7-width: 4%; + --bar-3-8-width: 17%; + --bar-5-10-width: 4%; + --bar-1-color: var(--evening); + --bar-2-color: var(--honey); + --bar-3-color: var(--cool); + --bar-4-color: var(--midnight); + --bar-5-color: var(--galaxy-gray); + --bar-6-color: var(--evening); + --bar-7-color: var(--tangerine); + --bar-8-color: var(--moonbeam); + --bar-9-color: var(--evening); + --bar-10-color: var(--galaxy-gray); + +/* Ultra layout elements */ + + --section-2-color: var(--cool); + --pill-1-color: var(--evening); + --pill-2-color: var(--cool); + --pill-3-color: var(--cool); + --pill-4-color: var(--evening); + --pill-5-color: var(--midnight); + --pill-6-color: var(--midnight); + --pill-a1-color: var(--midnight); + --pill-a2-color: var(--cool); + --pill-a3-color: black; + --pill-a4-color: var(--evening); + --pill-a5-color: var(--tangerine); + --pill-a6-color: var(--honey); + --panel-11-color: var(--cool); + --panel-12-color: var(--cool); + --panel-13-color: var(--honey); + --panel-14-color: var(--evening); + --panel-15-color: var(--cool); + + /* End Ultra layout elements */ + + --radius-top: 0 0 0 160px; + --radius-bottom: 160px 0 0 0; + --radius-content-top: 0 0 0 60px; + --radius-content-bottom: 60px 0 0 0; + --panel-border: .25rem solid black; + --bar-border: .25rem solid black; + --bar-cut-width: 34%; + --bar-cut-out-width: 34%; + --divider-height: .5rem; +/* + NOTE: --font-color also sets the following: + 1. horizontal line
color + 2. lcars-list default bullet color + 3. blockquote border color + 4. images with the *border* class border color +*/ + --font-color: var(--cool); + --sub-fonts: .875rem; + --dc-font-size: .875rem; + --dc-row-height: calc(var(--dc-font-size) + .125rem); + --banner-color: var(--ghost); + --data-cascade-color: var(--evening); + --light-color: var(--moonbeam); + --h1-color: var(--ghost); + --h2-color: var(--ghost); + --h3-color: var(--ghost); + --h4-color: var(--ghost); + --link-color: var(--cool); + --code-color: var(--martian); + --nav-width: 240px; + --nav-1-color: var(--cool); + --nav-2-color: var(--roseblush); + --nav-3-color: var(--honey); + --nav-4-color: var(--cardinal); + --button-color: var(--cool); + --button-color-sidebar: var(--cool); + --lcars-bar-color: var(--evening); + --lcars-bar-start-color: var(--midnight); + --lcars-bar-end-color: var(--midnight); + --lcars-bar-text-color: var(--moonbeam); + +/* Image Frame */ + + --image-border-color: var(--cool); + --primary-color: var(--evening); + --secondary-color: var(--cool); + --accent-color: #adcaff; /* bdd1ff */ + --spacers: .65rem; + --frame-height: 40px; +} + +@media (max-width: 1500px) { + :root { + --lfw: 200px; + --radius-top: 0 0 0 130px; + --radius-bottom: 130px 0 0 0; + --divider-height: .4rem; + --nav-width: 210px; + --dc-font-size: .75rem; + --bar-height: 24px; + } +} + +@media (max-width: 1300px) { + :root { + font-size: 1.2rem; + --sub-fonts: .9rem; + --lfw: 180px; + --nav-width: 180px; + --radius-top: 0 0 0 100px; + --radius-bottom: 100px 0 0 0; + --radius-content-top: 0 0 0 40px; + --radius-content-bottom: 40px 0 0 0; + --bar-height: 20px; + } +} + +@media (max-width: 950px) { + :root { + --lfw: 150px; + } +} + +@media (max-width: 750px) { + :root { + --panel-border: .25rem solid black; + --bar-border: .25rem solid black; + --lfw: 120px; + --radius-top: 0 0 0 80px; + --radius-bottom: 80px 0 0 0; + --radius-content-top: 0 0 0 34px; + --radius-content-bottom: 34px 0 0 0; + --nav-width: 174px; + --bar-height: 16px; + --spacers: .5rem; + --frame-height: 25px; + } +} + +@media (max-width: 525px) { + :root { + --lfw: 62px; + --left-frame-padding: .5rem; + --radius-top: 0 0 0 40px; + --radius-bottom: 40px 0 0 0; + --bar-height: 10px; + --divider-height: .3rem; + } +} + +@media (max-width: 450px) { + :root { + --nav-width: 48%; + } +} + +*, *:after, *:before { + box-sizing: border-box; +} + +* { + margin: 0; + padding: 0; + font: inherit; +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +input, textarea, button, select { + font: inherit; +} + +@font-face { + font-family: 'Antonio'; + font-weight: 400; + src: url('Antonio-Regular.woff2') format('woff2'), + url('Antonio-Regular.woff') format('woff'); +} + +@font-face { + font-family: 'Antonio'; + font-weight: 700; + src: url('Antonio-Bold.woff2') format('woff2'), + url('Antonio-Bold.woff') format('woff') +} + +html { + scroll-behavior: smooth; +} + +body { + display: flex; + padding-top: 10px; + padding-left: 5px; + background-color: black; + font-family: 'Antonio', 'Arial Narrow', 'Avenir Next Condensed', sans-serif; + font-weight: 400; + line-height: 1.5; + color: var(--font-color); +} + +a { + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: .2rem; + color: var(--link-color); +} + +a:hover { + filter: brightness(115%); + animation: none; +} + +a:active { + filter: brightness(80%); + outline: none; +} + +button { + border: none; + outline: none; + color: black; + transition: width 1s; +} + +button:hover { + cursor: pointer; + animation: none; + filter: brightness(115%); + color: black; +} + +button:active { + filter: brightness(85%); +} + +/* Ultra Layout elements */ + +.wrap-everything { + display: flex; + width: 100%; + column-gap: 10px; +} + +#column-1 { + width: 350px; + padding: 10px 10px 10px 20px; + transition: 800ms; +} + +#column-2 { + width: var(--lfw); + background-color: var(--section-2-color); + text-align: right; + font-weight: bold; + line-height: 1.2; + color: black; + transition: 800ms; + z-index: 2; +} + +#column-2 a { + color: black; + text-decoration: none; +} + +#column-3 { + flex: 1; + margin-inline: auto; +} + +.wrap { + display: flex; + margin-inline: auto; + padding-left: 5px; + padding-right: 15px; + overflow: hidden; +} + +@media (max-width: 1680px) { + #column-1 { + margin-left: -370px; + } + + #column-2 { + margin-left: -230px; + } + + .wrap-everything { + column-gap: 5px; + } +} + +@media (max-width: 1500px) { + #column-1, + #column-2 { + display: none; + } +} + +.lcars-frame { + display: flex; + min-height: 280px; + position: relative; + --frame-color: var(--evening); +} + +.frame-col-1 { + width: 20px; + height: 280px; + background: var(--frame-color); + border-radius: 16px 0 0 16px; + position: relative; +} + +.frame-col-1:before { + content: ''; + display: block; + width: 20px; + height: 200px; + border-top: 5px solid black; + border-bottom: 5px solid black; + background-color: var(--frame-color); + position: absolute; + top: 40px; + left: 0; +} + +.frame-col-1-cell-a { + width: 14px; + height: 65px; + background-color: var(--grape); + border-left: 4px solid black; + border-bottom: 4px solid black; + position: absolute; + top: 45px; + right: 0; + z-index: 2; +} + +.frame-col-1-cell-b { + width: 14px; + height: 70px; + background-color: var(--cool); + border-left: 4px solid black; + position: absolute; + top: 110px; + right: 0; + z-index: 2; +} + +.frame-col-1-cell-c { + width: 14px; + height: 65px; + background-color: var(--grape); + border-top: 4px solid black; + border-left: 4px solid black; + position: absolute; + bottom: 45px; + right: 0; + z-index: 2; +} + +.frame-col-1-blocks:before { + content: ''; + display: block; + width: 10px; + height: 3px; + background-color: black; + position: absolute; + top: 54px; + left: 0; +} + +.frame-col-2 { + width:20px; + height: 280px; + background-color: var(--frame-color); + position: relative; +} + +.frame-col-2:before { + content: ''; + display: block; + width: 20px; + height: 240px; + background-color: black; + border-radius: 10px 0 0 10px; + position: absolute; + top: 20px; + left: 0; +} + +.frame-col-3 { + display: flex; + width: 240px; + height: 280px; + align-items: center; + justify-content: center; +} + +.frame-col-4 { + width:20px; + height: 280px; + background-color: var(--frame-color); + position: relative; +} + +.frame-col-4:before { + content: ''; + display: block; + width: 20px; + height: 240px; + background-color: black; + border-radius: 0 10px 10px 0; + position: absolute; + top: 20px; + left: 0; +} + +.display-horizontal { + rotate: 90deg; +} + +.frame-col-5 { + width:20px; + height: 280px; + background-color: var(--frame-color); + border-radius: 0 16px 16px 0; + padding-top: 40px; + position: relative; +} + +.frame-col-5:before { + content: ''; + display: block; + width: 20px; + height: 200px; + border-top: 5px solid black; + border-bottom: 5px solid black; + background-color: var(--frame-color); +} + +.frame-col-5-cell-a { + width: 14px; + height: 65px; + background-color: var(--tangerine); + border-bottom: 4px solid black; + border-right: 4px solid black; + position: absolute; + top: 45px; + left: 0; + z-index: 2; +} + +.frame-col-5-cell-b { + width: 14px; + height: 70px; + background-color: var(--cool); + border-right: 4px solid black; + position: absolute; + top: 110px; + left: 0; + z-index: 2; +} + +.frame-col-5-cell-c { + width: 14px; + height: 65px; + background-color: var(--tangerine); + border-top: 4px solid black; + border-right: 4px solid black; + position: absolute; + bottom: 45px; + left: 0; + z-index: 2; +} + +.line { + height: 20px; + width: 12px; + background: linear-gradient(#600, #f20, #600); +} + +.line:nth-child(1) { + animation: animateLine6 1s 0.2s infinite; +} + +.line:nth-child(2) { + animation: animateLine5 1s 0.3s infinite; +} + +.line:nth-child(3) { + animation: animateLine3 1s 0.4s infinite; +} + +.line:nth-child(4) { + animation: animateLine3 1s 0.5s infinite; +} + +.line:nth-child(5) { + animation: animateLine2 1s 0.6s infinite; +} + +.line:nth-child(6) { + animation: animateLine2 1s 0.7s infinite; +} + +.line:nth-child(7) { + animation: animateLine2 1s 0.8s infinite; +} + +/* 8 & 9 are middle lines*/ + +.line:nth-child(8) { + animation: animateLine4 1s 0.9s infinite; +} + +.line:nth-child(9) { + animation: animateLine4 1s 1s infinite; +} + +.line:nth-child(10) { + animation: animateLine2 1s 0.8s infinite; +} + +.line:nth-child(11) { + animation: animateLine2 1s 0.7s infinite; +} + +.line:nth-child(12) { + animation: animateLine2 1s 0.6s infinite; +} + +.line:nth-child(13) { + animation: animateLine3 1s 0.5s infinite; +} + +.line:nth-child(14) { + animation: animateLine3 1s 0.4s infinite; +} + +.line:nth-child(15) { + animation: animateLine5 1s 0.3s infinite; +} + +.line:nth-child(16) { + animation: animateLine6 1s 0.2s infinite; +} + +@keyframes animateLine2 { + 0% { + height: 180px; + } + 50% { + height: 90px; + } + 100% { + height: 180px; + } +} + +@keyframes animateLine3 { + 0% { + height: 120px; + } + 50% { + height: 60px; + } + 100% { + height: 120px; + } +} + +@keyframes animateLine4 { + 0% { + height: 230px; + } + 50% { + height: 115px; + } + 100% { + height: 230px; + } +} + +@keyframes animateLine5 { + 0% { + height: 60px; + } + 50% { + height: 30px; + } + 100% { + height: 60px; + } +} + +@keyframes animateLine6 { + 0% { + height: 30px; + } + 50% { + height: 15px; + } + 100% { + height: 30px; + } +} + +.pillbox, +.pillbox-2 { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 8px; + margin: 1.25rem auto; + text-align: right; + font-size: var(--sub-fonts); +} + +.pill, +.pill-2 { + display: flex; + width: 100%; + height: 56px; + justify-content: flex-end; + align-items: flex-end; + text-decoration: none; + color: black; + font-weight: bold; + padding-right: .75rem; + padding-bottom: .35rem; +} + +.pillbox a { + display: flex; + width: 100%; + height: 56px; + justify-content: flex-end; + align-items: flex-end; + text-decoration: none; + color: black; + font-weight: bold; + padding-right: .75rem; + padding-bottom: .35rem; +} + +.pillbox-2 a { + display: flex; + width: 100%; + height: 56px; + justify-content: flex-end; + align-items: flex-end; + text-decoration: none; + color: black; + font-weight: bold; + padding-right: .75rem; + padding-bottom: .35rem; +} + +.pill:hover, +.pill-2:hover { + filter: brightness(115%); +} + +.pill:active, +.pill-2:active { + filter: brightness(80%); +} + +.pill:nth-child(1), +.pillbox a:nth-child(1) { + border-radius: 100vmax 0 0 100vmax; + background-color: var(--pill-1-color); +} + +.pill:nth-child(2), +.pillbox a:nth-child(2) { + background-color: var(--pill-2-color); +} + +.pill:nth-child(3), +.pillbox a:nth-child(3) { + border-radius: 100vmax 0 0 100vmax; + background-color: var(--pill-3-color); +} + +.pill:nth-child(4), +.pillbox a:nth-child(4) { + background-color: var(--pill-4-color); +} + +.pill:nth-child(5), +.pillbox a:nth-child(5) { + background-color: var(--pill-5-color); + border-radius: 100vmax 0 0 100vmax; +} + +.pill:nth-child(6), +.pillbox a:nth-child(6) { + background-color: var(--pill-6-color); +} + +.pill-2:nth-child(1), +.pillbox-2 a:nth-child(1) { + border-radius: 100vmax 0 0 100vmax; + background-color: var(--pill-a1-color); +} + +.pill-2:nth-child(2), +.pillbox-2 a:nth-child(2) { + background-color: var(--pill-a2-color); + border-radius: 0 100vmax 100vmax 0; + padding-right: 1rem; +} + +.pill-2:nth-child(3), +.pillbox-2 a:nth-child(3) { + background-color: var(--pill-a3-color); +} + +.pill-2:nth-child(4), +.pillbox-2 a:nth-child(4) { + background-color: var(--pill-a4-color); + border-radius: 0 100vmax 100vmax 0; + padding-right: 1rem; +} + +.pill-2:nth-child(5), +.pillbox-2 a:nth-child(5) { + background-color: var(--pill-a5-color); + border-radius: 100vmax 0 0 100vmax; +} + +.pill-2:nth-child(6), +.pillbox-2 a:nth-child(6) { + background-color: var(--pill-a6-color); + border-radius: 0 100vmax 100vmax 0; + padding-right: 1rem; +} + +.lcars-list-2 ul { + list-style: none; +} + +.lcars-list-2 { + margin: 0 auto 50px auto; + padding-left: 5px; +} + +.lcars-list-2 li { + position: relative; + padding-bottom: 5px; + padding-left: 38px; + font-size: var(--sub-fonts); + color: var(--font-color); +} + +.lcars-list-2 li::before { + content: ''; + display: block; + width: 24px; + height: 14px; + border-radius: 50%; + background-color: var(--font-color); + position: absolute; + top: 8px; + left: 0; +} + +.panel-11 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 23vh; + max-height: 275px; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-11-color); + border-bottom: var(--panel-border); +} + +.panel-12 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 15vh; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-12-color); + border-bottom: var(--panel-border); +} + +.panel-13 a { + display: flex; + align-items: flex-end; + justify-content: flex-end; + padding: 1.5rem .75rem .75rem 2px; + background-color: var(--panel-13-color); + border-bottom: var(--panel-border); +} + +.panel-14 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 20vh; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-14-color); + border-bottom: var(--panel-border); +} + +.panel-15 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 20vh; + padding-right: .75rem; + padding-bottom: .75rem; + background-color: var(--panel-15-color); + border-bottom: var(--panel-border); +} + +.section-2-buttons a { + display: block; + text-decoration: none; + text-align: right; + border-bottom: var(--panel-border); + padding: 1.5rem .75rem .75rem 2px; + background-color: var(--evening); + text-transform: uppercase; + color: black; +} + +.section-2-buttons a:nth-child(2) { + background-color: var(--moonbeam); +} + +/* End Ultra layout elements */ + +.scroll-top { + display: none; +} + +.left-frame-top, +.left-frame { + width: var(--lfw); + text-align: right; + font-size: clamp(.875rem, 2vw, 1rem); + line-height: 1.2; + font-weight: bold; + color: black; + transition: width 1s; +} + +.left-frame-top { + background-color: var(--left-frame-top-color); + border-radius: var(--radius-top); +} + +.left-frame-top a, +.left-frame a { + text-decoration: none; + color: black; +} + +.left-frame { + display: flex; + flex-direction: column; + justify-content: space-between; + padding-top: 100px; + background-color: var(--left-frame-color); + border-radius: var(--radius-bottom); +} + +.panel-1 a { + display: block; + background-color: var(--panel-1-color); + padding-top: clamp(40px, 8vw, 110px); + padding-right: .75rem; + padding-bottom: .75rem; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.right-frame-top { + flex: 1; + align-content: flex-end; + position: relative; +} + +.right-frame-top:before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to top right, var(--corner-color-top) 50%, black 50%); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +.right-frame-top:after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-top); + position: absolute; + left: 0; + bottom: var(--bar-height); + z-index: -1; +} + +@media (max-width: 650px) { + .right-frame-top:before { + bottom: 16px; + } + + .right-frame-top:after { + bottom: 16px; + } +} + +@media (max-width: 525px) { + .right-frame-top:before { + bottom: 10px; + } + + .right-frame-top:after { + bottom: 10px; + } +} + +.banner { + padding-bottom: 1rem; + padding-left: 5px; + text-align: right; + text-transform: uppercase; + line-height: 1.1; + font-size: clamp(1.25rem, 0.75rem + 4vw, 3.75rem); + color: var(--banner-color); +} + +.banner a { + color: var(--banner-color); + text-decoration: none; +} + +.data-cascade-button-group { + display: flex; + justify-content: flex-end; +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +.header-content { + flex: 1; + min-height: 180px; + padding-right: .5rem; + padding-left: clamp(20px, 3vw, 50px); +} + +.header-content > *:first-child { + margin-top: 0; +} + +.header-content > *:last-child { + margin-bottom: 0; +} + +/* Data Cascade 2025 */ + +.data-cascade-wrapper { + flex: 1; + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + max-width: 100%; + height: calc(var(--dc-row-height) * 9); /* 204px */ + overflow: hidden; + padding-right: .5rem; + padding-left: clamp(20px, 3vw, 50px); + column-gap: .5rem; +} + +.data-column { + display: grid; + grid-template-columns: 1fr; + margin-top: 1px; + text-align: right; + font-size: var(--dc-font-size); /* .938 */ + line-height: 1; + text-box: trim-both cap alphabetic; + color: black; +} + +.dc-row-1, +.dc-row-2, +.dc-row-3, +.dc-row-4, +.dc-row-5, +.dc-row-6, +.dc-row-7 { + text-box: trim-both cap alphabetic; + height: var(--dc-row-height); +} + +@media (max-width: 850px) { + .data-cascade-wrapper { + display: none; + } +} + + +@keyframes data-group-1 { + + 0%, + 3.99% { + color: black; + } + + 4%, + 45.99% { + color: var(--data-cascade-color); + } + + 46%, + 49.99% { + color: var(--light-color); + } + + 50%, + 63.99% { + color: var(--data-cascade-color); + } + + 64%, + 67.99% { + color: var(--light-color); + } + + 68%, + 100% { + color: var(--data-cascade-color); + } + + +} + +@keyframes data-group-1a { + + 0%, + 4.99% { + color: black; + } + + 5%, + 45.99% { + color: var(--data-cascade-color); + } + + 46%, + 49.99% { + color: var(--light-color); + } + + 50%, + 63.99% { + color: var(--data-cascade-color); + } + + 64%, + 67.99% { + color: var(--light-color); + } + + 68%, + 100% { + color: var(--data-cascade-color); + } + + +} + +@keyframes data-group-2 { + + 0%, + 12.99% { + color: black; + } + + 13%, + 49.99% { + color: var(--data-cascade-color); + } + + 50%, + 53.99% { + color: var(--light-color); + } + + 54%, + 67.99% { + color: var(--data-cascade-color); + } + + 68%, + 71.99% { + color: var(--light-color); + } + + 72%, + 100% { + color: var(--data-cascade-color); + } + + +} + +@keyframes data-group-2b { + + 0%, + 14.99% { + color: black; + } + + 15%, + 49.99% { + color: var(--data-cascade-color); + } + + 50%, + 53.99% { + color: var(--light-color); + } + + 54%, + 67.99% { + color: var(--data-cascade-color); + } + + 68%, + 71.99% { + color: var(--light-color); + } + + 72%, + 81.99% { + color: var(--data-cascade-color); + } + + 82%, + 100% { + color: var(--light-color); + } + + +} + +@keyframes data-group-3 { + + 0%, + 26.99% { + color: black; + } + + 27%, + 40.99% { + color: var(--light-color); + } + + 41%, + 53.99% { + color: var(--data-cascade-color); + } + + 54%, + 57.99% { + color: var(--light-color); + } + + 58%, + 71.99% { + color: var(--data-cascade-color); + } + + 72%, + 75.99% { + color: var(--light-color); + } + + 76%, + 100% { + color: var(--data-cascade-color); + } + +} + +.dc-row-1 { + animation: data-group-1 6000ms ease 200ms infinite; +} + +.dc-row-2 { + animation: data-group-1a 6000ms ease 200ms infinite; +} + +.dc-row-3 { + animation: data-group-2 6000ms ease 200ms infinite; +} + +.dc-row-4 { + animation: data-group-2b 6000ms ease 200ms infinite; +} + +.dc-row-5 { + animation: data-group-3 6000ms ease 200ms infinite; +} + +.dc-row-6 { + animation: data-group-3 6000ms ease 200ms infinite; +} + +.dc-row-7 { + animation: data-group-3 6000ms ease 200ms infinite; +} + + +/* Static data cascade */ + +.data-cascade-wrapper#frozen .dc-row-1 { + animation: none; + color: var(--data-cascade-color); +} + +.data-cascade-wrapper#frozen .dc-row-2 { + animation: none; + color: var(--data-cascade-color); +} + +.data-cascade-wrapper#frozen .dc-row-3 { + animation: none; + color: var(--data-cascade-color); +} + +.data-cascade-wrapper#frozen .dc-row-4 { + animation: none; + color: var(--data-cascade-color); +} + +.data-cascade-wrapper#frozen .dc-row-5 { + animation: none; + color: var(--light-color); +} + +.data-cascade-wrapper#frozen .dc-row-6 { + animation: none; + color: var(--light-color); +} + +.data-cascade-wrapper#frozen .dc-row-7 { + animation: none; + color: var(--light-color); +} + +/* Navigation & Buttons */ + +.lcars-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + margin-block: 1rem; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1 a { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + height: clamp(90px, 11vw, 160px); + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + transition: width 1s; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-1-button { + display: flex; + width: var(--lfw); + justify-content: flex-end; + align-items: flex-end; + background-color: var(--panel-1-color); + min-height: clamp(90px, 11vw, 160px); + overflow: hidden; + padding: var(--left-frame-padding); + border-radius: 0; + border-bottom: var(--panel-border); + text-decoration: none; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.panel-2 a { + display: flex; + justify-content: flex-end; + align-items: flex-end; + min-height: 3.75rem; + padding: var(--left-frame-padding); + background-color: var(--panel-2-color); + border-bottom: var(--panel-border); +} + +nav { + display: flex; + flex-wrap: wrap; + align-self: center; + width: calc(var(--nav-width) + var(--nav-width) + 1rem); + justify-content: flex-end; + column-gap: .5rem; + row-gap: .65rem; +} + +@media (max-width: 1500px) { + nav { + column-gap: .375rem; + row-gap: .5rem; + } +} + +@media (max-width: 1440px) { + .data-cascade-button-group:has(.header-content) { + row-gap: 1rem; + } + + .data-cascade-button-group:has(.header-content) > nav { + width: 100%; + } +} + +nav a, +nav button, +.buttons button { + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: flex-end; + width: var(--nav-width); + height: calc(var(--nav-width) / 2.8); + padding-inline: 1.5rem; + padding-bottom: .7rem; + border-radius: 100vmax; + background-color: var(--button-color); + text-align: right; + line-height: 1.175; + text-decoration: none; + text-transform: uppercase; + font-weight: bold; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +nav a:nth-child(1), +nav button:nth-child(1) { + background-color: var(--nav-1-color); +} + +nav a:nth-child(2), +nav button:nth-child(2) { + background-color: var(--nav-2-color); +} + +nav a:nth-child(3), +nav button:nth-child(3) { + background-color: var(--nav-3-color); +} + +nav a:nth-child(4), +nav button:nth-child(4) { + background-color: var(--nav-4-color); +} + +@media (max-width: 1300px) { + nav { + padding-left: .5rem; + gap: .5rem; + } + + nav button { + padding-bottom: .5rem; + font-size: .875rem; + padding-inline: 1.25rem; + } +} + +@media (max-width: 780px) { + nav { + flex: 1; + } + + .data-cascade-button-group:has(.header-content) > *:nth-child(2) { + flex: none; + } +} + +@media (max-width: 450px) { + nav a, + nav button { + height: 63px; + } +} + +.buttons { + display: flex; + flex-wrap: wrap; + gap: .5rem; + margin-block: 2rem; +} + +.justify-space-between { + justify-content: space-between; +} + +.justify-center { + justify-content: center; +} + +.justify-flex-end { + justify-content: flex-end; +} + +.justify-space-around { + justify-content: space-around; +} + +.justify-space-evenly { + justify-content: space-evenly; +} + +.buttons a, +.buttons button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + width: 224px; + height: 80px; + padding-inline: 1.75rem; + padding-bottom: .675rem; + background-color: var(--button-color); + border-radius: 100vmax; + border-width: 0; + text-align: right; + line-height: 1.175; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + color: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.sidebar-nav button, +.sidebar-nav a, +.sidebar-button { + display: flex; + justify-content: flex-end; + align-items: flex-end; + min-height: 3.75rem; + width: var(--lfw); + background-color: var(--button-color-sidebar); + border-radius: 0; + border-bottom: var(--panel-border); + padding: var(--left-frame-padding); + text-decoration: none; + text-align: right; + word-break: break-all; + text-transform: uppercase; + color: black; +} + +@media (max-width: 1300px) { + .lcars-button, + .buttons a, + .buttons button { + width: 200px; + height: 74px; + } +} + +.panel-button { + display: flex; + justify-content: flex-end; + width: var(--lfw); + border-radius: 0; + padding: var(--left-frame-padding); + border-bottom: var(--panel-border); +} + +.pan-0 /* use this if you're not mimicking an established panel */ { + height: 18vh; + max-height: 240px; + background-color: var(--button-color-sidebar); +} + +.pan-4 { + height: 22vh; + max-height: 300px; + background-color: var(--panel-4-color) !important; +} + +.pan-5 { + height: 4.25rem; + background-color: var(--panel-5-color) !important; + align-items: center; +} + +.pan-6 { + height: 29vh; + max-height: 360px; + background-color: var(--panel-6-color) !important; +} + +.pan-7 { + height: 27vh; + max-height: 350px; + background-color: var(--panel-7-color) !important; +} + +.pan-8 { + height: 15vh; + background-color: var(--panel-8-color) !important; +} + +.pan-10 { + height: 30vh; + background-color: var(--panel-10-color) !important; +} + +.text-bottom { + align-items: flex-end; +} + +#topBtn { + display: none; + position: fixed; + bottom: 0; + z-index: 99; + border-radius: 0; + border-top: var(--panel-border); + border-right: none; + border-bottom: var(--panel-border); + border-left: none; + outline: none; + width: var(--lfw); + padding: var(--left-frame-padding); + padding-bottom: 10vh; + background-color: var(--panel-top-button-color); + text-align: right; + line-height: 1; + font-weight: bold; + text-transform: uppercase; + color: black; + cursor: pointer; +} + +#topBtn:hover { + filter: brightness(115%); +} + +#topBtn:active { + filter: brightness(80%); +} + +@media (max-width: 525px) { + .sidebar-button, + .sidebar-nav a, + .sidebar-nav button, + .panel-button { + font-size: .75rem; + } + + #topBtn { + padding-bottom: 6vh; + } +} + +/* --- Horizontal bar panels & sidebar panels --- */ + +.floor-text { + padding-top: .25rem; + font-size: 1.4rem; + text-align: right; + text-transform: uppercase; + color: var(--cool); +} + +.bar-panel { + display: flex; + height: var(--bar-height); +} + +.first-bar-panel { + margin-top: .5rem; +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-5, +.bar-6, +.bar-7, +.bar-9, +.bar-10 { + height: var(--bar-height); +} + +.bar-1, +.bar-2, +.bar-3, +.bar-4, +.bar-6, +.bar-7, +.bar-8, +.bar-9 { + border-right: var(--bar-border); +} + +.bar-1 { + width: var(--bar-1-6-width); + background-color: var(--bar-1-color); +} + +.bar-2 { + width: var(--bar-2-7-width); + background-color: var(--bar-2-color); +} + +.bar-3 { + width: var(--bar-3-8-width); + background-color: var(--bar-3-color); +} + +.bar-4 { + flex: 1; + background-color: var(--bar-4-color); +} + +.bar-5 { + width: var(--bar-5-10-width); + background-color: var(--bar-5-color); +} + +.bar-6 { + width: var(--bar-1-6-width); + background-color: var(--bar-6-color); +} + +.bar-7 { + width: var(--bar-2-7-width); + background-color: var(--bar-7-color); +} + +.bar-8 { + width: var(--bar-3-8-width); + height: 50%; + background-color: var(--bar-8-color); +} + +.bar-9 { + flex: 1; + background-color: var(--bar-9-color); +} + +.bar-10 { + width: var(--bar-5-10-width); + background-color: var(--bar-10-color); +} + +/* LCARS bottom section */ + +#gap { + margin-top: var(--divider-height); +} + +.panel-3, +.panel-4, +.panel-5, +.panel-6, +.panel-7, +.panel-8 { + border-bottom: var(--panel-border); +} + +.panel-3, +.panel-4, +.panel-6, +.panel-7, +.panel-8, +.panel-10 { + padding: var(--left-frame-padding); +} + +.panel-4 { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 22vh; + max-height: 300px; + background-color: var(--panel-4-color); +} + +.panel-5 { + display: flex; + justify-content: flex-end; + align-items: center; + height: 4.25rem; + padding: var(--left-frame-padding); + background-color: var(--panel-5-color); +} + +.panel-6 { + height: 29vh; + max-height: 360px; + background-color: var(--panel-6-color); +} + +.panel-7 { + height: 27vh; + max-height: 350px; + background-color: var(--panel-7-color); +} + +.panel-8 { + height: 15vh; + background-color: var(--panel-8-color); +} + +/* panel-9 height is fluid and governed by the amount of content on the page. Background color is inherited from :root --left-frame-color */ + +.panel-9 { + min-height: 27vh; + padding: var(--left-frame-padding); +} + +.panel-10 { + height: 30vh; + border-top: var(--panel-border); + background-color: var(--panel-10-color); +} + +@media (max-width: 525px) { + .panel-4, + .panel-6, + .panel-7 { + height: 18vh; + } +} + +.right-frame { + flex: 1; + position: relative; +} + +.right-frame:before { + content: ''; + display: block; + width: 60px; + height: 60px; + background: linear-gradient(to bottom right, var(--corner-color-bottom) 50%, black 50%); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +.right-frame:after { + content: ''; + display: block; + width: 60px; + height: 60px; + background-color: black; + border-radius: var(--radius-content-bottom); + position: absolute; + left: 0; + top: var(--bar-height); + z-index: -1; +} + +main { + padding-top: clamp(1rem, 4vw, 45px); + padding-bottom: .5rem; + padding-left: clamp(20px, 3vw, 50px); +} + +main > *:first-child, +article > *:first-child { + margin-top: 0; +} + +main:has(.floor-heading) > *:nth-child(2) { + margin-top: 0; +} + +.flexbox { + display: flex; + gap: 1.2rem; + flex-wrap: wrap; +} + +.col { + flex: 1 1 360px; +} + +.col > *:first-child { + margin-top: 0; +} + +h1, h2, h3, h4 { + margin-block: 1.75rem; + font-weight: normal; + line-height: 1.2; + text-transform: uppercase; + text-box: trim-both cap alphabetic; +} + +h1 { + font-size: clamp(1.5rem, 1.25rem + 3.5vw, 4rem); + text-align: right; + color: var(--h1-color); +} + +h2 { + font-size: clamp(1.4rem, 1.1rem + 2.25vw, 2.3rem); + color: var(--h2-color); +} + +h3 { + font-size: clamp(1.15rem, 1.05rem + 1.25vw, 1.875rem); + color: var(--h3-color); +} + +h4 { + font-size: clamp(1.025rem, 1rem + 1.125vw, 1.575rem); + color: var(--h4-color); +} + +.floor-heading { + display: flex; + justify-content: flex-end; + width: 100%; + position: fixed; + left: 50%; + transform: translate(-50%, 0); + bottom: 10px; + z-index:4; +} + +.floor-heading > * { + margin-block: 0; + width: fit-content; + padding-inline: .5rem; + padding-bottom: .5rem; + background-color: black; +} + +p { + margin-block: 1.75rem; + text-box: trim-both cap alphabetic; +} + +.caption { + margin-top: -1rem; + text-align: center; + font-size: var(--sub-fonts); +} + +.indent { + padding-left: 1.5rem; +} + +.postmeta { + margin-block: 1.25rem; + text-align: right; + font-size: clamp(1.2rem, 0.88rem + 1.28vw, 1.6rem); + line-height: 1.2; + text-transform: uppercase; +} + +article h1 { + margin-bottom: 0; +} + +hr { + margin-block: 1.5rem; + height: 6px; + border: none; + background-color: var(--font-color); + border-radius: 3px; +} + +blockquote { + margin-block: 1.75rem; + margin-left: 1.5rem; + padding-block: .25rem; + padding-left: 1.5rem; + position: relative; + text-box: trim-both cap alphabetic; +} + +blockquote::before { + content: ''; + display: block; + width: 10px; + height: 100%; + background-color: var(--font-color); + border-radius: 5px; + position: absolute; + left: 0; + top: 0; +} + +blockquote > *:first-child { + margin-top: 0; +} + +blockquote > * { + margin-bottom: 0; +} + +iframe { + display: block; + width: 100%; + border: none; +} + +.flush { + margin-top: -1rem; +} + +.nomar { + margin-block: 0 !important; +} + +.go-center { + text-align: center !important; +} + +.go-right { + text-align: right !important; +} + +.go-left { + text-align: left !important; +} + +.go-big { + font-size: clamp(1.2rem, 1rem + 1vw, 1.275rem); +} + +.uppercase { + text-transform: uppercase; +} + +.strike { + text-decoration: line-through; + text-decoration-thickness: .15rem; +} + +.now { + white-space: nowrap; +} + +.big-sky { + margin-top: 5rem; +} + +.smoke-glass { + opacity: .35; +} + +strong { + font-weight: bold; +} + +code { + font-family: monospace; + font-size: .9rem; + color: var(--code-color); +} + +.code { + width: 100%; + min-height: 5rem; + padding-block: .5rem; + padding-inline: 1rem; + background-color: #232323; + border-color: #4c4c4c; + tab-size: 4; + font-family: monospace; + font-size: .85rem; + color: #dcdcdc; +} + +@keyframes blink { + 0% {opacity: 0} + 49%{opacity: 0} + 50% {opacity: 1} +} + +.blink-slow { + animation: blink 3500ms infinite; +} + +.blink { + animation: blink 2s infinite; +} + +.blink-fast { + animation: blink 1s infinite; +} + +@keyframes pulse { + 0% {filter: brightness(1.0)} + 50% {filter: brightness(.25)} +} + +.pulse { + animation: pulse 2s infinite; +} + +.pulse-rate-high { + animation: pulse 1s infinite; +} + +.pulse-rate-low { + animation: pulse 3s infinite; +} + +.accordion-wrapper { + display: block; + margin: 1.75rem auto; + width: 100%; +} + +.limit-width { + max-width: 1240px; +} + +.accordion { + display: flex; + align-items: center; + min-height: 3rem; + width: 100%; + padding-right: 2.75rem; + padding-left: 1rem; + border-radius: 100vmax; + background-color: var(--cool); + border-left: solid 3rem var(--evening); + text-align: left; + font-size: 1.25rem; + color: black; + cursor: pointer; + transition: 0.4s ease; + position: relative; +} + +.active, .accordion:hover { + background-color: var(--ghost); /* 8bf */ + border-left-color: var(--moonbeam); + filter: none; +} + +.accordion:before { + content: ''; + display: block; + width: .5rem; + height: 4rem; + background-color: black; + position: absolute; + top: 0; + left: 0; +} + +.accordion:after { + display: block; + content: '\276F'; + position: absolute; + right: 1.5rem; + top: 21%; + transform: rotate(90deg); + transition: 0.4s; + font-weight: bold; + color: black; +} + +.active:after { + content: "\276F"; + transform:rotate(-90deg); + transition: 0.4s ease; +} + +.accordionContent { + padding-block: .5rem; + padding-inline: 3.5rem; + max-height: 0; + overflow: hidden; + transition: max-height 0.25s ease-out; +} + +.accordionContent ul { + margin-left: 0; +} + +@media (max-width: 525px) { + .accordion { + min-height: 2.5rem; + font-size: 1rem; + border-left-width: 2.5rem; + } +} + +/* Images */ + +.pics-right { + float: right; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +.pics-left { + float: left; + margin-inline: 1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +@media (max-width: 1060px) { + .pics-right, + .pics-left { + float: none; + margin-inline: auto; + } + + .pics-right img, + .pics-left img { + margin-inline: auto; + } +} + +.pics { + margin-block: 2rem; + margin-inline: auto; +} + +.border { + border: 2px solid var(--font-color); +} + +.lcars-list { + margin-block: 1.15rem; + margin-left: 2rem; + list-style: none; +} + +.lcars-list li { + position: relative; + padding-block: .45rem; + padding-left: 2.25rem; + text-box: trim-both cap alphabetic; +} + +.lcars-list li::before { + content: ''; + display: block; + width: 34px; + height: 18px; + border-radius: 50%; + background-color: var(--font-color); + position: absolute; + top: .45rem; + left: 0; +} + +@media (max-width: 650px) { + + .lcars-list { + margin-left: .5rem; + } + + .lcars-list li::before { + transform: scale(90%); + } +} + +.lcars-bar { + margin-block: 1.75rem; + height: clamp(15px, 2vh, 25px); + background: transparent; + border-right: clamp(15px, 2vh, 25px) solid var(--lcars-bar-end-color); + border-left: clamp(15px, 2vh, 25px) solid var(--lcars-bar-start-color); + border-radius: 100vmax; + position: relative; +} + +.lcars-bar::after { + content: ''; + display: block; + height: clamp(15px, 2vh, 25px); + width: 100%; + background-color: var(--lcars-bar-color); + border-right: .8vh solid black; + border-left: .8vh solid black; + position: absolute; + top: 0; + left: 0; +} + +.lcars-text-bar { + display: flex; + position: relative; + height: clamp(16px, 4vh, 41px); + margin-block: 2.75rem; + overflow: visible; + border-radius: 100vmax; + background-color: var(--lcars-bar-color); + border-right: clamp(16px, 4vh, 43px) solid var(--lcars-bar-end-color); + border-left: clamp(16px, 4vh, 43px) solid var(--lcars-bar-start-color); +} + +.the-end { + justify-content: flex-end; +} + +.lcars-text-bar h2, +.lcars-text-bar h3, +.lcars-text-bar h4, +.lcars-text-bar span { + margin-block: 0; + background-color: black; + height: clamp(20px, 5.5vh, 60px); /* Setting height is a Firefox fix */ + overflow: visible; + border-top: 1px solid black; + padding-inline: 1vh; + font-size: clamp(17px, 4.5vh, 46px); + line-height: 1; + text-transform: uppercase; + color: var(--lcars-bar-text-color); + z-index: 1; + text-box: trim-both cap alphabetic; +} + +.lcars-text-bar::before { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} + +.lcars-text-bar::after { + content: ''; + background-color: black; + display: block; + width: 1vh; + height: 6vh; + position: absolute; + top: 0; + right: 0; + overflow: hidden; +} + +/* Image Frame */ + +.image-frame { + display: block; + margin: 2.75rem auto; + width: fit-content; + background: linear-gradient(var(--primary-color) 56%, var(--secondary-color) 44%); + border-radius: 50px 25px 0 50px; + position: relative; +} + +.image-frame::before { + content: ''; + display: block; + width: 40px; + height: 40px; + background-color: black; + position: absolute; + right: 0; + top: 0; +} + +.image-frame::after { + content: ''; + display: block; + border-top: var(--spacers) solid black; + border-bottom: var(--spacers) solid black; + width: 45px; + height: 80px; + background-color: var(--secondary-color); + position: absolute; + left: 0; + top: 56%; +} + +.imgf-title { + display: flex; + justify-content: flex-end; + height: 40px; + border-right: 40px solid var(--secondary-color); + border-radius: 25px 100vh 100vh 0; + position: relative; + z-index: 1; + text-align: right; +} + +.h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + border-right: var(--spacers) solid black; +} + +.imgf-title h4 { + margin-block: 0; + width: fit-content; + background-color: black; + padding-left: var(--spacers); + font-size: 2.05rem; + color: var(--title-color); + line-height: 40px; + text-transform: uppercase; +} + +.imgf-image-body { + margin-left: 45px; + background-color: black; + width: fit-content; + padding: 1rem; + border-radius: 28px 0 0 28px; + +} + +.image-holder { + width: fit-content; + padding: 1rem; + border: 2px solid var(--image-border-color); + border-radius: 20px; +} + +.imgf-base { + display: grid; + grid-template-columns: 20% 13% 35px 15% 1fr; + margin-left: 80px; + border-left: var(--spacers) solid black; + +} + +.imgf-block-1 { + height: var(--frame-height); + background-color: var(--accent-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-2 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-right: var(--spacers) solid black; +} + +.imgf-block-3 { + height: var(--frame-height); + background-color: black; + border-right: 10px solid var(--secondary-color); + border-left: 10px solid var(--accent-color); +} + +.imgf-block-4 { + height: var(--frame-height); + background-color: var(--secondary-color); + border-left: var(--spacers) solid black; +} + +.imgf-block-5 { + height: var(--frame-height); + background-color: black; +} + +@media (max-width: 750px) { + + .image-frame { + border-radius: 40px 25px 0 40px; + } + + .image-frame::after { + width: 25px; + height: 60px; + top: 50%; + } + + .imgf-title { + height: 25px; + border-right: 24px solid var(--secondary-color); + } + + .h4-wrapper { + width: fit-content; + height: var(--frame-height); + background-color: black; + } + + .imgf-title h4 { + font-size: 1.45rem; + } + + .imgf-image-body { + margin-left: 25px; + padding: .75rem; + border-radius: 20px 0 0 20px; + } + + .image-holder { + padding: .75rem; + border-radius: 10px; + } +} + +/* color styles */ + +.font-cardinal { + color: var(--cardinal) !important; +} + +.button-cardinal, +.background-cardinal, +.bullet-cardinal::before { + background-color: var(--cardinal) !important; +} + +.font-cool { + color: var(--cool) !important; +} + +.button-cool, +.background-cool, +.bullet-cool::before { + background-color: var(--cool) !important; +} + +.font-evening { + color: var(--evening) !important; +} + +.button-evening, +.background-evening, +.bullet-evening::before { + background-color: var(--evening) !important; +} + +.font-galaxy-gray { + color: var(--galaxy-gray) !important; +} + +.button-galaxy-gray, +.background-galaxy-gray, +.bullet-galaxy-gray::before { + background-color: var(--galaxy-gray) !important; +} + +.font-ghost { + color: var(--ghost) !important; +} + +.button-ghost, +.background-ghost, +.bullet-ghost::before { + background-color: var(--ghost) !important; +} + +.font-grape { + color: var(--grape) !important; +} + +.button-grape, +.background-grape, +.bullet-grape::before { + background-color: var(--grape) !important; +} + +.font-honey { + color: var(--honey) !important; +} + +.button-honey, +.background-honey, +.bullet-honey::before { + background-color: var(--honey) !important; +} + +.font-lawn { + color: var(--lawn) !important; +} + +.button-lawn, +.background-lawn, +.bullet-lawn::before { + background-color: var(--lawn) !important; +} + +.font-martian { + color: var(--martian) !important; +} + +.button-martian, +.background-martian, +.bullet-martian::before { + background-color: var(--martian) !important; +} + +.font-midnight { + color: var(--midnight) !important; +} + +.button-midnight, +.background-midnight, +.bullet-midnight::before { + background-color: var(--midnight) !important; +} + +.font-moonbeam { + color: var(--moonbeam) !important; +} + +.button-moonbeam, +.background-moonbeam, +.bullet-moonbeam::before { + background-color: var(--moonbeam) !important; +} + +.font-pumpkinshade { + color: var(--pumpkinshade) !important; +} + +.button-pumpkinshade, +.background-pumpkinshade, +.bullet-pumpkinshade::before { + background-color: var(--pumpkinshade) !important; +} + +.font-roseblush { + color: var(--roseblush) !important; +} + +.button-roseblush, +.background-roseblush, +.bullet-roseblush::before { + background-color: var(--roseblush) !important; +} + +.font-tangerine { + color: var(--tangerine) !important; +} + +.button-tangerine, +.background-tangerine, +.bullet-tangerine::before { + background-color: var(--tangerine) !important; +} + +.font-wheat { + color: var(--wheat) !important; +} + +.button-wheat, +.background-wheat, +.bullet-wheat::before { + background-color: var(--wheat) !important; +} + +/* Footer */ + +footer { + margin-top: 2.5vw; + padding-bottom: 3rem; + padding-left: clamp(20px, 3vw, 50px); + font-size: .875rem; +} + +.meta-data { + margin-bottom: 1rem; + width: fit-content; + font-size: 1.25rem; + border-right: 24px solid var(--cool); + border-left: 24px solid var(--cool); + border-radius: 0 100vmax 100vmax 0; + padding-inline: .375rem; + position: relative; + line-height: 1; + text-box: trim-both cap alphabetic; +} + +.meta-data:before { + content: ''; + display: block; + width: 5px; + height: 2rem; + background-color: black; + position: absolute; + top: 0; + left: -20px; +} + +.headtrim { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + top: 0; + left: 0; + z-index: 999; +} + +.baseboard { + height: 10px; + width: 100%; + background-color: black; + position: fixed; + bottom: 0; + left: 0; + z-index: 999; +} + +/* Grouped @media */ + +@media (max-width: 525px) { + + body { + padding: .25rem; + } + + .baseboard { + display: none; + } + + .wrap { + padding-left: 0; + padding-right: .25rem; + } + + .left-frame { + padding-top: 25px; + } + + .floor-heading { + bottom: 0; + } + + .hop { + display: none; + } + + .floor-text { + font-size: 1.125rem; + } + + blockquote { + margin-left: .75rem; + } +} + +@-moz-document url-prefix() { + + main { + padding-top: clamp(1rem, 4vw, 30px); + } + + h1, h2, h3, h4, p { + margin-block: 1.1rem; + } + + .lcars-text-bar h2, + .lcars-text-bar span { + position: absolute; + top: -.6vh; + } + + .meta-data { + height: 1.15rem; + line-height: 1rem; + } +} + +@-moz-document url-prefix() { + + main { + padding-top: clamp(1rem, 4vw, 30px); + } + + h1, h2, h3, h4, p { + margin-block: 1.15rem; + } + + .imgf-title h4 { + margin-top: -4px; + margin-bottom: 0; + } + + .postmeta { + margin-top: .75rem; + } + + .lcars-text-bar h2, + .lcars-text-bar h3, + .lcars-text-bar h4, + .lcars-text-bar span { + position: absolute; + top: -.7vh; + } + + .lcars-list li::before { + top: .85rem; + } + + .meta-data { + height: 1.15rem; + line-height: 1rem; + } +} \ No newline at end of file diff --git a/lcars_v4/frontend/crew/index.html b/lcars_v4/frontend/crew/index.html new file mode 100644 index 0000000..b82e37b --- /dev/null +++ b/lcars_v4/frontend/crew/index.html @@ -0,0 +1,231 @@ + + + + + Lower Decks PADD + + + + + + + + +
+
+
+ + LCARS + +
02-262000
+
+
+ +
+
+
+
47
+
31
+
28
+
94
+
+
+
329
+
128
+
605
+
704
+
+
+
39725514862
+
51320259663
+
21857221984
+
40372566301
+
+
+
56
+
04
+
40
+
35
+
+
+
614
+
883
+
109
+
297
+
+
+
000
+
13
+
05
+
25
+
+
+
48
+
07
+
38
+
62
+
+
+
416
+
001
+
888
+
442
+
+
+
86225514862
+
31042009183
+
74882306985
+
54048523421
+
+
+
10
+
80
+
31
+
85
+
+
+
87
+
71
+
40
+
26
+
+
+
98
+
63
+
52
+
71
+
+
+
118
+
270
+
395
+
260
+
+
+
8675309
+
7952705
+
9282721
+
4981518
+
+
+
000
+
99
+
10
+
84
+
+
+
65821407321
+
54018820533
+
27174523016
+
38954062564
+
+
+
999
+
202
+
574
+
293
+
+
+
3872
+
1105
+
1106
+
7411
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + +
+
03-111968
+
04-041969
+
05-1701D
+
06-071984
+
+
+
07-081940
+
+
+
+
+
+
+
+
+
+
+
+

Crew Sheet

+ +
+
+ + Content Copyright © 2025 ld.hedeler.com
+ + + LCARS Inspired Website Template by www.TheLCARS.com. +
+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/lcars_v4/frontend/index.html b/lcars_v4/frontend/index.html new file mode 100644 index 0000000..69f2980 --- /dev/null +++ b/lcars_v4/frontend/index.html @@ -0,0 +1,232 @@ + + + + + Lower Decks PADD + + + + + + + + + +
+
+
+ + +
02-262000
+
+
+ +
+
+
+
47
+
31
+
28
+
94
+
+
+
329
+
128
+
605
+
704
+
+
+
39725514862
+
51320259663
+
21857221984
+
40372566301
+
+
+
56
+
04
+
40
+
35
+
+
+
614
+
883
+
109
+
297
+
+
+
000
+
13
+
05
+
25
+
+
+
48
+
07
+
38
+
62
+
+
+
416
+
001
+
888
+
442
+
+
+
86225514862
+
31042009183
+
74882306985
+
54048523421
+
+
+
10
+
80
+
31
+
85
+
+
+
87
+
71
+
40
+
26
+
+
+
98
+
63
+
52
+
71
+
+
+
118
+
270
+
395
+
260
+
+
+
8675309
+
7952705
+
9282721
+
4981518
+
+
+
000
+
99
+
10
+
84
+
+
+
65821407321
+
54018820533
+
27174523016
+
38954062564
+
+
+
999
+
202
+
574
+
293
+
+
+
3872
+
1105
+
1106
+
7411
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + +
+
03-111968
+
04-041969
+
05-1701D
+
06-071984
+
+
+
07-081940
+
+
+
+
+
+
+
+
+
+
+
+

Lower Decks PADD

+ +
+
+ + Content Copyright © 2025 ld.hedeler.com
+ + + LCARS Inspired Website Template by www.TheLCARS.com. +
+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/lcars_v4/frontend/tinyserver.go b/lcars_v4/frontend/tinyserver.go new file mode 100644 index 0000000..fc97222 --- /dev/null +++ b/lcars_v4/frontend/tinyserver.go @@ -0,0 +1,39 @@ +package main + +import ( + "log" + "net/http" + "path/filepath" + "strings" +) + +func main() { + // Folder to serve + dir := "." + + // File server handler + fs := http.FileServer(http.Dir(dir)) + + // Wrap the file server to add caching headers + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ext := strings.ToLower(filepath.Ext(r.URL.Path)) + + // Set long caching for static assets + switch ext { + case ".css", ".js", ".woff", ".woff2", ".ttf", ".eot", ".svg", ".png", ".jpg", ".jpeg", ".gif": + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + default: + // Optional: short caching for HTML so you always get latest page + w.Header().Set("Cache-Control", "no-cache") + } + + fs.ServeHTTP(w, r) + }) + + addr := ":8080" + log.Printf("Serving %s on http://localhost%s\n", dir, addr) + err := http.ListenAndServe(addr, handler) + if err != nil { + log.Fatal(err) + } +} diff --git a/lcars_v4/go.mod b/lcars_v4/go.mod new file mode 100644 index 0000000..5a773da --- /dev/null +++ b/lcars_v4/go.mod @@ -0,0 +1,18 @@ +module ld + +go 1.25.0 + +require modernc.org/sqlite v1.39.0 + +require ( + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/sys v0.34.0 // indirect + modernc.org/libc v1.66.3 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.11.0 // indirect +) diff --git a/lcars_v4/go.sum b/lcars_v4/go.sum new file mode 100644 index 0000000..c46fb2d --- /dev/null +++ b/lcars_v4/go.sum @@ -0,0 +1,49 @@ +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM= +modernc.org/cc/v4 v4.26.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= +modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= +modernc.org/fileutil v1.3.8 h1:qtzNm7ED75pd1C7WgAGcK4edm4fvhtBsEiI/0NQ54YM= +modernc.org/fileutil v1.3.8/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= +modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ= +modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/sqlite v1.39.0 h1:6bwu9Ooim0yVYA7IZn9demiQk/Ejp0BtTjBWFLymSeY= +modernc.org/sqlite v1.39.0/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/lcars_v4/interval/interval.go b/lcars_v4/interval/interval.go new file mode 100644 index 0000000..e755d5e --- /dev/null +++ b/lcars_v4/interval/interval.go @@ -0,0 +1,94 @@ +package interval + +import ( + "errors" + "math/rand" + "sync" + "time" +) + +type MutexMap[K comparable, V any] struct { + mutex sync.Mutex + m map[K]V +} + +func (m *MutexMap[K, V]) Get(key K) (V, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + v, ok := m.m[key] + if !ok { + return v, errors.New("unknown key") + } + return v, nil +} + +func (m *MutexMap[K, V]) Set(key K, value V) { + m.mutex.Lock() + defer m.mutex.Unlock() + + m.m[key] = value +} + +func (m *MutexMap[K, V]) Delete(key K) { + m.mutex.Lock() + defer m.mutex.Unlock() + + delete(m.m, key) +} + +var stopChannels = MutexMap[int, chan bool]{ + m: make(map[int]chan bool), +} + +// SetInterval schedules a repeating task to be executed at a specified interval. +func SetInterval(f func(), milliseconds int) (id int) { + for { + id = rand.Int() + if _, err := stopChannels.Get(id); err == nil { + continue // ID collision, keep looking for another unique random value + } + break + } + + stop := make(chan bool) + stopChannels.Set(id, stop) + + ticker := time.NewTicker(time.Duration(milliseconds) * time.Millisecond) + + go func() { + for { + select { + case <-stop: + ticker.Stop() + return + case <-ticker.C: + f() + } + } + }() + + return +} + +// ClearInterval stops a scheduled interval identified by the specified interval ID. +func ClearInterval(id int) error { + stop, err := stopChannels.Get(id) + if err != nil { + return err + } + stop <- true + stopChannels.Delete(id) + + return nil +} + +// SetTimeout schedules a one-time task to be executed after a specified interval. +func SetTimeout(f func(), milliseconds int) { + timer := time.NewTimer(time.Duration(milliseconds) * time.Millisecond) + go func() { + <-timer.C + timer.Stop() + f() + }() +} diff --git a/lcars_v4/main.go b/lcars_v4/main.go new file mode 100644 index 0000000..e06396c --- /dev/null +++ b/lcars_v4/main.go @@ -0,0 +1,221 @@ +package main + +import ( + "embed" + "fmt" + "ld/eventbus" + "ld/interval" + "ld/server" + "ld/sqlite" + "log" + "os" + "os/signal" + "path/filepath" + "strings" + "syscall" +) + +const ( + exitCodeErr = 1 + exitCodeInterrupt = 2 +) + +var AppRoot = "./" // path for supporting files that sit in app root folder in production + +//go:embed frontend/* +var frontend embed.FS + +//go:embed embed +var embedded embed.FS + +// main specific variables +var ExecutableName string + +func main() { + fmt.Println("Here") + err := run() + if err != nil { + os.Exit(exitCodeErr) + } + ExecutableName, err = getExecutableName() + if err != nil { + os.Exit(exitCodeErr) + } + + // readCrew() + + // readMessages() + ebus := eventbus.NewEventBus() + + interval.SetInterval(func() { + fmt.Println("------------------") + }, 10) + + interval.SetInterval(func() { + ebus.Publish("foo:baz", eventbus.Data{"value": "Hallo Welt"}) + }, 100) + + runEventbus(ebus) + + run() + +} + +func runEventbus(ebus *eventbus.EventBus) { + + // Create a new instance + eventChannel := eventbus.NewEventChannel() + + // Subscribe to "foo:baz" - or use a wildcard like "foo:*" + ebus.SubscribeChannel("foo:baz", eventChannel) + ebus.SubscribeChannel("pups-klo", eventChannel) + ebus.SubscribeChannel("ömme*", eventChannel) + + eventChannelTopic := ebus.Subscribe("ömmels") + + // Subscribe with existing channel use + // eventbus.SubscribeChannel("foo:*", eventChannel) + + // Wait for the incoming event on the channel + go func() { + + for evt := range eventChannel { + fmt.Println("FIRST", evt.Topic, evt.Data) + evt.Done() + } + + }() + go func() { + + for evt := range eventChannel { + fmt.Println("SECOND", evt.Topic, evt.Data) + evt.Done() + } + }() + + go func() { + + for evt := range eventChannelTopic { + fmt.Println("ÖMMELS", evt.Topic, evt.Data) + evt.Done() + } + }() + + for i := 0; i < 1000; i++ { + + ebus.Publish("foo:baz", eventbus.Data{"value": i}) + ebus.Publish("pups-klo", eventbus.Data{"value": i}) + ebus.Publish("pups-klo", eventbus.Data{"value": i}) + ebus.Publish("ömmels", eventbus.Data{"value": i}) + ebus.Publish("ömmels", eventbus.Data{"value": i * 10}) + ebus.Publish("ömmels", eventbus.Data{"value": i * 100}) + } + +} + +func run() error { + + // setting up logging to file + logFileName := AppRoot + ExecutableName + ".log" + logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Printf("error opening file: %v", err) + os.Exit(exitCodeErr) + } + defer logFile.Close() + log.SetOutput(logFile) + + stateDB, err := createStateDB(true) + if err != nil { + log.Fatalf("Failed to create internal StateDB: %v", err) + } + + // setting up the server + server, err := server.New( + logFileName, + stateDB, + embedded, + ) + + if err != nil { + log.Fatalf("server-app not created - error: %v", err) + } + + // tasks.SetupTasks(server) + + err = server.Start() + if err != nil { + fmt.Printf("server not started - error: %v \n", err) + log.Fatalf("server not started - error: %v", err) + } + + readCrew(server) + readMessages(server) + // return nil + + // listen for os shutdown events, report them into log file and exit application + chanOS := make(chan os.Signal, 2) + signal.Notify(chanOS, os.Interrupt, syscall.SIGTERM) + go func() { + <-chanOS + log.Println("shutting down request signal received") + server.Close() + os.Exit(exitCodeInterrupt) + }() + + // setting up the routes, hooking up API endpoints with backend functions + // routes.SetupRoutes(server) + + return nil + +} + +// some internal functions + +func getExecutableName() (string, error) { + name, err := os.Executable() + if err != nil { + return "", err + } + name = filepath.Base(name) + return strings.TrimSuffix(name, filepath.Ext(name)), nil +} + +func createStateDB(StateDBDelete bool) (*sqlite.Database, error) { + + // fileName := fmt.Sprintf("state-%s.db", ulid.Make()) + + fileName := "state.db" + + if StateDBDelete { + _, err := os.Stat(fileName) + if err == nil { + err := os.Remove(fileName) + if err != nil { + log.Fatal("error deleting statedb-file:", err) + } + } + } + + db, err := sqlite.New(fileName) + if err != nil { + return nil, err + } + + err = db.Open() + if err != nil { + return nil, err + } + + query, err := embedded.ReadFile("embed/create_state_db.sql") + if err != nil { + return nil, err + } + + _, err = db.DB().Exec(string(query)) + if err != nil { + return nil, err + } + + return db, nil +} diff --git a/lcars_v4/notes.txt b/lcars_v4/notes.txt new file mode 100644 index 0000000..874fb6d --- /dev/null +++ b/lcars_v4/notes.txt @@ -0,0 +1,2 @@ +Nächste-Generation Abzeichen Icon von Icons8 +Geek icons created by Pixel perfect - Flaticon diff --git a/lcars_v4/server/server.go b/lcars_v4/server/server.go new file mode 100644 index 0000000..75310bc --- /dev/null +++ b/lcars_v4/server/server.go @@ -0,0 +1,105 @@ +// Copyright 2024 codeM GmbH +// Author: Thomas Hedeler +package server + +import ( + "embed" + "ld/eventbus" + "ld/interval" + "ld/sqlite" + "log" +) + +type Server struct { + SQLiteVersion string + ServerInfo map[string]any + StateDB *sqlite.Database + Embedded embed.FS + LogFileName string + TokenDuration int // TODO einbauen + Secret []byte + Header string + intervalID int + Ebus *eventbus.EventBus + Tasks map[string]TaskFunc +} + +func New( + logfilename string, + StateDB *sqlite.Database, + embedded embed.FS, + +) (*Server, error) { + + // creating the server + return &Server{ + LogFileName: logfilename, + StateDB: StateDB, + Embedded: embedded, + Tasks: make(map[string]func(s *Server) error), + }, nil +} + +func (s *Server) Start() error { + + // query, err := s.Embedded.ReadFile("embed/win/server_info.sql") + // if err != nil { + // return err + // } + + // res, err := s.StundenDB.ReadRecords(string(query)) + // if err != nil { + // return err + // } + + // s.ServerInfo = res[0] + + // err = inits.LoadLogins(s.StundenDB, s.StateDB) + // if err != nil { + // return err + // } + + // err = inits.LoadTasks(s.StundenDB, s.StateDB) + // if err != nil { + // return err + // } + + // // start the task engine + // if s.Production { + // s.intervalID = interval.SetInterval(s.interval, 60000) // check for executable tasks every 60 seconds + // } else { + // s.intervalID = interval.SetInterval(s.interval, 30000) // check for executable tasks every 30 seconds + // } + return nil +} + +func (s *Server) Close() error { + + // stop the task engine + err := interval.ClearInterval(s.intervalID) + if err != nil { + log.Print(err) + } + + err = s.StateDB.Close() + if err != nil { + log.Print(err) + } + return err +} + +// func to dispatch routes to all parts of the application: +// they receive references to the server and the current fiber context via closures +// this way all functions have access to server properties and can handle the +// incoming requests themselves. + +// type HandlerFunc = func(s *Server, c *fiber.Ctx) error + +// func (s *Server) Handler(handler HandlerFunc) func(c *fiber.Ctx) error { +// return func(c *fiber.Ctx) error { +// return handler(s, c) +// } +// } + +// signature for internal tasks +type TaskFunc = func(s *Server) error diff --git a/lcars_v4/server/taskengine.go b/lcars_v4/server/taskengine.go new file mode 100644 index 0000000..7062e81 --- /dev/null +++ b/lcars_v4/server/taskengine.go @@ -0,0 +1,118 @@ +package server + +import ( + "log" + "time" +) + +// this function schedules the tasks and will be called periodically, see server.Start() +func (s *Server) interval() { + + // read scheduled task list from stateDB + // check for next executable task: + // - if there is one or more tasks ready for execution then select one of them. + // - if there is a selected task, update its next execution field and execute the task + + defer func() { + if r := recover(); r != nil { + // fmt.Println("Recovered from panic in worker:", r) + log.Printf("recovered from panic in taskengine: %v ", r) + } + }() + + tasks, err := s.StateDB.ReadRecords("SELECT * FROM tasks ORDER by next_execution limit 1;") + + if err != nil { + log.Printf("error in taskengine: %s ", err) + return + } + + if len(tasks) < 1 { + log.Printf("error in taskengine: %s ", "found no task for execution") + return + } + + task := tasks[0] // pick the one task with the smallest next execution time, see previous sql statement + + task_name, haveTask := task["task_name"].(string) + if !haveTask { + log.Printf("error in taskengine: task %s is of wrong type", task["task_name"]) + return + } + + nextExecution := task["next_execution"].(int64) + startTime := task["start_time"].(int64) + execInterval := task["interval"].(int64) + nowSeconds := time.Now().Unix() + + if nowSeconds < nextExecution { // task execution is not yet due + return + } + + // calculate next execution time + for nextExecution = startTime; nowSeconds > nextExecution; nextExecution += execInterval { + // add as many intervals to the starttime until the next execution lies in the future + } + + task["start_time"] = task["next_execution"] + task["next_execution"] = nextExecution + + /* + no_executions INTEGER, -- how often executed + duration INTEGER, -- duration of the last exec in ms + no_errors INTEGER, -- error count + last_error_text TEXT, + + */ + + if count, ok := task["no_executions"].(int64); ok { + task["no_executions"] = count + 1 + } + + // update next_execution in state database + _, err = s.StateDB.UpsertRecord("tasks", "task_id", task) + if err != nil { + log.Printf("error in taskengine: cannot update task record - before execution %s ", err) + return + } + + task_func, haveTask := s.Tasks[task_name] // select the function with the matching name + + if !haveTask { + log.Printf("error in taskengine: task %s is not defined", task_name) + } + + if haveTask { + + start := time.Now() + // if !s.Production { + // fmt.Println("Taskengine: executing task:", task_name, start) + // } + err = task_func(s) // finally execute the task; attention: a task that panics will kill the server! + + task["duration"] = int(time.Since(start).Milliseconds()) + + if err != nil { + log.Printf("taskengine: execution task: %s failed with error: %s ", task_name, err) + task["last_error_text"] = err.Error() + if count, ok := task["no_errors"].(int64); ok { + task["no_errors"] = count + 1 + } + // if !s.Production { + // fmt.Println("Taskengine: failed task:", task_name, err) + // } + } else { + // if !s.Production { + // fmt.Println("Taskengine: successfully completed task:", task_name, time.Now()) + // } + } + + _, err = s.StateDB.UpsertRecord("tasks", "task_id", task) + if err != nil { + log.Printf("error in taskengine: cannot update task record - after execution %s ", err) + return + } + + } + +} diff --git a/lcars_v4/sqlite/database.go b/lcars_v4/sqlite/database.go new file mode 100644 index 0000000..7e4aace --- /dev/null +++ b/lcars_v4/sqlite/database.go @@ -0,0 +1,440 @@ +package sqlite // name the package as you see fit + +import ( + "database/sql" + "errors" + "fmt" + "os" + "strconv" + "strings" + + _ "modernc.org/sqlite" +) + +// This is the data type to exchange data with the database +type Record = map[string]any + +type Database struct { + databaseName string + database *sql.DB +} + +type Transaction struct { + tx *sql.Tx + err error +} + +type Action func(tx *sql.Tx) error + +func New(DBName string) (*Database, error) { + return &Database{databaseName: DBName}, nil +} + +func (d *Database) Close() error { + query := ` + PRAGMA analysis_limit = 400; + PRAGMA optimize; + ` + _, err := d.DB().Exec(query) + if err != nil { + return err + } + return d.database.Close() +} + +// provides access to the internal database object +func (d *Database) DB() *sql.DB { + return d.database +} + +func (d *Database) Name() string { + return d.databaseName +} + +func (d *Database) Open() (err error) { + d.database, err = openSqliteDB(d.databaseName) + return err +} + +func (d *Database) OpenInMemory() (err error) { + d.database, err = sql.Open("sqlite", ":memory:") + return err +} + +func openSqliteDB(databasefilename string) (*sql.DB, error) { + + _, err := os.Stat(databasefilename) + if errors.Is(err, os.ErrNotExist) { + return createDB(databasefilename) + } + if err != nil { + return nil, err + } + return sql.Open("sqlite", databasefilename) + +} + +func createDB(dbfileName string) (*sql.DB, error) { + + query := ` + PRAGMA synchronous = off; + PRAGMA foreign_keys = on; + PRAGMA journal_mode = WAL; + PRAGMA busy_timeout = 5000; + PRAGMA cache_size = 2000; + PRAGMA temp_store = memory; + PRAGMA mmap_size = 30000000000; + PRAGMA page_size = 4096; + PRAGMA user_version = 1; + ` + db, err := sql.Open("sqlite", dbfileName) + if err != nil { + + return nil, err + } + _, err = db.Exec(query) + if err != nil { + return nil, err + } + return db, nil +} + +func (d *Database) TableList() (result []Record, err error) { + return d.ReadRecords("select name from sqlite_master where type='table';") +} + +func (d *Database) ReadTable(tablename string) (result []Record, err error) { + + return d.ReadRecords(fmt.Sprintf("select * from '%s';", tablename)) +} + +func (d *Database) ReadRecords(query string, args ...any) (result []Record, err error) { + + rows, err := d.DB().Query(query, args...) + if err != nil { + return result, err + } + defer rows.Close() + return Rows2records(rows) + +} + +func (d *Database) GetRecord(tablename string, idfield string, key any) (result Record, err error) { + + query := fmt.Sprintf("select * from %s where %s = ?;", tablename, idfield) + res, err := d.DB().Query(query, key) + if err != nil { + return result, err + } + defer res.Close() + return Rows2record(res) + +} + +func (d *Database) UpsertRecord(tablename string, idfield string, record Record) (result Record, err error) { + + return upsert(d.DB(), tablename, idfield, record) + +} + +func (d *Database) DeleteRecord(tablename string, idfield string, id any) (err error) { + + return deleteRecord(d.DB(), tablename, idfield, id) + +} + +// *sql.DB and *sql.Tx both have a method named 'Query', +// this way they can both be passed into upsert and deleteRecord function +type iquery interface { + Query(query string, args ...any) (*sql.Rows, error) +} + +func upsert(t iquery, tablename string, idfield string, record Record) (result Record, err error) { + + fields := []string{} + data := []any{} + for k, v := range record { + fields = append(fields, k) + data = append(data, v) + } + query, err := buildUpsertCommand(tablename, idfield, fields) + if err != nil { + return result, err + } + res, err := t.Query(query, data...) // res contains the full record - see SQLite: RETURNING * + if err != nil { + return result, err + } + defer res.Close() + return Rows2record(res) + +} + +func deleteRecord(t iquery, tablename string, idfield string, id any) (err error) { + + query := fmt.Sprintf("DELETE FROM \"%s\" WHERE \"%s\" = ?;", tablename, idfield) + _, err = t.Query(query, id) + return err + +} + +func buildUpsertCommand(tablename string, idfield string, fields []string) (string, error) { + var sb strings.Builder + sb.Grow(256 + len(fields)*20) // rough preallocation + + // INSERT INTO + sb.WriteString(`INSERT INTO "`) + sb.WriteString(tablename) + sb.WriteString(`"(`) + for i, f := range fields { + sb.WriteString(` "`) + sb.WriteString(f) + sb.WriteByte('"') + if i < len(fields)-1 { + sb.WriteByte(',') + } + } + sb.WriteString(")\n\tVALUES(") + + // VALUES + for i := 0; i < len(fields); i++ { + sb.WriteString(" ?") + sb.Write(strconv.AppendInt(nil, int64(i+1), 10)) + if i < len(fields)-1 { + sb.WriteByte(',') + } + } + sb.WriteString(")\n\tON CONFLICT(\"") + sb.WriteString(tablename) + sb.WriteString(`"."`) + sb.WriteString(idfield) + sb.WriteString("\")\n\tDO UPDATE SET ") + + // UPDATE SET + for i, f := range fields { + sb.WriteByte('"') + sb.WriteString(f) + sb.WriteString(`"= ?`) + sb.Write(strconv.AppendInt(nil, int64(i+1), 10)) + if i < len(fields)-1 { + sb.WriteByte(',') + } + } + sb.WriteString("\n\tRETURNING *;") + + return sb.String(), nil +} + +// func buildUpsertCommand(tablename string, idfield string, fields []string) (result string, err error) { + +// pname := map[string]string{} // assign correct index for parameter name +// // parameter position, starts at 1 in sql! So it needs to be calculated by function pname inside template + +// for i, k := range fields { +// pname[k] = strconv.Itoa(i + 1) +// } +// funcMap := template.FuncMap{ +// "pname": func(fieldname string) string { +// return pname[fieldname] +// }, +// } +// tableDef := struct { +// Tablename string +// KeyField string +// LastField int +// FieldNames []string +// }{ +// Tablename: tablename, +// KeyField: idfield, +// LastField: len(fields) - 1, +// FieldNames: fields, +// } +// var templString = `{{$last := .LastField}}INSERT INTO "{{ .Tablename }}"({{ range $i,$el := .FieldNames }} "{{$el}}"{{if ne $i $last}},{{end}}{{end}}) +// VALUES({{ range $i,$el := .FieldNames }} ?{{pname $el}}{{if ne $i $last}},{{end}}{{end}}) +// ON CONFLICT("{{ .Tablename }}"."{{.KeyField}}") +// DO UPDATE SET {{ range $i,$el := .FieldNames }}"{{$el}}"= ?{{pname $el}}{{if ne $i $last}},{{end}}{{end}} +// RETURNING *;` + +// dbTempl, err := template.New("upsertDB").Funcs(funcMap).Parse(templString) +// if err != nil { +// return result, err +// } +// var templBytes bytes.Buffer +// err = dbTempl.Execute(&templBytes, tableDef) +// if err != nil { +// return result, err +// } +// return templBytes.String(), nil +// } + +func Rows2record(rows *sql.Rows) (Record, error) { + columns, err := rows.Columns() + if err != nil { + return nil, err + } + values := make([]any, len(columns)) + valuePtrs := make([]any, len(columns)) + for i := range values { + valuePtrs[i] = &values[i] + } + result := Record{} + for rows.Next() { + if err := rows.Scan(valuePtrs...); err != nil { + return nil, err + } + for i, col := range columns { + result[col] = values[i] + } + } + if len(result) == 0 { + return nil, errors.New("no rows found") + } + return result, nil +} + +func Rows2records(rows *sql.Rows) ([]Record, error) { + columns, err := rows.Columns() + if err != nil { + return nil, err + } + recLength := len(columns) + results := []Record{} + for rows.Next() { + values := make([]any, recLength) + valuePtrs := make([]any, recLength) + for i := range values { + valuePtrs[i] = &values[i] + } + record := Record{} + if err := rows.Scan(valuePtrs...); err != nil { + return nil, err + } + for i, col := range columns { + record[col] = values[i] + } + results = append(results, record) + } + if len(results) == 0 { + return nil, errors.New("no rows found") + } + return results, nil +} + +func (d *Database) Version() (string, error) { + result := "" + sqliteversion, err := d.ReadRecords("SELECT sqlite_version();") + if len(sqliteversion) == 1 { + result = sqliteversion[0]["sqlite_version()"].(string) + } + return result, err +} + +func (d *Database) UserVersion() (int64, error) { + + var result int64 + userversion, err := d.ReadRecords("PRAGMA user_version;") + if len(userversion) == 1 { + result = userversion[0]["user_version"].(int64) + } + return result, err +} + +func (d *Database) Begin() *Transaction { + tx, err := d.database.Begin() + return &Transaction{tx, err} +} + +func (t *Transaction) Next(action Action) *Transaction { + if t.err != nil { + return t + } + t.err = action(t.tx) + return t +} + +func (t *Transaction) End() error { + + if t.err != nil { + err := t.tx.Rollback() + if err != nil { + t.err = errors.Join(t.err, err) + } + return t.err + } + t.err = t.tx.Commit() + return t.err +} + +func (t *Transaction) GetRecord(tablename string, idfield string, key any, output Record) *Transaction { + + if t.err != nil { + return t + } + query := fmt.Sprintf("select * from %s where %s = ?;", tablename, idfield) + res, err := t.tx.Query(query, key) + if err != nil { + t.err = err + return t + } + defer res.Close() + result, err := Rows2record(res) + if err != nil { + t.err = err + return t + } + for k := range output { + delete(output, k) + } + for k, v := range result { + output[k] = v + } + return t +} + +func (t *Transaction) UpsertRecord(tablename string, idfield string, record Record, output Record) *Transaction { + + if t.err != nil { + return t + } + result, err := upsert(t.tx, tablename, idfield, record) + if err != nil { + t.err = err + return t + } + for k := range output { + delete(output, k) + } + for k, v := range result { + output[k] = v + } + return t +} + +func (t *Transaction) DeleteRecord(tablename string, idfield string, id any) *Transaction { + + if t.err != nil { + return t + } + err := deleteRecord(t.tx, tablename, idfield, id) + if err != nil { + t.err = err + } + return t +} + +// returns a value of the provided type, if the field exist and if it can be cast into the provided type parameter +func Value[T any](rec Record, field string) (value T, ok bool) { + var v any + if v, ok = rec[field]; ok { + value, ok = v.(T) + } + return +} + +// don't report an error if there are simply just 'no rows found' +func NoRowsOk(recs []Record, err error) ([]Record, error) { + if err != nil && err.Error() != "no rows found" { + return recs, err + } + return recs, nil +} diff --git a/lcars_v4/state/events.go b/lcars_v4/state/events.go new file mode 100644 index 0000000..c3df2a6 --- /dev/null +++ b/lcars_v4/state/events.go @@ -0,0 +1,2 @@ +package state +