PageSourceSearch

https://openelectricity.org.au/_app/immutable/nodes/33.adpLFS6J.js

js openelectricity.org.au collected 2026-09-24 18:24:26 UTC 56,565 bytes, 65 lines download raw bytes

1import"../chunks/DsnmJJEf.js";import{p as J,c as a,n as be,r as e,a as p,e as Y,f as y,t as $,h as o,u as je,s as t,o as Za,A as qa,bS as re,i as b,m as Ue,aJ as Ka,k as La,l as Xe,d as Ne,j as G,af as Ja,bx as Ya}from"../chunks/CrZWGQw6.js";import{d as Qa,a as er,s as h}from"../chunks/Cf9b1Pg_.js";import{p as O,r as Ve,i as Lt}from"../chunks/Dm50tvsH.js";import{e as W}from"../chunks/DvQYBH6E.js";import{c as ue}from"../chunks/DyozxAKL.js";import{b as Ze,r as tr,d as ar,s as M,g as rr,a as z}from"../chunks/DnKQ9cPv.js";import{s as P,c as sr}from"../chunks/Dz3h3GFh.js";import{b as or}from"../chunks/B6lfLGkN.js";import{M as lr}from"../chunks/C6J9WEQ1.js";import{P as dr}from"../chunks/BWliB-Sv.js";import{L as va}from"../chunks/CDZbqm4B.js";import{f as kt}from"../chunks/b1-d2NKg.js";import{s as ir}from"../chunks/DyZpPvjy.js";import{f as $a}from"../chunks/DpT7U2b2.js";import{s as nr}from"../chunks/BhRC-2Xl.js";import{b as cr}from"../chunks/D9ZWH3BP.js";import{g as Ca,s as se}from"../chunks/BvaVSrWj.js";import{M as pr}from"../chunks/BTUFzwLv.js";import{B as _t}from"../chunks/B7yIcEVE.js";import{B as mr}from"../chunks/Cu-ihsLb.js";import{T as ya}from"../chunks/BEvl4EX7.js";import{C as ze}from"../chunks/Dj5ASKCM.js";import{p as hr}from"../chunks/CdEA5IGF.js";import{B as ve}from"../chunks/VQwJAxmi.js";import{C as gr}from"../chunks/Ba2-glw5.js";import{C as xr}from"../chunks/Cgnbp7YL.js";import{s as qe}from"../chunks/DxT3OYjk.js";import{b as Ke}from"../chunks/C6XItoiV.js";import{c as $t}from"../chunks/Cj793bts.js";import{s as ur,r as vr}from"../chunks/Bvlpv5_J.js";import{s as yr}from"../chunks/Bs7x1FIf.js";import{v as br}from"../chunks/BEx8-u_O.js";import{F as fr}from"../chunks/Bo7IB98g.js";import{C as wr}from"../chunks/BW-3m-K5.js";import{X as _r}from"../chunks/DdM7QLiR.js";import{S as kr}from"../chunks/DM5aLcJM.js";import{A as Lr}from"../chunks/AP1_gpYh.js";import{A as $r}from"../chunks/I9Efsl3z.js";import{C as Cr,S as Sr,c as Tr}from"../chunks/sCrROROJ.js";import{g as Mr,S as Fr}from"../chunks/CJs61MB3.js";import"../chunks/CUdGVStK.js";import{i as Ar}from"../chunks/BF832CT1.js";import"../chunks/fvGWXswz.js";import"../chunks/ClttB-im.js";import{h as jr,i as Dr}from"../chunks/nCywSm-s.js";import"../chunks/4zIuwugW.js";import"../chunks/BB0OkHMs.js";import"../chunks/BgtS7yHa.js";import{g as Er}from"../chunks/C-sV3ZCx.js";import"../chunks/CIwIcka0.js";import{g as Pr}from"../chunks/BZgZkgzk.js";import{R as Br}from"../chunks/Qn5fwYF3.js";import{D as ba}from"../chunks/CRma1Vqn.js";var Gr=new Set(["$$slots","$$events","$$legacy","ref","class","children"]),Rr=y("<p><!></p>");function Wr(k,d){J(d,!0);let u=O(d,"ref",15,null),x=Ve(d,Gr);var n=Rr();Ze(n,g=>({"data-slot":"card-description",class:g,...x}),[()=>$t("text-muted-foreground text-sm",d.class)]);var v=a(n);qe(v,()=>d.children??be),e(n),Ke(n,g=>u(g),()=>u()),p(k,n),Y()}var Or=new Set(["$$slots","$$events","$$legacy","ref","class","children"]),Hr=y("<div><!></div>");function Ir(k,d){J(d,!0);let u=O(d,"ref",15,null),x=Ve(d,Or);var n=Hr();Ze(n,g=>({"data-slot":"card-header",class:g,...x}),[()=>$t("@container/card-header has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6 grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6",d.class)]);var v=a(n);qe(v,()=>d.children??be),e(n),Ke(n,g=>u(g),()=>u()),p(k,n),Y()}var Nr=new Set(["$$slots","$$events","$$legacy","ref","class","children"]),zr=y("<div><!></div>");function Ur(k,d){J(d,!0);let u=O(d,"ref",15,null),x=Ve(d,Nr);var n=zr();Ze(n,g=>({"data-slot":"card-title",class:g,...x}),[()=>$t("font-semibold leading-none",d.class)]);var v=a(n);qe(v,()=>d.children??be),e(n),Ke(n,g=>u(g),()=>u()),p(k,n),Y()}var Xr=y('<label><input class="peer absolute inset-0 size-full cursor-pointer opacity-0" type="radio"/> <span class="rounded-md border-solid border-[0.05rem] border-mid-warm-grey p-4 font-sans text-sm peer-checked:border-dark-grey peer-checked:bg-light-warm-grey peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-dark-grey"> </span></label>');function fa(k,d){J(d,!0);let u=O(d,"changeHandler",3,null),x=O(d,"name",3,""),n=O(d,"label",3,""),v=O(d,"value",3,""),g=O(d,"checked",3,!1);var c=Xr(),f=a(c);tr(f);var F=je(()=>hr(u())),C=t(f,2),i=a(C,!0);e(C),e(c),$(()=>{P(c,1,`label relative ${d.class??""}`,"svelte-1kds3rm"),ar(f,v()),M(f,"name",x()),rr(f,g()),h(i,n())}),er("change",f,function(...L){o(F)?.apply(this,L)}
1),p(k,c),Y()}Qa(["change"]);var Vr=new Set(["$$slots","$$events","$$legacy"]),Zr=Za('<svg><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path></svg>');function qr(k,d){let u=Ve(d,Vr);var x=Zr();Ze(x,()=>({role:"img",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",class:"w-6 h-6",...u})),p(k,x)}var Kr=y('<div class="font-mono text-xxs text-mid-grey mt-1"> </div>'),Jr=y('<div class="border border-warm-grey rounded-lg overflow-hidden bg-white"><div class="h-16 flex items-end px-3 py-2"><span class="font-mono text-xxs"> </span></div> <div class="px-3 py-2"><div class="font-space text-xs font-medium leading-xs"> </div> <!></div></div>'),Yr=y('<div class="grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3"></div>');function ye(k,d){J(d,!0);var u=Yr();W(u,21,()=>d.items,x=>x.name,(x,n)=>{var v=Jr(),g=a(v);let c;var f=a(g);let F;var C=a(f,!0);e(f),e(g);var i=t(g,2),L=a(i),A=a(L,!0);e(L);var w=t(L,2);{var j=D=>{var E=Kr(),U=a(E,!0);e(E),$(()=>h(U,o(n).note)),p(D,E)};Lt(w,D=>{o(n).note&&D(j)})}e(i),e(v),$(D=>{c=z(g,"",c,{"background-color":o(n).hex}),F=z(f,"",F,D),h(C,o(n).hex),h(A,o(n).name)},[()=>({color:Ca(o(n).hex)})]),p(x,v)}),e(u),p(k,u),Y()}function Qr(k,d){J(d,!1);const u=[["coal_black",i=>6-1.2*Math.exp(-(((i-26)/9)**2))],["gas_ccgt",i=>.8+.9*Math.exp(-(((i-37)/5)**2))+.3*Math.sin(i/4)],["hydro",i=>1+.8*Math.exp(-(((i-38)/6)**2))+.2*Math.sin(i/3+1)],["wind",i=>2.2+.9*Math.sin(i/6+2)+.3*Math.sin(i/2.5)],["solar_utility",i=>Math.max(0,3.6*Math.exp(-(((i-24)/7.5)**2)))],["solar_rooftop",i=>Math.max(0,2.8*Math.exp(-(((i-24)/6.5)**2)))]],x=Date.UTC(2026,0,14,13,0),n=1800*1e3,v=Array.from({length:49},(i,L)=>{const A=x+L*n,w={time:A,date:new Date(A)};for(const[j,D]of u)w[j]=Math.round(D(L)*1e3);return w}),g=u.map(([i])=>i),c=qa(new Cr({key:Symbol("design-system-demo"),title:"Generation by fuel type",prefix:"M",displayPrefix:"M",baseUnit:"W",timeZone:"Australia/Sydney"}));
1re(c,o(c).chartStyles.chartHeightPx=320);const f=Er("30m","Australia/Sydney"),F=jr("design-system-demo-hour","Australia/Sydney",{hour:"numeric",hour12:!0}),C=i=>L=>L?.getTime?.()?i(L):"";re(c,o(c).xTicks=6),re(c,o(c).formatTickX=C(i=>Dr(i,F.format(i),"Australia/Sydney"))),re(c,o(c).formatTooltipX=C(i=>f.formatTooltip(i))),re(c,o(c).seriesData=v),re(c,o(c).seriesNames=g),re(c,o(c).seriesColours=Object.fromEntries(g.map(i=>[i,Mr(i)]))),re(c,o(c).seriesLabels=Object.fromEntries(g.map(i=>[i,$a[i]]))),o(c).setXDomain(v[0].time,v[v.length-1].time),Ar(),Sr(k,{get chart(){return o(c)},showHeader:!1,showOptions:!1,zoomMode:"none",enablePan:!1}),Y()}var es=y('<div class="bg-white border border-warm-grey rounded-lg px-6 py-5"><p class="text-sm m-0"> </p> <p class="font-mono font-medium text-lg leading-lg tabular-nums m-0 mt-2"> <span class="text-xs text-mid-grey font-normal"> </span></p> <p> <span class="ml-2"> </span></p></div>'),ts=y('<div class="flex items-stretch h-14"><div class="flex-1 relative min-w-0"><div class="absolute inset-y-0 left-0"></div> <div class="relative z-10 h-full flex items-center justify-end pl-6 pr-2"><span class="text-sm font-medium whitespace-nowrap bg-white/70 rounded-sm px-1"> </span></div></div> <div class="flex items-center pl-2 shrink-0"><span class="w-2.5 h-2.5 rounded-full shrink-0"></span></div> <div class="w-36 flex items-center justify-end px-4 shrink-0"><span class="font-mono text-sm tabular-nums"> <span class="text-xs text-mid-grey">&nbsp;GWh</span></span></div> <div class="w-24 flex items-center justify-end shrink-0"><span class="font-mono text-sm tabular-nums"> </span></div> <div class="w-32 flex items-center justify-end pr-6 shrink-0"><span> <span class="ml-2"> </span></span></div></div>'),as=y('<div class="bg-light-warm-grey rounded-xl p-10 flex flex-col gap-8"><div class="flex items-start justify-between gap-8"><div><h3 class="text-xl leading-xl font-semibold m-0"> </h3> <p class="text-sm text-mid-grey m-0 mt-1">24 Feb – 2 March, 2026</p></div> <svg viewBox="0 0 443 416" class="w-24 shrink-0"><g stroke-width="6" stroke-linejoin="round"><path d="M175 53L175 251L112 281L34 292L23 284L31 252L4 184L11 133L88 106L109 70L116 67L130 70L143 42L158 42L164 60Z"></path><path d="M207 11L262 25L244 51L273 71L273 181L175 181L175 53L183 56L192 25L216 22Z"></path><path d="M175 181L305 181L305 335L287 299L274 302L274 283L260 297L270 262L250 294L226 257L175 251Z"></path><path d="M418 220L305 218L305 181L273 181L273 71L303 82L321 7L335 48L352 53L363 98L390 113L399 140L410 138L434 173L441 207Z"></path><path d="M305 218L418 220L442 208L403 328L380 307L346 309L305 281Z"></path><path d="M305 281L346 309L380 307L403 328L364 350L348 333L333 346L311 340Z"></path><path d="M346 373L384 374L381 409L360 413Z"></path></g></svg></div> <div class="grid grid-cols-3 gap-4"></div> <div class="bg-white rounded-lg border border-warm-grey divide-y divide-warm-grey overflow-hidden"></div> <div class="flex items-center justify-between gap-8 mt-6"><p class="text-xs text-mid-grey m-0">Source: Open Electricity, TSI</p> <img class="block h-8" src="/img/logo.svg" alt="Open Electricity"/></div></div>');function wa(k,d){J(d,!0);let u=O(d,"network",3,"NEM");const x="#353535",n="#C6C6C6",v="#FAF9F6",g=je(()=>u()==="NEM"),c=je(()=>o(g)?x:n),f=je(()=>o(g)?n:x),F=[{label:"Generation",value:"3,588",unit:"GWh",change:"5.4%",up:!0},{label:"Renewables",value:"45.6%",unit:"",change:"5.4%",up:!0},{label:"Avg. Price",value:"$44",unit:"/MWh",change:"5.4%",up:!1}],C=[{code:"solar",label:"Solar",energy:725,share:20.2,change:"22%",up:!1},{code:"wind",label:"Wind",energy:320,share:8.9,change:"42%",up:!1},{code:"hydro",label:"Hydro",energy:259,share:7.2,change:"42%",up:!0},{code:"battery_discharging",label:"Battery Discharge",energy:53,share:1.5,change:"2%",up:!1},{code:"gas",label:"Gas",energy:165,share:4.6,change:"73%",up:!0},{code:"coal",label:"Coal",energy:2060,share:57.4,change:"12%",up:!0}],i=Pr(0),L=B=>kt[B];var A=as(),w=a(A),j=a(w),D=a(j),E=a(D);e(D),b(2),e(j);var U=t(j,2),H=a(U);M(H,"stroke",v);var Q=a(H),oe=t(Q);M(oe,"fill",n);
1var fe=t(oe),ce=t(fe),we=t(ce),_e=t(we),De=t(_e);e(H),e(U),e(w);var le=t(w,2);W(le,21,()=>F,B=>B.label,(B,_)=>{var I=es(),N=a(I),de=a(N,!0);e(N);var X=t(N,2),ee=a(X,!0),te=t(ee),pe=a(te);e(te),e(X);var R=t(X,2);let ae;var ie=a(R,!0),V=t(ie),me=a(V,!0);e(V),e(R),e(I),$(()=>{h(de,o(_).label),h(ee,o(_).value),h(pe,` ${o(_).unit??""}`),ae=P(R,1,"font-mono text-xs tabular-nums m-0",null,ae,{"text-success-green":o(_).up,"text-error-red":!o(_).up}),h(ie,o(_).change),h(me,o(_).up?"▲":"▼")}),p(B,I)}),e(le);var ke=t(le,2);W(ke,21,()=>C,B=>B.code,(B,_)=>{var I=ts(),N=a(I),de=a(N);let X;var ee=t(de,2),te=a(ee),pe=a(te,!0);e(te),e(ee),e(N);var R=t(N,2),ae=a(R);let ie;e(R);var V=t(R,2),me=a(V),Le=a(me,!0);b(),e(me),e(V);var he=t(V,2),ge=a(he),Je=a(ge);e(ge),e(he);var $e=t(he,2),Ce=a($e);let xe;var Se=a(Ce,!0),Te=t(Se),Ee=a(Te,!0);e(Te),e(Ce),e($e),e(I),$((Ye,Me,Pe)=>{X=z(de,"",X,Ye),h(pe,o(_).label),ie=z(ae,"",ie,Me),h(Le,Pe),h(Je,`${o(_).share??""}%`),xe=P(Ce,1,"font-mono text-sm tabular-nums",null,xe,{"text-success-green":o(_).up,"text-error-red":!o(_).up}),h(Se,o(_).change),h(Ee,o(_).up?"▲":"▼")},[()=>({width:`${o(_).share??""}%`,"background-color":L(o(_).code)}),()=>({"background-color":L(o(_).code)}),()=>i.format(o(_).energy)]),p(B,I)}),e(ke),b(2),e(A),$(()=>{h(E,`${u()??""} weekly energy summary`),M(U,"aria-label",`${u()??""} regions highlighted`),M(Q,"fill",o(f)),M(fe,"fill",o(c)),M(ce,"fill",o(c)),M(we,"fill",o(c)),M(_e,"fill",o(c)),M(De,"fill",o(c))}),p(k,A),Y()}var rs=y('<div class="flex items-stretch justify-center w-full select-none"><!> <div class="max-w-full min-w-0"><!></div> <!></div>');function _a(k,d){J(d,!0);let u=O(d,"initial",3,560),x=O(d,"min",3,420),n=Ue(Ka(u())),v=Ue(void 0),g;La(()=>()=>g?.abort());function c(w,j){w.preventDefault(),g?.abort();const D=w.clientX,E=o(n),U=(o(v)?.clientWidth??1/0)-32,H=new AbortController;g=H;const{signal:Q}=H;window.addEventListener("pointermove",oe=>{Xe(n,Math.min(U,Math.max(x(),E+(oe.clientX-D)*2*j)),!0)},{signal:Q}),window.addEventListener("pointerup",()=>H.abort(),{signal:Q}),window.addEventListener("pointercancel",()=>H.abort(),{signal:Q})}var f=rs(),F=a(f);ba(F,{axis:"x",active:!0,onstart:w=>c(w,-1),class:"rounded-full h-40 self-center"});var C=t(F,2);let i;var L=a(C);qe(L,()=>d.children),e(C);var A=t(C,2);ba(A,{axis:"x",active:!0,onstart:w=>c(w,1),class:"rounded-full h-40 self-center"}),e(f),Ke(f,w=>Xe(v,w),()=>o(v)),$(()=>i=z(C,"",i,{width:`${o(n)??""}px`})),p(k,f),Y()}const K=(k,d=be,u=be,x=be,n)=>{let v=Ja(()=>Ya(n?.(),""));var g=os(),c=a(g),f=a(c),F=a(f,!0);e(f);var C=t(f,2),i=a(C,!0);e(C),e(c);var L=t(c,2);{var A=w=>{var j=ss(),D=a(j,!0);e(j),$(()=>{M(j,"href",o(v)),h(D,x())}),p(w,j)};Lt(L,w=>{o(v)&&w(A)})}e(g),$(()=>{h(F,d()),h(i,u())}),p(k,g)};var ss=y('<a class="font-mono text-xs text-mid-grey border border-warm-grey bg-light-warm-grey rounded-full px-6 py-2 hover:text-red hover:no-underline"> </a>'),os=y('<div class="border-t-2 border-dark-grey pt-6 mb-8 flex flex-wrap items-baseline justify-between gap-4"><div><p class="font-space font-medium tracking-wider text-sm leading-sm uppercase text-red mb-2"> </p> <h2 class="font-space mb-0"> </h2></div> <!></div>'),ls=y('<div class="flex flex-col items-center gap-6"><!> <h1 class="tracking-widest text-center">Design System</h1></div>'),ds=y(`<div><p class="text-sm text-center w-full md:w-[800px] mx-auto">The visual language of Open Electricity, rendered from the live code — every swatch, type
2				style and component on this page is imported from the same source the site itself uses, with
3				links into the <a href="https://github.com/opennem/openelectricity">public repo</a> for each section.</p></div>`),is=y("<a> </a>"),ns=y('<div class="flex-1"></div>'),cs=y('<div class="mb-8"><p class="font-space uppercase text-xxs text-mid-grey mb-3"> <code> </code></p> <!></div>'),ps=y('<div class="flex items-baseline gap-8 px-6 py-3"><span class="font-mono text-xs text-mid-grey w-44 shrink-0"> </span> <span>Electricity demand fell 4.2% year on year</span></div>'),ka=y("<!> <!>",1),ms=y('<span class="font-mono font-medium text-lg tabular-nums">23,412 MW</span> <span class="text-xs ml-3">▲ 42% renewables</span>',1),hs=y('<span class="font-space text-xs font-medium rounded-full px-6 py-2 border border-black/10"> </span>'),gs=y('<div class="flex flex-col items-center gap-2 w-40"><!> <span class="font-mono text-xxs text-mid-grey"> </span></div>'),xs=y('<div class="flex flex-col items-center gap-2 w-40"><span class="bg-white border border-warm-grey rounded-lg size-20 flex items-center justify-center text-dark-grey"><!></span> <span class="font-mono text-xxs text-mid-grey"> </span></div>'),us=y('<iframe loading="lazy" title="Record OG card preview" width="1200" height="630" class="pointer-events-none origin-top-left border-0"></iframe>'),vs=y('<tr><td class="px-6 py-3"> </td><td class="font-mono text-xs px-6 py-3"><a> </a></td></tr>'),ys=y(`<!> <!> <nav class="sticky top-0 z-30 bg-white/95 backdrop-blur-sm border-b border-warm-grey" aria-label="Page sections"><div class="container flex gap-2 overflow-x-auto py-4"></div></nav> <div class="container py-12 flex flex-col gap-24"><div class="border-l-4 border-red bg-light-warm-grey rounded-r-lg px-8 py-6 text-sm max-w-4xl"><strong class="font-space">Read this first.</strong> The app sets <code>html &#123; font-size: 62.5% &#125;</code>, so <strong>1rem = 10px</strong> everywhere —
4		every Tailwind rem utility renders ~1.6× smaller than stock (<code>text-base</code> is 16px, <code>p-4</code> is 10px, <code>rounded-lg</code> ≈ 6px). When recreating layouts in a design
5		tool, work on a 5px base grid. The site-wide mobile↔desktop boundary is <code>md:</code> = <strong>1024px</strong>, not Tailwind's usual 768px.</div> <section id="colour" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">
5The palette is warm-neutral — no cool blue-greys anywhere in the chrome. Greys carry a slight
6			warm cast, one brick-red accent does all interactive signalling, and every other colour comes
7			from the fuel-technology data palette. The custom palette replaces Tailwind's defaults
8			entirely.</p> <h3 class="subhead-primary mb-4">Neutrals — the warm ramp</h3> <!> <h3 class="subhead-primary mt-12 mb-4">Accent</h3> <!> <h3 class="subhead-primary mt-12 mb-4">Categorical &amp; regions</h3> <p class="text-sm text-mid-grey max-w-3xl mb-4">The secondary palette serves non-fuel-tech series; region colours reuse it, with NEM as a
9			whole getting its own red.</p> <!> <h3 class="subhead-primary mt-12 mb-4">Sequential scales</h3> <div class="max-w-3xl"><div class="h-8 rounded-md border border-warm-grey"></div> <div class="flex justify-between font-mono text-xxs text-mid-grey mt-1 mb-6"><span> </span> <span> </span></div> <div class="flex rounded-md overflow-hidden border border-warm-grey h-8"></div> <div class="flex justify-between font-mono text-xxs text-mid-grey mt-1"><span> </span> <span> </span></div></div> <div class="border-l-4 border-red bg-light-warm-grey rounded-r-lg px-8 py-6 text-sm max-w-4xl mt-10"><strong class="font-space">A second colour system coexists.</strong> The shadcn-svelte
10			components (<code>ui/button</code>, <code>ui/card</code>) use their own cool-neutral oklch
11			variable layer defined in <code>src/app.css</code> — a shadcn "default" button renders near-black,
12			not brand red. Its dark-mode variables exist but are unused: the product UI is light-only.</div></section> <section id="fuel-techs" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">The heart of the visual identity — each technology has a fixed colour used in every chart, map
13			and legend. The canonical map is <code>$lib/theme/openelectricity.js</code>; the older
14			palettes still in the repo (<code>theme/opennem.js</code>, <code>theme/openelectricity-old.js</code> and the stale copy inside <code>fuel_techs.js</code>) should not be used.</p> <h3 class="subhead-primary mb-4">Detailed palette</h3> <!> <h3 class="subhead-primary mt-12 mb-4">Group palette</h3> <!> <h3 class="subhead-primary mt-12 mb-4">Grouping schemes</h3> <p class="text-sm text-mid-grey max-w-3xl mb-6">Each view mode groups the detailed fueltechs differently — these are the live scheme
15			definitions from <code>src/lib/fuel-tech-groups/</code>, listed in stack order (bottom of the
16			chart first). Detailed and split-solar variants, plus scenario- and facility-specific schemes,
17			live in the same directory.</p> <!> <div class="border-l-4 border-red bg-light-warm-grey rounded-r-lg px-8 py-6 text-sm max-w-4xl mt-10"><strong class="font-space">Stack order matters.</strong> Stacked charts build bottom→top: loads
18			first (battery charging, pumps, exports), then imports, coal (brown → black), bioenergy, distillate,
19			the gas family, batteries discharging, hydro, wind, and solar on top — solar always crowns the stack.</div></section> <section id="typography" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">Three faces with strict roles, all self-hosted variable fonts in <code>static/fonts/</code>.</p> <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-12"><div class="border border-warm-grey rounded-lg p-8"><p class="font-space font-medium tracking-wider text-sm leading-sm uppercase text-red mb-4">Body · font-sans</p> <p class="text-xl leading-xl mb-4">DM Sans — prose &amp; running text</p> <p class="text-xs text-mid-grey">Weights: 300 light (metadata) · 400 · 500 · 600 semibold (headings) · 700</p></div> <div class="border border-warm-grey rounded-lg p-8"><p class="font-space font-medium tracking-wider text-sm leading-sm uppercase text-red mb-4">UI voice · font-space</p> <p class="font-space text-xl leading-xl mb-4">Space Grotesk — labels, buttons, eyebrows</p> <p class="text-xs text-mid-grey">Almost always <span class="font-space uppercase tracking-widest">uppercase + wide tracking</span> at small sizes. Weights: 400 · 500 · 600 · 700</p></div> <div class="border border-warm-grey rounded-lg p-8"><p class="font-space font-medium tracking-wider text-sm leading-sm uppercase text-red mb-4">Data · font-mono</p> <p class="font-mono text-xl leading-xl mb-4">DM Mono — 1,234.5 MW</p> <p class="text-xs text-mid-grey">Numerics and values, always with <code>tabular-nums</code>. Weights: 400 · 500</p></div></div> <h3 class="subhead-primary mb-4">Type scale</h3> <p class="text-sm text-mid-grey max-w-3xl mb-4">Effective px on the 10px root; line heights pair 1:1 with each size token and always add 4px.
20			Convention: always write <code>text-X leading-X</code> together.</p> <div class="border border-warm-grey rounded-lg divide-y divide-warm-grey overflow-x-auto"></div> <h3 class="subhead-primary mt-12 mb-4">Heading defaults</h3> <p class="text-sm text-mid-grey max-w-3xl mb-4">All headings are semibold (600) with <code>mb-[0.5em]</code>, except h6 at medium (500). Body
21			text is 16px <code>#353535</code>; paragraphs get <code>mb-[1em]</code>.</p> <div class="overflow-x-auto"><table class="w-full text-sm border border-warm-grey rounded-lg"><tbody class="divide-y divide-warm-grey"><tr><td class="font-mono px-6 py-3">h1</td><td class="font-mono px-6 py-3">40 / 44px</td><td class="font-mono px-6 py-3">60 / 64px ≥ 1024px</td></tr><tr><td class="font-mono px-6 py-3">h2</td><td class="font-mono px-6 py-3">28 / 32px</td><td class="font-mono px-6 py-3">36 / 40px ≥ 1024px</td></tr><tr><td class="font-mono px-6 py-3">h3</td><td class="font-mono px-6 py-3">24 / 28px</td><td class="px-6 py-3 text-mid-grey">—</td></tr><tr><td class="font-mono px-6 py-3">h4</td><td class="font-mono px-6 py-3">
2116 / 20px</td><td class="font-mono px-6 py-3">20 / 24px ≥ 1024px</td></tr><tr><td class="font-mono px-6 py-3">h5</td><td class="font-mono px-6 py-3">16 / 20px</td><td class="px-6 py-3 text-mid-grey">—</td></tr><tr><td class="font-mono px-6 py-3">h6</td><td class="font-mono px-6 py-3">14 / 18px · 500</td><td class="px-6 py-3 text-mid-grey">—</td></tr></tbody></table></div> <h3 class="subhead-primary mt-12 mb-4">Letter spacing</h3> <div class="overflow-x-auto"><table class="w-full text-sm border border-warm-grey rounded-lg"><tbody class="divide-y divide-warm-grey"><tr><td class="font-mono px-6 py-3">tightest / tighter / tight</td><td class="font-mono px-6 py-3">-1.2 / -0.72 / -0.48px</td><td class="px-6 py-3 text-mid-grey">large display headings</td></tr><tr><td class="font-mono px-6 py-3">wider</td><td class="font-mono px-6 py-3">0.63px</td><td class="px-6 py-3 text-mid-grey">.subhead-secondary, large links</td></tr><tr><td class="font-mono px-6 py-3">widest</td><td class="font-mono px-6 py-3">1.5px</td><td class="px-6 py-3 text-mid-grey">.subhead-primary, uppercase eyebrows</td></tr></tbody></table></div> <h3 class="subhead-primary mt-12 mb-4">Named text styles</h3> <div class="border border-warm-grey rounded-lg divide-y divide-warm-grey"><div class="flex flex-wrap items-center gap-x-12 gap-y-2 px-6 py-4"><span class="font-mono text-xs text-mid-grey w-52 shrink-0">.subhead-primary</span> <span class="subhead-primary">Grid snapshot</span></div> <div class="flex flex-wrap items-center gap-x-12 gap-y-2 px-6 py-4"><span class="font-mono text-xs text-mid-grey w-52 shrink-0">.subhead-secondary</span> <span class="subhead-secondary">All regions · Last 7 days</span></div> <div class="flex flex-wrap items-center gap-x-12 gap-y-2 px-6 py-4"><span class="font-mono text-xs text-mid-grey w-52 shrink-0">.text-link-large</span> <span class="text-link-large">View the full analysis</span></div> <div class="flex flex-wrap items-center gap-x-12 gap-y-2 px-6 py-4"><span class="font-mono text-xs text-mid-grey w-52 shrink-0">chart title (h6)</span> <span class="font-space uppercase text-xs font-normal">Generation by fuel type</span></div> <div class="flex flex-wrap items-center gap-x-12 gap-y-2 px-6 py-4"><span class="font-mono text-xs text-mid-grey w-52 shrink-0">control eyebrow</span> <span class="font-space uppercase text-xxs text-mid-grey">Display options</span></div></div> <h3 class="subhead-primary mt-12 mb-4">Writing &amp; formatting conventions</h3> <ul class="text-sm max-w-3xl flex flex-col gap-3 list-disc list-outside ml-8"><li><strong>UK/AU spelling</strong> throughout — colour, centre, organisation — and <strong>en-AU</strong> <code>Intl</code> formatting for all dates and numbers: "16 June 2025",
22				"6:30 am", comma-grouped thousands. Short month names render as June / July / Sept.</li> <li><strong>Values are always DM Mono</strong> with <code>tabular-nums</code>; the unit (<span class="font-mono">MW</span>, <span class="font-mono">GWh</span>, <span class="font-mono">$/MWh</span>) follows in a smaller, mid-grey suffix.</li> <li><strong>Sentence case</strong> for headings and prose. Space Grotesk UI labels (eyebrows, chart
23				titles, group headings) are uppercase with wide tracking.</li> <li><strong>Trends and status</strong>: success-green ▲ for up, error-red ▼ for down; facility
24				statuses use the dedicated status palette.</li> <li><strong>Interaction</strong>: links are brick red with hover underline; focus rings are red
25				(<code>focus:ring-red</code>); transitions run 150–500ms ease. Chart hover paints the red
26				focus line and dot.</li></ul></section> <section id="layout" class="scroll-mt-24"><!> <div class="grid grid-cols-1 md:grid-cols-2 gap-8"><div><h3 class="subhead-primary mb-4">Breakpoints</h3> <table class="w-full text-sm border border-warm-grey rounded-lg"><tbody class="divide-y divide-warm-grey"><tr><td class="font-mono px-6 py-3">sm</td><td class="font-mono px-6 py-3">640px</td><td class="px-6 py-3 text-mid-grey"></td></tr><tr><td class="font-mono px-6 py-3">tablet</td><td class="font-mono px-6 py-3">768px</td><td class="px-6 py-3 text-mid-grey">facilities routes only</td></tr><tr><td class="font-mono px-6 py-3">md</td><td class="font-mono px-6 py-3">1024px</td><td class="px-6 py-3 text-mid-grey font-medium">the mobile↔desktop boundary</td></tr><tr><td class="font-mono px-6 py-3">lg</td><td class="font-mono px-6 py-3">1440px</td><td class="px-6 py-3 text-mid-grey"></td></tr><tr><td class="font-mono px-6 py-3">xl</td><td class="font-mono px-6 py-3">1920px</td><td class="px-6 py-3 text-mid-grey"></td></tr></tbody></table></div> <div><h3 class="subhead-primary mb-4">Radii (effective)</h3> <table class="w-full text-sm border border-warm-grey rounded-lg"><tbody class="divide-y divide-warm-grey"><tr><td class="font-mono px-6 py-3">rounded-sm</td><td class="font-mono px-6 py-3">≈ 2px</td><td class="px-6 py-3 text-mid-grey">checkboxes, legend swatches</td></tr><tr><td class="font-mono px-6 py-3">rounded-md</td><td class="font-mono px-6 py-3">≈ 4px</td><td class="px-6 py-3 text-mid-grey">buttons, menu items</td></tr><tr><td class="font-mono px-6 py-3">rounded-lg</td><td class="font-mono px-6 py-3">≈ 6px</td><td class="px-6 py-3 text-mid-grey">cards, tooltips, panels</td></tr><tr><td class="font-mono px-6 py-3">rounded-xl</td><td class="font-mono px-6 py-3">≈ 10px</td><td class="px-6 py-3 text-mid-grey">shadcn cards, map controls</td></tr><tr><td class="font-mono px-6 py-3">rounded-full</td><td class="font-mono px-6 py-3">999px</td><td class="px-6 py-3 text-mid-grey">pills, toggles, map FABs</td></tr></tbody></table></div></div> <p class="text-sm text-mid-grey max-w-3xl mt-8">Containers centre with padding 25px → 40px (md) → 100px (lg) → 240px (xl). There is no custom
27			spacing scale, but on the 10px root every Tailwind step is 2.5px — <code>p-4</code> = 10px, <code>gap-6</code> = 15px. Signature surface treatments: glass chrome
28			(<code>bg-white/95 backdrop-blur-sm border border-mid-warm-grey shadow-md</code>) and the
29			grain texture overlay (<code>/img/grain.svg</code> at 40% opacity).</p></section> <section id="components" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">These are the real components, imported and rendered live — not recreations. House form
30			controls live in <code>form-elements/</code> (Space Grotesk voice); primitives in <code>ui/</code> (shadcn-svelte, its own neutral scale).</p> <h3 class="subhead-primary mb-2">Buttons — house style (deprecated)</h3> <p class="mb-4 max-w-3xl text-sm text-mid-grey">Kept for compatibility with existing screens. Use the shadcn-layer Button for new w
30ork and
31			when updating existing interfaces.</p> <div><!> <!> <!> <!></div> <h3 class="subhead-primary mb-4">Buttons — shadcn layer</h3> <div><!> <!> <!> <!> <!> <!></div> <h3 class="subhead-primary mb-4">Form controls</h3> <div><!> <!> <!> <!> <!> <!> <!> <!></div> <p class="text-xs text-mid-grey -mt-6 mb-10">The toggle label defaults to "Table" and can be set with the <code>label</code> prop.</p> <h3 class="subhead-primary mb-4">Card &amp; floating chrome</h3> <div><!> <div class="flex flex-col items-center gap-3"><button aria-label="Zoom in">+</button> <span class="font-mono text-xxs text-mid-grey">MAP_FAB_CLASS</span></div> <div class="flex flex-col gap-3"><div class="bg-dark-grey rounded-lg py-3 px-4 shadow text-white text-xs font-space max-w-sm leading-relaxed">Rooftop solar is estimated from distributed PV output</div> <span class="font-mono text-xxs text-mid-grey">Tooltip surface</span></div></div> <h3 class="subhead-primary mb-4">Overlays &amp; feedback</h3> <p class="text-sm text-mid-grey max-w-3xl mb-4">Transient UI sits on dark-grey surfaces; menus and panels on white with warm-grey hairlines.
32			The announcement banner is the one pure-black surface.</p> <div><div class="rounded-lg bg-dark-grey text-white px-6 py-3 text-sm shadow-lg">Link copied to clipboard</div> <div class="bg-white rounded-lg shadow-lg border border-mid-warm-grey min-w-[200px] py-1 text-sm"><div class="font-space uppercase text-xs text-mid-grey px-4 py-2">Chart type</div> <div class="px-4 py-1 mx-1 rounded-md hover:bg-warm-grey cursor-pointer">Stacked area</div> <div class="px-4 py-1 mx-1 rounded-md hover:bg-warm-grey cursor-pointer">Line</div> <div class="h-px bg-warm-grey my-1"></div> <div class="px-4 py-1 mx-1 rounded-md hover:bg-warm-grey cursor-pointer">Download CSV</div></div> <div class="bg-black text-white text-sm leading-sm px-10 py-6 font-light rounded-lg basis-full">Explore the new facilities map — every registered generator in the NEM and WEM. <a href="/facilities" class="text-white underline">Take a look →</a></div></div> <h3 class="subhead-primary mb-4">Facility status</h3> <div></div> <h3 class="subhead-primary mt-12 mb-4">Icons</h3> <p class="text-sm text-mid-grey max-w-3xl mb-4">Fuel-tech glyphs (<code>*Sm</code>) render as <code>FuelTechBadge</code> chips — the
33			/facilities presentation: a colour-filled circle with the glyph in <strong>white</strong>,
34			flipping to <strong>black</strong> on the light backgrounds (solar, OCGT and reciprocating
35			gas, data centre) via <code>needsDarkText()</code> in <code>$lib/utils/fueltech-display.js</code>. The glyphs stroke <code>currentColor</code>, so
36			the flip is just a text-colour change. UI icons are hand-rolled Heroicon-style; <code>@lucide/svelte</code> is also available for anything not covered.</p> <div><div class="flex flex-wrap gap-6 mb-8"></div> <div class="flex flex-wrap gap-6"></div></div></section> <section id="charts" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">Charts are quiet frames for loud data: hairline 20%-black gridlines, 10px light axis text in
37			mid-warm-grey, the fuel-tech palette doing all the talking, and the brick-red accent appearing
38			only on focus. The specimen below renders through the production Stratum chart stack with
39			synthetic data — hover it.</p> <div class="border border-warm-grey rounded-lg p-8 mb-10"><h6 class="m-0 mb-4 leading-none font-space uppercase text-xs font-normal">Generation by fuel type — typical day</h6> <!></div> <div class="grid grid-cols-1 md:grid-cols-2 gap-8"><div><h3 class="subhead-primary mb-4">Chart tokens</h3> <table class="w-full text-sm border border-warm-grey rounded-lg"><tbody class="divide-y divide-warm-grey"><tr><td class="px-6 py-3">Gridlines / axes / zero line</td><td class="font-mono px-6 py-3"> </td></tr><tr><td class="px-6 py-3">Axis tick text</td><td class="font-mono px-6 py-3">10px · 300 · #C6C6C6</td></tr><tr><td class="px-6 py-3">Focus line (hover)</td><td class="font-mono px-6 py-3"> </td></tr><tr><td class="px-6 py-3">Focus dot</td><td class="font-mono px-6 py-3"> </td></tr><tr><td class="px-6 py-3">Net-total line</td><td class="font-mono px-6 py-3">#C74523 · 2px</td></tr><tr><td class="px-6 py-3">Date-brush selection</td><td class="font-mono px-6 py-3">#963F29 @ 22%</td></tr><tr><td class="px-6 py-3">Series fallback</td><td class="font-mono px-6 py-3"> </td></tr><tr><td class="px-6 py-3">Default height</td><td class="font-mono px-6 py-3"> </td></tr></tbody></table></div> <div><h3 class="subhead-primary mb-4">Chart chrome type</h3> <table class="w-full text-sm border border-warm-grey rounded-lg"><tbody class="divide-y divide-warm-grey"><tr><td class="px-6 py-3">Chart title</td><td class="px-6 py-3 text-mid-grey">Space Grotesk · 12px · uppercase</td></tr><tr><td class="px-6 py-3">Control eyebrows</td><td class="px-6 py-3 text-mid-grey">Space Grotesk · 10px · uppercase</td></tr><tr><td class="px-6 py-3">Tooltip values</td><td class="px-6 py-3 text-mid-grey">DM Mono · tabular-nums</td></tr><tr><td class="px-6 py-3">Legend swatch</td><td class="px-6 py-3 text-mid-grey">10 × 10px · 2px radius</td></tr></tbody></table> <p class="text-sm text-mid-grey mt-6">Observable Plot charts use two presets in <a>PlotChartTheme.svelte.js</a> — <code>terminal</code> (default, DM Mono chrome) and <code>openelectricity</code> (DM Sans, red crosshair).</p></div></div></section> <section id="compositions" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">Composed artefacts built from the foundations above — report and social cards that combine
40			stat tiles, fuel-tech bars, records and the network glyph.</p> <h3 class="subhead-primary mb-4 text-center">Weekly summary cards</h3> <p class="text-sm text-mid-grey max-w-3xl mx-auto text-center mb-6">A composed specimen: the weekly energy summary card in its NEM and WEM variants — stat tiles,
41			proportional fuel-tech bars and a simplified network map glyph (the real state geometry,
42			trimmed for card size), all resolved from the canonical palette.</p> <div class="flex flex-col gap-8"><!> <!></div> <p class="text-xs text-mid-grey mt-2 text-center">Drag either side handle to test a card across widths — each card resizes independently,
43			staying centred.</p> <details class="max-w-4xl border border-warm-grey rounded-lg mt-6"><summary class="cursor-pointer px-6 py-4 font-space uppercase text-xs text-mid-grey select-none">Build spec — weekly summary card</summary> <ul class="text-sm px-10 pb-6 flex flex-col gap-3 list-disc list-outside"><li><strong>Card</strong>: <code>bg-light-warm-grey rounded-xl p-10</code>, children stacked
44					with <code>flex flex-col gap-8</code> (20px gaps on the 10px root).</li> <li><strong>Header</strong>: <code>flex items-start justify-between</code> — title <code>text-xl leading-xl font-semibold</code> with the date <code>text-sm text-mid-grey</code> beneath; the Australia glyph is a fixed <code>w-24 shrink-0</code> on the right.</li> <li><strong>Stat tiles</strong>: <code>grid grid-cols-3 gap-4</code>; each tile <code>bg-white border border-warm-grey rounded-lg px-6 py-5</code>. Label <code>text-sm</code>; value <code>font-mono font-medium text-lg tabular-nums</code> with
45					the unit as a smaller <code>text-xs text-mid-grey</code> suffix; the trend line sits flush
46					under the value (no top margin), <code>font-mono text-xs</code>, coloured <code>text-success-green</code> ▲ up / <code>text-error-red</code> ▼ down, triangle
47					separated from the number by <code>ml-2</code>.</li> <li><strong>Fuel-tech table</strong>: <code>
47bg-white rounded-lg border border-warm-grey divide-y divide-warm-grey</code>; each
48					row is <code>flex items-stretch h-14</code> (35px tall).</li> <li><strong>Bar</strong>: absolutely positioned inside the row's flexible first cell (<code>absolute inset-y-0 left-0</code>), full row height, anchored to the left edge. <strong>Bar width literally equals the row's share percentage</strong> (<code></code>) — 57.4% share renders a 57.4%-wide bar; it is NOT
49					scaled relative to the largest row. A 100% bar would fill the whole flexible cell, which
50					ends just right of the label.</li> <li><strong>Label</strong>: right-aligned in the same flexible cell, layered over the bar (<code>relative z-10</code>), <code>text-sm font-medium whitespace-nowrap</code> — it never truncates; a <code>bg-white/70 rounded-sm px-1</code> pill keeps it legible where the bar runs beneath. The
51					10px colour dot sits in its own cell after the label, outside the bar's reach.</li> <li><strong>Numeric columns</strong>: fixed widths (energy <code>w-36</code>, share <code>w-24</code>, trend <code>w-32</code>), all right-aligned <code>font-mono text-sm tabular-nums</code> so digits line up; energy carries a <code>text-xs text-mid-grey</code> GWh suffix; trend colours/triangles follow the tile rule.</li> <li><strong>Australia glyph</strong>: viewBox <code>0 0 443 416</code> (the state-map
52					coordinate space), simplified state paths. Member states fill <code>#353535</code>, non-members <code>#C6C6C6</code>; NT is always light (it belongs to
53					neither market); strokes are <code>#FAF9F6</code> (the card background) at width 6 with <code>stroke-linejoin: round</code>, so states read as separate pieces.</li> <li><strong>Footer</strong>: <code>flex items-center justify-between</code> with an extra <code>mt-6</code>; source line <code>text-xs text-mid-grey</code>; wordmark image <code>h-8</code> (20px).</li></ul></details> <hr class="border-0 border-t border-warm-grey my-20"/> <h3 class="subhead-primary mb-4">Record card</h3> <p class="text-sm text-mid-grey max-w-3xl mb-6">The shared <code>RecordCard</code> — the pinned-record card rendered on the homepage and
54			/records, here with fixed specimen values. <a>$lib/components/records/RecordCard.svelte</a></p> <div class="max-w-[220px]"><!></div> <details class="max-w-4xl border border-warm-grey rounded-lg mt-6"><summary class="cursor-pointer px-6 py-4 font-space uppercase text-xs text-mid-grey select-none">Build spec — record card</summary> <ul class="text-sm px-10 pb-6 flex flex-col gap-3 list-disc list-outside"><li><strong>Frame</strong>: constrained to <code>max-w-[220px]</code>; <code>min-h-[200px] p-6 rounded-xl bg-white border border-mid-warm-grey</code>, border
55					darkening to <code>dark-grey</code> on hover. The whole card is one link with no underline.</li> <li><strong>Vertical layout</strong>: <code>grid grid-cols-1 gap-4 content-between</code> — the
56					description block and the value row are pushed to opposite ends, so the value row always pins
57					to the bottom regardless of description length.</li> <li><strong>Top row</strong>: <code>flex items-center justify-between</code> — fuel-tech chip
58					left (<code>rounded-full p-3</code>, background = the fueltech colour, glyph stroked
59					white, or black on light backgrounds like solar), region label <code>text-sm text-mid-grey</code> right.</li> <li><strong>Description</strong>: <code>text-base leading-base</code> (16/20px) with <code>my-8</code> above and below.</li> <li><strong>Value row</strong>: separated by <code>border-t border-mid-warm-grey pt-6</code>;
60					value <code>font-mono</code> with the unit in <code>&lt;small&gt;</code> <code>text-mid-grey</code>; relative time <code>text-xxs text-mid-grey</code>, right end
61					on large screens, stacked beneath on small.</li></ul></details> <hr class="border-0 border-t border-warm-grey my-20"/> <h3 class="subhead-primary mb-4">Record OG card</h3> <p class="text-sm text-mid-grey max-w-3xl mb-6">The record social image is a 1200×630 Puppeteer screenshot of the <code>(micro)/record/[id]</code> page, generated and cached by the <code>record-og-image</code> worker. This is that HTML page live, scaled to fit — what you see
62			is exactly what the OG pipeline captures. Open the source page directly: <a target="_blank" rel="noopener"></a></p> <div class="w-full max-w-[1200px] border border-warm-grey rounded-lg overflow-hidden aspect-[1200/630]"><!></div></section> <section id="brand" class="scroll-mt-24"><!> <div class="bg-light-warm-grey border border-warm-grey rounded-lg p-16 flex flex-wrap items-center gap-24 mb-8"><img class="block" src="/img/logo.svg" alt="Open Electricity"/> <!></div> <p class="text-sm text-mid-grey max-w-3xl">The wordmark fills with dark grey <code>#353535</code>, not black. The zig-zag "lightning
63			wave" mark is the strongest brand signature: its fill cycles through the emissions-intensity
64			spectrum — fossil brown → renewable green and back — over 5 seconds. When static, it takes a
65			single fill from the same spectrum.</p></section> <section id="sources" class="scroll-mt-24"><!> <p class="text-sm text-mid-grey max-w-3xl mb-8">Everything on this page traces to one of these files.</p> <div class="border border-warm-grey rounded-lg overflow-x-auto"><table class="w-full text-sm"><tbody class="divide-y divide-warm-grey"></tbody></table></div></section></div>`,1);function fo(k,d){J(d,!0);const u="bg-light-warm-grey border border-warm-grey rounded-lg p-10",x="https://github.com/opennem/openelectricity/blob/main/",n="https://github.com/opennem/openelectricity/tree/main/",v=["solar_utility","solar_rooftop","solar","wind","wind_offshore","hydro","pumps","battery","battery_discharging","battery_charging","bioenergy","bioenergy_biomass","bioenergy_biogas","coal","coal_black","coal_brown","gas","gas_steam","gas_ccgt","gas_ccgt_ccs","gas_ocgt","gas_recip","gas_wcmg","gas_hydrogen","distillate","demand","data_centre","renewables","fossils"],g=[{name:"ChevronDown",component:wr},{name:"XMark",component:_r},{name:"Share",component:kr},{name:"ArrowDownTray",component:Lr},{name:"AdjustmentsHorizontal",component:$r},{name:"Github",component:qr}],c=[{name:"white",hex:"#FFFFFF",note:"page background"},{name:"light-warm-grey",hex:"#FAF9F6",note:"off-white surface"},{name:"warm-grey",hex:"#F1F0ED",note:"subtle fills, dividers"},{name:"mid-warm-grey",hex:"#C6C6C6",note:"borders, axis text"},{name:"mid-grey",hex:"#6A6A6A",note:"muted text, labels"},{name:"dark-grey",hex:"#353535",note:"body text, dark surfaces"},{name:"black",hex:"#000000",note:"button fills, banner"}],f=[{name:"red",hex:"#C74523",note:"primary accent — links, focus"},{name:"dark-red",hex:"#963F29",note:"link hover, brush handles"}],F=cr.map(r=>({name:r.shortLabel,hex:r.colour,note:r.description})),C=nr.map((r,l)=>({name:`secondary ${l+1}`,hex:r})).filter(r=>!F.some(l=>l.hex.toLowerCase()===r.hex.toLowerCase())),i={vre:"VRE (Wind + Solar)",residual:"Residual",demand:"Demand"},L=r=>$a[r]??i[r]??r,A=(r,l={})=>r.map(s=>({name:l[s]??L(s),hex:kt[s],note:s})),w=A(["solar_utility","solar_rooftop","solar_thermal","wind","wind_offshore","hydro","pumps","battery_discharging","battery_charging","bioenergy_biomass","bioenergy_biogas","coal_black","coal_brown","gas_steam","gas_ccgt","gas_ccgt_ccs","gas_ocgt","gas_recip","gas_wcmg","gas_hydrogen","distillate","nuclear","imports","exports","interconnector","demand","demand_response","data_centre","vre","residual"]),j=A(["coal","gas","bioenergy","solar","renewables","fossils","demand","total_sources","total_loads"]),D=[ur,vr,br,yr].map(r=>({label:r.label,value:r.value,items:A(r.order,r.labels)})),E=new Tr,U=ir.map(({label:r,colour:l})=>({name:r,hex:l})),H=[{cls:"text-xxxs",label:"xxxs · 8px"},{cls:"text-xxs",label:"xxs · 10px"},{cls:"text-xs leading-xs",label:"xs · 12/16px"},{cls:"text-sm leading-sm",label:"sm · 14/18px"},{cls:"text-base leading-base",label:"base · 16/20px"},{cls:"text-lg leading-lg",label:"lg · 20/24px"},{cls:"text-xl leading-xl",label:"xl · 24/28px"},{cls:"text-2xl leading-2xl",label:"2xl · 28/32px"},{cls:"text-3xl leading-3xl",label:"3xl · 36/40px"},{cls:"text-4xl leading-4xl",label:"4xl · 40/44px"},{cls:"text-6xl leading-6xl",label:"6xl · 48/52px"},{cls:"text-9xl leading-9xl",label:"9xl · 60/64px"}],Q=[{what:"Colour palette, type scale, breakpoints",path:"tailwind.config.js"},{what:"Base styles, fonts, shadcn variables, named text styles",path:"src/app.css"},{what:"Canonical fuel-tech, status and carbon colours",path:"src/lib/theme/openelectricity.js"},{what:"Fuel-tech display names",path:"src/lib/fuel_techs.js"},{what:"Grouping schemes",path:"src/lib/fuel-tech-groups/"},{what:"Secondary categorical palette",path:"src/lib/theme/secondary-colour-palette.js"},{what:"Region colours",path:"src/lib/regions.js"},{what:"Sequential scales (emissions, price)",path:"src/lib/colours.js"},{what:"House form controls",path:"src/lib/components/form-elements/"},{what:"shadcn primitives",path:"src/lib/components/ui/"},{what:"Stratum chart tokens",path:"src/lib/components/charts/v2/ChartStyles.svelte.js"},{what:"Observable Plot themes",path:"src/lib/components/charts/plot/PlotChartTheme.svelte.js"},{what:"Icons (UI + fuel-tech glyphs)",path:"src/lib/icons/"},{what:"Logo mark (animated)",path:"src/lib/images/logo-mark.svelte"},{what:"Wordmark SVG",path:"static/img/logo.svg"},{what:"Self-hosted fonts",path:"static/fonts/"}],oe=[{id:"colour",label:"Colour"},{id:"fuel-techs",label:"Fuel techs"},{id:"typography",label:"Type"},{id:"layout",label:"Layout"},{id:"components",label:"Components"},{id:"charts",label:"Charts"},{id:"compositions",label:"Compositions"},{id:"brand",label:"Brand"},{id:"sources",label:"Sources"}];let fe=Ue(""),ce=Ue(0);La(()=>{const r=oe.map(s=>document.getElementById(s.id)).filter(s=>s!==null),l=new IntersectionObserver(s=>{for(const m of s)m.isIntersecting&&Xe(fe,m.target.id,!0)},{rootMargin:"-10% 0px -70% 0px"});return r.forEach(s=>l.observe(s)),()=>l.disconnect()});var we=ys(),_e=Ne(we);lr(_e,{title:"Design System",description:"The visual language of Open Electricity — colours, typography, components and chart styling, rendered from the live code.",image:"/img/preview.jpg"});var De=t(_e,2);dr(De,{heading:s=>{var m=ls(),S=a(m);va(S,{classes:"w-16 h-10"}),b(2),e(m),p(s,m)},subheading:s=>{var m=ds();p(s,m)},$$slots:{heading:!0,subheading:!0}});
65var le=t(De,2),ke=a(le);W(ke,21,()=>oe,r=>r.id,(r,l)=>{var s=is(),m=a(s,!0);e(s),$(()=>{M(s,"href",`#${o(l).id??""}`),P(s,1,`font-space text-xxs font-medium uppercase tracking-wider whitespace-nowrap rounded-full px-6 py-2 hover:no-underline ${o(fe)===o(l).id?"bg-dark-grey text-white":"text-mid-grey hover:bg-warm-grey hover:text-dark-grey"}`),h(m,o(l).label)}),p(r,s)}),e(ke),e(le);var B=t(le,2),_=t(a(B),2),I=a(_);K(I,()=>"01 · Foundations",()=>"Colour",()=>"tailwind.config.js",()=>`${x}tailwind.config.js`);var N=t(I,6);ye(N,{get items(){return c}});var de=t(N,4);ye(de,{get items(){return f}});var X=t(de,6);{let r=je(()=>[...F,...C]);ye(X,{get items(){return o(r)}})}var ee=t(X,4),te=a(ee);let pe;var R=t(te,2),ae=a(R),ie=a(ae);e(ae);var V=t(ae,2),me=a(V);e(V),e(R);var Le=t(R,2);W(Le,20,()=>se.price,r=>r,(r,l)=>{var s=ns();let m;$(()=>m=z(s,"",m,{"background-color":l})),p(r,s)}),e(Le);var he=t(Le,2),ge=a(he),Je=a(ge);e(ge);var $e=t(ge,2),Ce=a($e);e($e),e(he),e(ee),b(2),e(_);var xe=t(_,2),Se=a(xe);K(Se,()=>"02 · Data palette",()=>"Fuel technology colours",()=>"src/lib/theme/openelectricity.js",()=>`${x}src/lib/theme/openelectricity.js`);var Te=t(Se,6);ye(Te,{get items(){return w}});var Ee=t(Te,4);ye(Ee,{get items(){return j}});var Ye=t(Ee,6);W(Ye,17,()=>D,r=>r.value,(r,l)=>{var s=cs(),m=a(s),S=a(m),T=t(S),Z=a(T,!0);e(T),e(m);var q=t(m,2);ye(q,{get items(){return o(l).items}}),e(s),$(()=>{h(S,`${o(l).label??""} · `),h(Z,o(l).value)}),p(r,s)}),b(2),e(xe);var Me=t(xe,2),Pe=a(Me);K(Pe,()=>"03 · Foundations",()=>"Typography",()=>"src/app.css",()=>`${x}src/app.css`);var Ct=t(Pe,10);W(Ct,21,()=>H,r=>r.cls,(r,l)=>{var s=ps(),m=a(s),S=a(m,!0);e(m);var T=t(m,2);e(s),$(()=>{h(S,o(l).label),P(T,1,`${o(l).cls??""} whitespace-nowrap`)}),p(r,s)}),e(Ct),b(18),e(Me);var Qe=t(Me,2),Sa=a(Qe);K(Sa,()=>"04 · Foundations",()=>"Layout, space & surfaces",()=>"tailwind.config.js",()=>`${x}tailwind.config.js`),b(4),e(Qe);var et=t(Qe,2),St=a(et);K(St,()=>"05 · Library",()=>"Components",()=>"src/lib/components/",()=>`${n}src/lib/components`);var Be=t(St,8);P(Be,1,"bg-light-warm-grey border border-warm-grey rounded-lg p-10 flex flex-wrap items-center gap-6 mb-10");var Tt=a(Be);_t(Tt,{children:(r,l)=>{b();var s=G("Primary action");p(r,s)},$$slots:{default:!0}});var Mt=t(Tt,2);_t(Mt,{secondary:!0,children:(r,l)=>{b();var s=G("Secondary");p(r,s)},$$slots:{default:!0}});var Ft=t(Mt,2);_t(Ft,{disabled:!0,children:(r,l)=>{b();var s=G("Disabled");p(r,s)},$$slots:{default:!0}});var Ta=t(Ft,2);mr(Ta,{children:(r,l)=>{b();var s=G("Button2 / ghost");p(r,s)},$$slots:{default:!0}}),e(Be);var Ge=t(Be,4);P(Ge,1,"bg-light-warm-grey border border-warm-grey rounded-lg p-10 flex flex-wrap items-center gap-6 mb-10");var At=a(Ge);ve(At,{children:(r,l)=>{b();var s=G("Default");p(r,s)},$$slots:{default:!0}});var jt=t(At,2);ve(jt,{variant:"secondary",children:(r,l)=>{b();var s=G("Secondary");p(r,s)},$$slots:{default:!0}});var Dt=t(jt,2);ve(Dt,{variant:"outline",children:(r,l)=>{b();var s=G("Outline");p(r,s)},$$slots:{default:!0}});var Et=t(Dt,2);ve(Et,{variant:"ghost",children:(r,l)=>{b();var s=G("Ghost");p(r,s)},$$slots:{default:!0}});var Pt=t(Et,2);ve(Pt,{variant:"destructive",children:(r,l)=>{b();var s=G("Destructive");p(r,s)},$$slots:{default:!0}});var Ma=t(Pt,2);ve(Ma,{variant:"link",children:(r,l)=>{b();var s=G("Link");p(r,s)},$$slots:{default:!0}}),e(Ge);var Re=t(Ge,4);P(Re,1,"bg-light-warm-grey border border-warm-grey rounded-lg p-10 flex flex-wrap items-center gap-10 mb-10 text-sm");var Bt=a(Re);ya(Bt,{checked:!0});var Gt=t(Bt,2);ya(Gt,{checked:!1});var Rt=t(Gt,2);ze(Rt,{name:"ds-check-on",label:"Solar (Rooftop)",checked:!0});var Wt=t(Rt,2);ze(Wt,{name:"ds-check-off",label:"Imports"});var Ot=t(Wt,2);ze(Ot,{name:"ds-check-mixed",label:"Mixed selection",indeterminate:!0});var Ht=t(Ot,2);ze(Ht,{name:"ds-check-disabled",label:"Disabled option",disabled:!0});var It=t(Ht,2);fa(It,{name:"ds-radio",label:"By technology",checked:!0,changeHandler:()=>{}});var Fa=t(It,2);fa(Fa,{name:"ds-radio",label:"By region",changeHandler:()=>{}}),e(Re);var We=t(Re,6);P(We,1,"bg-light-warm-grey border border-warm-grey rounded-lg p-10 flex flex-wrap items-start gap-10 mb-10");var Nt=a(We);ue(Nt,()=>gr,(r,l)=>{l(r,{class:"max-w-sm bg-white",children:(s,m)=>{var S=ka(),T=Ne(S);ue(T,()=>Ir,(q,ne)=>{ne(q,{class:"",children:(Fe,Xa)=>{var Ae=ka(),He=Ne(Ae);ue(He,()=>Ur,(yt,bt)=>{bt(yt,{class:"",children:(ft,Va)=>{b();var wt=G("NEM at a glance");p(ft,wt)},$$slots:{default:!0}})});var Ie=t(He,2);ue(Ie,()=>Wr,(yt,bt)=>{bt(yt,{class:"",children:(ft,Va)=>{b();var wt=G("Live generation across the National Electricity Market");p(ft,wt)},$$slots:{default:!0}})}),p(Fe,Ae)},$$slots:{default:!0}})});var Z=t(T,2);ue(Z,()=>xr,(q,ne)=>{ne(q,{class:"",children:(Fe,Xa)=>{var Ae=ms(),He=t(Ne(Ae),2);let Ie;$(()=>Ie=z(He,"",Ie,{color:kt.renewables})),p(Fe,Ae)},$$slots:{default:!0}})}),p(s,S)},$$slots:{default:!0}})});var zt=t(Nt,2),Aa=a(zt);b(2),e(zt),b(2),e(We);var Ut=t(We,6);P(Ut,1,"bg-light-warm-grey border border-warm-grey rounded-lg p-10 flex flex-wrap items-start gap-10 mb-10");var Oe=t(Ut,4);P(Oe,1,"bg-light-warm-grey border border-warm-grey rounded-lg p-10 flex flex-wrap items-center gap-6"),W(Oe,21,()=>U,r=>r.name,(r,l)=>{var s=hs();let m;var S=a(s,!0);e(s),$(T=>{m=z(s,"",m,T),h(S,o(l).name)},[()=>({"background-color":o(l).hex,color:Ca(o(l).hex)})]),p(r,s)}),e(Oe);var tt=t(Oe,6);P(tt,1,sr(u));var at=a(tt);W(at,20,()=>v,r=>r,(r,l)=>{var s=gs(),m=a(s);fr(m,{get fuelTech(){return l},size:"lg",showStatus:!1});var S=t(m,2),T=a(S,!0);e(S),e(s),$(()=>h(T,l)),p(r,s)}),e(at);var Xt=t(at,2);W(Xt,21,()=>g,r=>r.name,(r,l)=>{var s=xs(),m=a(s),S=a(m);ue(S,()=>o(l).component,(q,ne)=>{ne(q,{class:"size-9"})}),e(m);var T=t(m,2),Z=a(T,!0);e(T),e(s),$(()=>h(Z,o(l).name)),p(r,s)}),e(Xt),e(tt),e(et);var rt=t(et,2),Vt=a(rt);K(Vt,()=>"06 · Data visualisation",()=>"Chart styling",()=>"charts/v2/ChartStyles.svelte.js",()=>`${x}src/lib/components/charts/v2/ChartStyles.svelte.js`);var st=t(Vt,4),ja=t(a(st),2);Qr(ja,{}),e(st);var Zt=t(st,2),ot=a(Zt),qt=t(a(ot),2),Kt=a(qt),lt=a(Kt),Jt=t(a(lt)),Da=a(Jt,!0);e(Jt),e(lt);var dt=t(lt,2),Yt=t(a(dt)),Ea=a(Yt,!0);e(Yt),e(dt);var it=t(dt),Qt=t(a(it)),Pa=a(Qt);e(Qt),e(it);var nt=t(it,3),ea=t(a(nt)),Ba=a(ea,!0);e(ea),e(nt);var ta=t(nt),aa=t(a(ta)),Ga=a(aa,!0);e(aa),e(ta),e(Kt),e(qt),e(ot);var ra=t(ot,2),sa=t(a(ra),4),Ra=t(a(sa));M(Ra,"href","https://github.com/opennem/openelectricity/blob/main/src/lib/components/charts/plot/PlotChartTheme.svelte.js"),b(5),e(sa),e(ra),e(Zt),e(rt);var ct=t(rt,2),oa=a(ct);K(oa,()=>
65"07 · Compositions",()=>"Summary & social cards",()=>"");var pt=t(oa,8),la=a(pt);_a(la,{children:(r,l)=>{wa(r,{network:"NEM"})},$$slots:{default:!0}});var Wa=t(la,2);_a(Wa,{children:(r,l)=>{wa(r,{network:"WEM"})},$$slots:{default:!0}}),e(pt);var mt=t(pt,4),da=t(a(mt),2),ia=t(a(da),8),Oa=t(a(ia),6);Oa.textContent="width: {share}%",b(),e(ia),b(8),e(da),e(mt);var ht=t(mt,6),Ha=t(a(ht),3);M(Ha,"href","https://github.com/opennem/openelectricity/blob/main/src/lib/components/records/RecordCard.svelte"),e(ht);var gt=t(ht,2),Ia=a(gt);Br(Ia,{href:"/records/au.nem.battery_discharging.power.interval.high",fuelTech:"battery_discharging",regionLabel:"NEM",description:"Highest ever battery (discharging) generation",value:"1,270",unit:"MW",timeLabel:"2 hours ago"}),e(gt);var xt=t(gt,8),na=t(a(xt),5);M(na,"href","/record/au.nem.battery_discharging.power.interval.high?focusTime=1786436100000"),na.textContent="/record/au.nem.battery_discharging.power.interval.high",e(xt);var ut=t(xt,2),Na=a(ut);{var za=r=>{var l=us();M(l,"src","/record/au.nem.battery_discharging.power.interval.high?focusTime=1786436100000");let s;$(()=>s=z(l,"",s,{transform:`scale(${o(ce)/1200})`})),p(r,l)};Lt(Na,r=>{o(ce)>0&&r(za)})}e(ut),e(ct);var vt=t(ct,2),ca=a(vt);K(ca,()=>"08 · Identity",()=>"Brand",()=>"src/lib/images/logo-mark.svelte",()=>`${x}src/lib/images/logo-mark.svelte`);var pa=t(ca,2),Ua=t(a(pa),2);va(Ua,{classes:"w-56 h-32"}),e(pa),b(2),e(vt);var ma=t(vt,2),ha=a(ma);K(ha,()=>"09 · Reference",()=>"Source map",()=>"github.com/opennem/openelectricity",()=>"https://github.com/opennem/openelectricity");var ga=t(ha,4),xa=a(ga),ua=a(xa);W(ua,21,()=>Q,r=>r.path,(r,l)=>{var s=vs(),m=a(s),S=a(m,!0);e(m);var T=t(m),Z=a(T),q=a(Z,!0);e(Z),e(T),e(s),$((ne,Fe)=>{h(S,o(l).what),M(Z,"href",`${ne??""}${Fe??""}`),h(q,o(l).path)},[()=>o(l).path.endsWith("/")?n:x,()=>o(l).path.replace(/\/$/,"")]),p(r,s)}),e(ua),e(xa),e(ga),e(ma),e(B),$(r=>{pe=z(te,"",pe,r),h(ie,`${se.intensity[0]??""} · low emissions intensity`),h(me,`${se.intensity[se.intensity.length-1]??""} · high`),h(Je,`${se.price[0]??""} · low price`),h(Ce,`${se.price[se.price.length-1]??""} · high`),P(Aa,1,`${pr} size-16 text-base`),h(Da,E.xAxisStroke),h(Ea,E.focusYLineStrokeColour),h(Pa,`${E.focusYLineDotColour??""} · r ${E.focusYLineDotRadius??""}`),h(Ba,Fr),h(Ga,E.chartHeightClasses)},[()=>({background:`linear-gradient(90deg, ${se.intensity.join(", ")??""})`})]),or(ut,"clientWidth",r=>Xe(ce,r)),p(k,we),Y()}export{fo as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.