From 91cc2bd66369f82173f38e1ede4e8cadea4d6d8a Mon Sep 17 00:00:00 2001 From: mrkmntal Date: Mon, 6 Apr 2026 18:50:03 -0400 Subject: [PATCH] Add LWN News section --- DEVLOG.md | 11 + gulp/publish-frontend.mjs | 2 + index.mjs | 96 ++ server/images/logos/logo-corner.png | Bin 9668 -> 10141 bytes server/scripts/modules/linuxnews.mjs | 89 ++ server/styles/scss/_linux-news.scss | 54 + server/styles/scss/ws.scss | 3 +- server/styles/ws.min.css | 2 +- server/styles/ws.min.css.map | 2 +- session-ses_2a6f.md | 1863 ++++++++++++++++++++++++++ views/index.ejs | 6 +- views/partials/linux-news.ejs | 6 + 12 files changed, 2130 insertions(+), 4 deletions(-) create mode 100644 server/scripts/modules/linuxnews.mjs create mode 100644 server/styles/scss/_linux-news.scss create mode 100644 session-ses_2a6f.md create mode 100644 views/partials/linux-news.ejs diff --git a/DEVLOG.md b/DEVLOG.md index 6c06062..ffe213a 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -11,3 +11,14 @@ Added a new `Server Observations` forecast screen that blends Linux server telem - added the screen to the initial progress display list and tightened the progress screen typography so the extra row fits cleanly - updated navigation handling to safely work with sparse display arrays introduced by the new nav slot - updated the frontend build so generated CSS is copied to the development-served stylesheet path as well + +## Linux News: LWN + +Added a new `Linux News: LWN` screen that pulls current stories from the LWN homepage and presents them as readable, TV-friendly pages in the forecast rotation. + +- added `/api/linux-news` to fetch `https://lwn.net/` and parse homepage headlines, blurbs, and article links +- created a new `linuxnews` display module, EJS partial, and SCSS styling +- paginated the LWN feed into 4 screens with 2 stories per page and enabled the display by default +- registered the new screen in the main display deck and included it in the startup/progress screen list +- tightened the story card layout to prevent page bleed and overlapping text between stacked pages +- shortened LWN blurbs and reduced headline/body typography so long top-slot stories fit cleanly inside the 512x250 content box diff --git a/gulp/publish-frontend.mjs b/gulp/publish-frontend.mjs index 0a42030..3ff65cf 100644 --- a/gulp/publish-frontend.mjs +++ b/gulp/publish-frontend.mjs @@ -87,6 +87,8 @@ const mjsSources = [ 'server/scripts/modules/progress.mjs', 'server/scripts/modules/media.mjs', 'server/scripts/modules/custom-scroll-text.mjs', + 'server/scripts/modules/serverobservations.mjs', + 'server/scripts/modules/linuxnews.mjs', 'server/scripts/index.mjs', ]; diff --git a/index.mjs b/index.mjs index e00b588..0f5e1e8 100644 --- a/index.mjs +++ b/index.mjs @@ -14,6 +14,70 @@ import devTools from './src/com.chrome.devtools.mjs'; const execAsync = promisify(exec); +const decodeHtml = (text) => text + .replace(/ /g, ' ') + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, "'") + .replace(/’/g, "'") + .replace(/‘/g, "'") + .replace(/“/g, '"') + .replace(/”/g, '"') + .replace(/—/g, '-') + .replace(/–/g, '-') + .replace(/…/g, '...') + .replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code))); + +const stripHtml = (text) => decodeHtml(text + .replace(//gi, '') + .replace(//gi, '') + .replace(/<[^>]+>/g, ' ') + .replace(/\s+([,.;:!?])/g, '$1') + .replace(/\s+/g, ' ') + .trim()); + +const trimBlurb = (text, maxLength = 120) => { + if (text.length <= maxLength) return text; + const shortened = text.slice(0, maxLength); + const lastSpace = shortened.lastIndexOf(' '); + return `${shortened.slice(0, lastSpace > 0 ? lastSpace : maxLength)}...`; +}; + +const parseLwnStories = (html) => { + const headingRegex = /]*>([\s\S]*?)<\/h2>/gi; + const headings = [...html.matchAll(headingRegex)]; + const stories = []; + + headings.forEach((match, index) => { + if (stories.length >= 8) return; + + const headingHtml = match[1]; + const start = match.index + match[0].length; + const end = headings[index + 1]?.index ?? html.length; + const sectionHtml = html.slice(start, end); + + const headline = stripHtml(headingHtml).replace(/^\[\s*\$\s*\]\s*/, ''); + if (!headline || headline === 'Welcome to LWN.net') return; + + const hrefMatch = headingHtml.match(/href="([^"]+)"/i) + ?? sectionHtml.match(/href="(\/Articles\/[^"#]+)"/i); + const paragraphMatches = [...sectionHtml.matchAll(/]*>([\s\S]*?)<\/p>/gi)]; + const blurb = paragraphMatches + .map((paragraph) => stripHtml(paragraph[1])) + .find((paragraph) => paragraph && !paragraph.startsWith('Posted ') && !paragraph.startsWith('Read more')); + + if (!blurb) return; + + stories.push({ + headline, + blurb: trimBlurb(blurb), + url: hrefMatch ? new URL(hrefMatch[1], 'https://lwn.net/').toString() : 'https://lwn.net/', + }); + }); + + return stories; +}; + const travelCities = JSON.parse(await readFile('./datagenerators/output/travelcities.json')); const regionalCities = JSON.parse(await readFile('./datagenerators/output/regionalcities.json')); const stationInfo = JSON.parse(await readFile('./datagenerators/output/stations.json')); @@ -143,6 +207,38 @@ if (!process.env?.STATIC) { } }); + app.get('/api/linux-news', async (req, res) => { + try { + const response = await fetch('https://lwn.net/', { + headers: { + 'User-Agent': `ws4kp/${version}`, + }, + }); + + if (!response.ok) { + throw new Error(`LWN request failed with status ${response.status}`); + } + + const html = await response.text(); + const stories = parseLwnStories(html); + + if (stories.length === 0) { + throw new Error('No LWN stories found'); + } + + res.json({ + success: true, + stories, + }); + } catch (error) { + res.json({ + success: false, + stories: [], + error: error.message, + }); + } + }); + app.use('/api/', weatherProxy); // Cache management DELETE endpoint to allow "uncaching" specific URLs diff --git a/server/images/logos/logo-corner.png b/server/images/logos/logo-corner.png index 3e9862f815fdf05c2dfa7726eff47a40465a458d..d17345f51948f917dcfce9916b1ba4ab47efa43e 100644 GIT binary patch delta 10102 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

{ zU>NUj>}7bRGG$zU5ylv-j&%6u{q1yRlKu#O_Y%<%r&hO( zTfA(0^=#V&fa@x*XA3+JyKIcHIyI00!GaNUWBk4>4MVamjaE9XEsON3#&sY*<6V-vN zwy^5G_lO_23=9tXpbs4vtds|6>EWcsgeJ<4NlCbE@q88ob!Y?P0mN3P1}>Ecu5X~M z^KY+zgcuYduphy|`B(*m2l;XM=a2)IOCme_KFTRYG8!Nc= zzJAoCd?o2%NOSg#DlR;CGJk&PF3YkAxm?atA;i>6G;#T3$MS>6*t5NhfR1}EzIO2I znV9tl-%gQ0q|sAr^_9qA*?6hd6AIX^TVPdxW5fiyDWpN7q8Qy#0|=2;7*m=>2lrb& zX$-~~F1hpz-23+eRyVsii8QMA6jz)Cc*?WuJQmD^_KuElw!K^qM;yBsQ$>uwdyna2 zo1!Haf~QK}(hD#Lzih~)h#+chgy#hn1065EPE~spEnp3nIN*aive@I>|5VAblS(On zC`i%YKfsQ?JzVvR{rvLUkxZRXO5Z@1&)u?tUa1Z#np5xb!!Oo_1N9HMTzt!Ba;6Lr zh84QpbZIFkOs}A-WD+OLJdQWsc!Pb-&CEY#9y5-E-#+{yn_3FF{i_YQz|NifD6c4E zcx5R)oz1khwsQB~cacsPkaLBBr*`sx=kH9Vs-lqP@9yS%f6g$sAV@sx^HKpG*7*-* z#Q#nR(&%|s1%TZI2zGK3qTF`FaAr-Z20%opEKShezK{0Je_>?RR~SFKnBLxhJ~}r( zNUHIxwjRRVsVT1C|Wo`V2)e`N&6PpR@(mr`3hikg}lT3cJGC@ZG2 zTqw=F!lxIUL&KO71o+#df8*@4&!M4iBwPBGV`t8$p z^4Hejb_(;R&Y@v+v9Et2mvfnamRQCn=R(TT%J{lsqD2o-!ptev4EC;~wJ**1+Tu{1 zs4ul%$Ez@K98gEj3)Dg68z)rtL)Q~r&t|%wUFssju)-|IO}2pU-o2Y8OP*xZs2Xyv zN4lsoZ?NE4C5T;4olpoUnM{UMDupqIS<{MHw73tnl)@#zX?#@ zdv6uSnGIq?eu7nzflFn7z>2NsStDf)mfcO2q@7Tvi;GLx-&M#>zw6?gcWtJyaw37E zu_{MM7=rH2tR*d9V_4efNy-`8=;W| z7&~S(qeoUFC~v&+CbczXB*ZdWUS7uZV`>Oozf>y8nWr|8G~juE9_u%3AzfHb{TMsB zt5&V1zrP<5ValXBG}9f91F&W54*ve~o={+oD4J;@$k?)FJ2&3Bid%lSm)Dz4z)6;X zkDKd(x{-Tlz(%HA&kwk2uq_h~_Bw3bZ2iVz!>akocdzEDyDwtl$3H{Suxa_q+c-Fm zJse9gNNr6CBEt569Xr^!ZyzE;!}#%J`wmcDkqU`jw{9b;ahEWx;bQK*>$l``xvV9>sw9(1X3UrYz}mHI5rJ8=jt8K>zn=}eJdPhjXqJ{m=N_ucpS)!mQc6xIFtXoWb)*RBpe4YJokaHVW$m5t13&EK97iyN~O5^nrr#xum7Es z=bvhQQV}XDDi|Cbr83t}eWydQO;94A@CIbMfhn7*S*CC@tZ{3E7ZF zMS1#v>1S-L7Dy&j6i>beCpA1^jwhb_8*@)u#93!wjFJFs9K^b#_6n^(NTa8YJq^Sv zTR{;q7$aQ0C`m52h@E@q(Av>Yt$%Vn*!clQ&IW88^P#oCb97Ke+);0=DYiOKM^{^=e4C}KkuyG;u|%)OmF?}^{B#%ch*u@V^1+R zZrsFezq*6U$|`<*>-R|{5=@ygj+^gq;-Zh2(J+2AwS6|)8uC4o+d%^@n zguzUXwIA+c?wlzMA3lsv&2@QvLji4n9RpNX*f$RM?%l)VOCG1Qqm#<2N<@TxEiE{y z3hG9t0cGRHjr{6Yzox9boS*&lRvZT=9W$1%x} zEh(nAzk~1m+pB!*i^nl>;sny^G~L}j^!E1B-``JLTN|oMUtb^3zjcU76WdYGW7hNv zo><$#?!8GWi*tw(Hg4R6>$z-y-m;mA6Rn}z)3k@ebUBX6(AwI@2kX}J(uPr#)*Q#~ zJqIZ(Nl;l)&S1|j+FDxy7#z&-@;m*U^3g*$MwmKjBp>W;p{;$m&z}$&*BzTzpxL>o zjv(vVRTYm?$)4t}^gA1p{l*ax$Yut);Y(kpsA3GG=3GPP-sN;{evsmSL>sCe`wsR| zI{tjd%=jGrZR^>y;#LF?G1h8kvxX(iIaqwCPdWxBL;;h3e_oFudV( zS~e~rdFWA$_S4(j%g&uUx#Ef|dF`$D=hweCAguDygDt z&9~`n-%n>}Cj$cm6crVJF}!9B{n-@#*#uJ;-9_7$ztYqE5`$Tx;nbf~SUHKdEsxQ@ z{7rD-LxUNUlw9Dz;`zG0*ZK#*Uagv})S3k@= z@Apiuuj0JM$e!lz6IQHu-ZhSm@MklFeC5l3U#7Tn47DG*&dz{0 zNM@h|yeuYJL?TsTom2Jja{UCx0HQF2s*QF#sbW+OxEVZm5HW&rlDMQWDAz39#^*k{ zFqCu=p`oFHYp(qwqsKLpl`*6XY(T}!_A;35r+_vd`_p|aS+XQ-_u0>Vj#JOQg@<0U zM$9CN@p6NxmjN+K_4b@510P!PR;ALaX6Y}>YtZ{GMdf;eh% zaWNGY73^!-hv#__34WS2YZm`>)s6hyUz0e=B1G(N-boe$g{a@PDBz^PN#V-?LOQQ6 zCs~LgjRKiN@AB@FFW}|uFMN)hIg^2d)f7(tCdsl%pn~gaNKas>j0n~(P~YEDfA5ct zRN1%p4AGl^a>l=+x8@w|n{xItc9#7&O^n#clNjOS$HM#xD{!0d;VT#P;Rn9L6i9hs zrGv8GzFwM}o6#5pLA|T5xrXom{2}gtt_&Nb7DSwo4l8jHJ!0(T_z|)2@_8{n4+*kt zc=g8?P@k~&wl-S!u4mng-y$gkkvoNw^F09}{)UQwPiW2sP&_L=^3$7s%Ia0Cm^1e@L`#Wp6#;(tzyqWTN_g@4r}_PZ5BlwuFz6^kVPPTP zxba3NAA1V@-X!jP3RE2&0nO`AVnh%v!B`Pk)`FKtf@ja|W9+a&CZG5TmOSw|r!6{- zkA7r-4v#&ygngUdqrY<})J!L*fWNg57Hb&!44Dz&-?0d)gsdV7vY9?QSKrQm z9oOxEzPm^dKx_5{R3YK3Mb8ZY4Q!Lf4*q;pJOwe4TuDp};u0z0N9;xdQ1O{n%F>?TFzb?Z92{eV<6V6@90!UDOlS-;u16~Azdxly&hyCSlyu4= z;aK{5`f?Pf6L$3>bo3igC@=ICoCsZieaSqY^1xP5QJh2p{p;@Fl=BWyGIlJc;2qNa zojmu(>j;qP+k;AQn(8O3RD75!a%dFV$UM^#z7_5)V0S=WuTtLW|Qr@#0zv~C3R=RZr=zNg6z zoQdZ~Vaz~~!g#8B(G`Thj1O#oc*QJ!{zd2wI1+gRMy%)>0fS4^*0-pwtwluGy?Zx; zE!)?;mn$y2jKP6^KiVaXsIKJ7%P*(9s|zDAIMBycS6)GPXFCR~fB*c)hq>meE65BE zASiAw%XL>>$%^G~Awa?r=1n=oycza@(Ev{_d4x=Vo3$HGK5y1L5F7`8dJeq9ColO7 zrN`gEHs@vrCf~=5bH2&tSACJ{>Pl9ve3}EB{)9;6HCaq0_9~@6S3zJ!d~gV~j>hIy z2o=AmKf4OydAwiEi!Tk}gDrhr`>(&`ifg~lunK$B;*Z8J?tFlPbWvFM*kh07w%dP0 zc||n=bvJ(dM^shWK#YigP(6Gke|qc%(&=J?rF`v|zDj?t6wmW;9EZlK<0&e!qZ~MR zh{vB^N#mKlE-=G z(Qnf*u8tXVK0)|H6x6;bWjpf$6~||j&;u|=Fb+5-xO{(31POe9JjeQX#xddSC!D|~ zv#F(3c=+X!{AKw})-{bIK;QG=`8DGh%q2qr9mnCsdGo^G!-BAET@79R_P9k+`UZ;m z>+w8LpFszj zdHt`~GH1?gf{0dsB9TDE(APJ>o~CAo53AvfGtZ>Bq?kK@_D^ix@Cu$Pu4}0qfBH{VQAVG$!o*6@dWZ=|og%h#iVsT)-`UY)FYGc4bej+a-7M&V?=8Ug?K@~{ z+CxDyNlndva9iMOnK*!93f?^c9Fs&nsIRxbdQk{>XD7^_O?h>L9oy$6`WDD_b71RV z`1;qsPF0otQwOdatQ4C>proXj*|U%5oO8~myu5q_u4R#)4q?jBb)Q~~2A z%p}v-h2Z*(MA8+P-e9n(PE3l2a4+E{em_x(Y9KLx_!d-n`q>xB>m;~U|51c=x&R04 ztNaR{=aF;_V~1rKS66~6Y~8YzOvWBO&N}`$`Z{+ZVsJt_B30J1?M1p;w=;Y8>~Prl znVCN_Ac%38H*X%foQsICedBAiAKC}_)?e`6u$JEfTUS4s5hJP?>^b0Da^Jce{}*sr zA`&8hB*Z$xVOdbuuM>cgNF?~)*U#t5vmHKhat?_dx>=m8{E9Cbh@#^IHDp(@Fmz(Y~>wz-e<*Bpo~OOE15|?}&KF000K(Nkltn)e4EFh+RxmAz!bBkzgKooS=}s>+KmzCSbeeC)Bmv0+P>^~*(Ac+zOxY*(HuB`9g_=FaP3)|8RHuO7dKEIYuRTsG|S3&_cE-?WD)=sCB1*^9W2-}ka5Nb&i?S)Db(+8ChPWL62*Dj!Dv+;J{S`0 zyaY#-E!+0edZ0H{8vrX;uArx{k~M38)&j75cM}QI$mY$v*uQs>EnBwWX@Zy5lrpjY zeF{{qlN*g@NY90v~^ zWJl`=-dJo${qFNq2sR*ulC7xKt=M-9035OI zS+Ena%iro>^)x=Kwoi>FFFvP66i;*5Fqn0{M6BWR{C8$Dp3Ab7{?w zm^bNu1ViwSr0aUz^Hh?5&6%^g_uhL@^}_MN9WJ>#46Q9pf>7tMmy*S8fVv0PA8+ z9$U$RPyd4Avg&|CGMPb^z498@Tz)B+oGMgTrbsx}mSnR^U*90Dt%DPzp8WK&)4uig z85dqVx3G9PUTo`Sy9G~$z5y5*gu$%(L2U~{B)x&O1+Aj?1W$hXk@BJxM3D|#7g3L@ z{v_C%UQ`l(s%n6LcSstllsgBxsBAu?Yq}^%**$+C*}3c>e_AT6m&=(raUuf)gFN%h zGb~%SjQNde?zo|nabru!WO5uh*w6Mo$+m&y^t+N3^>-Ww>a01Rug`f^tIqw@Wt9~* zlkNUp;?Tqh^HW@6^8wSCUv3!>ULp=UjJMSIC<18Ib1<=gK~WymiZ8u7gwUX61aVwI zj3}vW69v7SD9vr8Tvt$A`U*AGgY@>mbL%c(Tgg?V3d(^jq62iax6t3boW*tbGp;s8 zS5J;NH%;?4b&Oj0m#3G!8qqf-eeBdPo%F%_o@W=FeoE;HC!IyQxZM6GKx3i60GZ&J zC1hj>FxYl~LzCux9EJpk&*YJ+1#QU>hUcRlAIwkw$_ft2{30VBPVOM4Z8d#;eH4tD z56SA##Y!dN;NFcq@#lxB&TU|HWjAeoRqpfe{XNe`I3lP3U;6UTPk!=m>;BZ7bvOd9JZ zBtJ&CdcJ%_an^K!!OQlrd;2C4`$&eIvs#sbBM??Ld)$AYT1p1u5? z758r+I>J8$HArWl^OZB#Z|J!BKszUT3SfL`QyVPs(-BrVM-{O+fMXV@{n~?hyb9+FUx<7Q>S@zAC!2W%gn|yR=oY|{}xXF Y2}MOw?t1&Su8btvyfXXC*yaqLDG0SHPAOp0KVCqAIcuQ%*};%8U=hW#&XLO%EO2EE|0`Lq~eU#2{;Wtcmk z9%RGXCOthCtU*-37%!W6DU27=0WWIEB@p9=_w7Z%HF6+}f*J`h<#ffXB?k~ebM=J7 zk4b(6=*Po- z8iks2$cJLSb!In*w#5u9T>i*^T4a;8x-V0{dEajCy|DpxCx}`QAE1qP7umTSS7 zT%kn1T>!)R8Q!eITk+j^6x7qsj{=>%Yw5^AwOZ1dIv%9xt^#5`l|Vm$XvYHT&V^8> zh*iKsGX+)D7$nOIW^4wLKot%;A?63?bTh9S@#=8XIqdyghPn6FQ3t4h1ymfMAy@$g zxBk20z_z&X5QX-5hJlR2O7gHFu3s*skeg`;;9-pSyyxe=r>O5EK`9}i;y%UtuE7vO ze_H}M=gXZFTpV@%3?vnZV<%%712KSsrs1{!PWjK5`cdG()&$e9%I(h%!ARt}^a7j6 z4U!MwnGU~$mW_Ce^yh+qW#{2S3cz!rOBP}TBJchYMR@Tq%`Mn{*Ze$)@%>89G{)k~ zyxZcM2HqkU``t4 zaC{sU1EwleYAG#|Ww4o$Hezh%#;mjm5<%L8tRaOkCCiN4lqgAmL7>@;u}wdQx16MA z`N-^)8C`~l-^$p~UqPE7MyXaCmvirsnkQywYVXnt^Q?C#-eiZhkXm z`-o+B5)n5L-rbdd0kH$r7%%WI&02rVP1DT0*t1XJD%$2 z+?x{)pV;J)Z+BsU|9o(WzrRy>;p+)YX11`aufe0Q40HB>(OvBAZ!qt&2AXA5O_Sk9 zmA_hI`HwG6K!MNxu#aE8YWP2ADIY&>9IEj2YeO9W13^=zQb~FDy79z-wUA|&{=qu; zKVRpIcPK`c7cZ~T)hbxkJgQlRD}LU`ubz**CM~4G&`1+AE+JNm)F)V5ToeBF^PMc8 z-|leAV0>GD%()*L&(1yjxavvEgpP;`&{lCuz`fYtY{1zm5at6L}RFi{db^>t2LnAaZLjp|fsL&b@ z@VmdMan!-%`0;-Yuzygg2s9NQ+5%B5ESn!u_1>|6bWW9|HbP^-kVHaz0u^zo8$?WO zYvHq}v;e()^VB8%!|>$GxwL zM2fW;0<7CKz&C!@!=*pn#brO+#Z#{bD=k2ObrT)L7JN<`CI~RbBF5C-l>*fH(+oHMB`liJ3c!|K88$O{l5^;iPIg^?r=%8o zM>3XtWgpF<2o*tmqu^bpoZW;doDC~~_mfeccy*9wW{E^NU{)(verh6@9b<{3V(Dnr z18iK52g2l*2J@y>0a&*Uw(PNp2utTg#1(Zh*pHX`d`!L49e;(=#J|t&ZsC6|ZaRyw z!j654ARIJ3!T_813^J*+O7}Q_iz;mBQIbShI@{6TxWlqx2Z#vsrdF9yYhr=SudEK3 zQRDO@I;q5loxKg#+?HZha!_L?t`@w^p6EphSr)Rh$$O-lfOnAKh5z>Wre zLpWCvm|e4&MES|-DYu@JaqUT?n2<*TJ9_I3)*bYpIND$;idxvz*3^DCMCYl6yD6 z+Rek9e$8IazGe@f{@xyc8Vx5?F~JLI=9bIGTJQcrC6VFc<6!4crt-=)-OQh8IQJ&l zzIPOWwwiI;35O`PmXvB+Mx`YsZc+a1z{uAjltoi3OdnqXpkjoxmm0QsKm_>cA%=0| zQchnT^U>9<9J?&R#0C9_U(I;xjRva9%7v|*I=2o2>)v(z#zq)_8qIiWgEN!ZK*K5z zY*qg15H}{ktO*qsPOCYhs;pk@X8+*28+W8U@S>A(!SohBwjdodccdBIztwQZTNQ5G z5am&`SZqj0l|86_f(fXvf7iN{MwPFe(Z(I0ikLp33MiX*rNrW5BEU(jTG{mN8e7)X z*!IsYd~U@Mi)TiEhzM`@)cM|>!(4aw0K-iO%f8g5qo(kU%GdqKq1&I+o^ zA2()Ti^(u;3jh9CMg}BC`24X3BITjCmDB^$)7Rv_Eip}R7d`vy^kx-~SmY{S1ND^a z?jGX%_YAXbUju-pb7GPTs9HcV0@pv2QO_)q!1>2jk)()!j!R}#*lrIyT;sV!^czsRUX+M^X9fuKv;D^3*AX02eq{tGkao{ zxsz(ln_Q!NoC}o#xiMNl6~yW-)t3#CNXQz(M}G!?7p~jKkq5-osuAz(NcqWQ%FBBb zs)^y6TL%#=*5V7*uK)8}TDa;r{iIfT?w!~z`2^P7k}-WkKg|rZQRS--#ys}s2&XL< zYO&?D9m2KG#?f1|kDgQEtA^bX4i@u?Bn5l!MC1uUmTKMeZHex5UU`1RF zF`tCQjhhB;1*9OVnNOhfJ$=B}F+D@R?%+%;mz=!ZXMKX52Ye^2#BltSI-fi$rK@Fs zKOM;^2#hpaskL@MeFqlUIXs1PZX55`rKL=y5FAgRoX4Cue=RR~E95>5B?U=AH`B37 zFyh9su08+|JGYghQCUEXpW*y@Pc64j@K)!uhw@;OH+PH+CEzGEe9s{uk@8O;9OB4X z@9_5PYuQ#GbxUahW85T|rYUh8G4;TI4})}-$a(%15btG5p85*7sT_A*q+s2}GVA&W zOZ0SHDT~55!ZwUmLNPwjiE|9Z4_S5%EN=NqzO&+>EpZ~?wi-NPA=iQU>jlq$zA~Q^RPxc#uxAy2yuptV zJ0nmr&eKAFBTn92F}_da&y|cA_4{W5FDWe)@|{q{H3(Poy$Syl-xoo}X|n(~C<9k* zH-Z>PR4uNpUs&YZ6~SurVO*9MMNJNwvXMvcd=yn>)lsXdcE6w9gA*8S!py~kOfYZp z=)Jdrz|2O<7|rD}XmQRIs#FhufCOvA$&`x{dA>5Abw(y{mmeNT$953Fdbzy&yLO(c zN&#pjj;V4;C_BISH^ueICpu*eUC5OsB7fR1@GS7*>6X3QUSsRltt?-@g8jAQxZsu+ zY$hNE6OHHRe?FggckDpbvMlpnlFRLR)iA6gURc#)ICaeAea66M)ww%=hM?>mha3;r zUk!+Lxvt+L^i`^oMdlNWDtV2x#AK+*5c(;o1fUg-#P8=g8j2QMGU2?tSoHTpV3qE6 z!$5B@eSLj&bawFic181okCV6Fv^1JcR2BPPE6M?I-LE}Cpij| zzm2^lMV!SeGPrZT&MbEd;D%XV@LuiPma+ji{V8!M(vGpd@@ENu>;LI8f^z}I#Y;be zyPraHt96#>WyyVUj07OCvr(ZhUdhVC59i?r?&q?LE+C2whaS3;dGqIUcvlzGCe0(( z`K;}k%lBSrEqL+P6uc8vFrYSM!XC&x#6fOQ>PncBp9?&de&k=J=;sD1z0P*7MjUO8U40I0w2e)=y8e}7LqKRx+UmaROTpZ)MU zcJA20!w)@#qJEbGj4@nr;n%t5nDhDCBOT;!trWR)DV{sPG#>+zJl+zv2pZcOWm7U#;$5e76eR#`r$%|ih)X3leeEO_@f1)vlk04!$5C#H8Ptcgc@`JglKM~gTeqo~CtsOqbF({OOIHwR23aQHR%8%b@G`MQb8mzVa z=bdM}oEX2YVTDu@o_c4LkIkL{fXz~>A-61(lj4N4NJVTZZid6lRCpNVtH?|Xg1J&W z?=~!N0Z~68I}GByhd^%r;;SWP!NY(#FolbhLy!v}CFz2@mAX2*kRvVS^Dfq9S;nSy zcXR!JNgrZ=I*Ye@VywcFsZFL-HgMTjzKe*kWcf<2dzrC-5@?S-ms_ZTV7@|$dBM3p zlF#(+CJL8_j-fwBfdXRkRi|5~s=7gfbk;gzrBlVBC9U~0KDP^#jf&Tz_3g(rFM;g^ zThZCzZ$D_b>*a!LRprvJeU&7RS^a_49JTs?1BeK>-}(n0dE^nSwfyB@|21~pk*po4 zQskexq~rnL$2>89X=x(xOWgvjQh2hyzi5#%h2KG@K-U*z3Of>FDFason$W`Ysm1Cl zT=qu@!TBIQM!79(^>K&7QbXTT73+fI2Ko7#zvR=G{Fn^4r(~jt&wTpR{Nk6tA+%tge?;{Gaq`Z6$WwVf8DQ;l#Ou5kDL--g}eFKy%9p(8y zKF>MB1K5`FT>G*6LsNW!2_x#obo|RmvfU3@x=F$ zF#rce1cn>|$+HaK)@Navsw?O1e}f+%-6+yJZ+QZ!6q8-q2o>izJ=qd2essLIN}SSy zo2umeDj+_d1}_=|ChDvCoRg}M$Y0B4e=pO) z3PZ>UDOjKr7(u}*QCwsB^5uN}E1yTiP&_~pjzSR{LPj!|YpawwBrgc?k2(jF+jnZNb}a5Tg)8@|iqOiUo+l7{{5lLcUk; zR~Q(O*igR3$N7b0JOHMD7GCO2_`=<;uf&dV4G(e{SDYzy<@;qgM#S-^S?tF0>71sx zFk*y~*4?M|z#Ckw4&xzcGXNaM8>^fg(6T~2n2|Vdh{uG&ypNW&=Cu(80JhSpA{rc+4 zl$QoswWI@psec$I+G$z2xSdJu2|IfG>3r34*pklNxbj1P2AQxC4qeA-^#8BU(3bhJ1P zFPa(CUdx!&)rO+Hw$;+r=0+N|aP92_kh&E4i8tND3dc-oGHpT!nJSS8i)Y3p3Eceq zl<5;wPFQAtSU9D|-oYlfJk?~RA>=y@_>f%^5GZzcfZshcz$b;B+U+5APh|HGkKjAe?c3xMAib_xwTsXvSS{;u?l^zCsB-KR{_9 zZ^5yzmKh_$Sgw8REOTb1Hk4+{nAmXa(he3)t&u5Qds`pd1`=;jc+hO|8RWj+z0JjHyC>Q>kP{7%CsC7>Z@*CBGS9!IcB-9}XME zP|7p7?v7rjTr|k^i$=NZVSf{aKki%G?_#+TG8>f^0!k4cZGNucM~e?zO3Cw?Ue%eJ z^P8f;AUKP4xA(bQW-MTpdOc$6E_c6Y5=HFToATsFA6NWNzzdtyJ%)v*a{T!lP! z3ay|JD9xNJiJyxP%;Uh~Ue*1QrFW*rqYBK(nWwyXy6;a7U z&X-Q^;!7txg}>9&;M%*Jgx)4IJheV$_9W%dg>4+!-N%#f#ExnhB&X?rkyPBL5m1Y$ z=646Vo1*>RvFopp?}U+SL=e;%uvt!AQ+WJU%i#yO8*-m{!%}ZlS^L%q^QXq_*w>C|}jR5^4P2wct-F>6{@y(Q1cDIux@aj8*OrMZ2bzFvK%D#b=oxP*% z=}XZx2CEDWTXyYtV-F2~D_JV^^fpMFDSP^qkrBg={dGTid0$Z2wLfKWP}shwj-u@E zv;5`>W%WUIRN=!1!jqfD&nW>!^`W2)G8CJH;)~!QcMPZc7hmjwzJyST7ZsEcoPoqu z%8C3VF2VA|Ac;W|1%rF`6v4zG#-bQ^)2|Ustkl|-B!Nb1X*L9ZA;PK<#g;r7@aveQqU%Z3B0_Oo!^XC4oL#EW&ChW2WL%d33;k-;5(?`;%W%k znUBJ0=9*gz)v61B1y<2fb-Rt;C2Y7k)}Inp+LDwfzZ5Zjd_vR0!IurPZ@7iYZ7DZ> zQdxE2I4ZI5_Ks05ziE_PH&oFkeDa_XzIk?)*;Be0uBSY{c9gTOR~q#gV=O;8CFS%Z zTWN2J*}1RIkM0`f>Zht6KwqpkPB!&5ictB_nm%y&Z4;}1resXPLLL9Ehk68qwR+sV zp&4-xQ@D`&-fDK3l+>1%XC5eD&XX*2*F*iX-hl959E4(ERU}e=bcS;9j8?|CB~0q5 zki;Mn{OHV#V-9JjB^I*Oa=`Q&SD#m*T1}bO-sGP@*~+{rHR_Fw_G-*2hqduAjP~F+QGm6VmgI3Zk)C!90s%V@wI?v{2+z(A3f*aAci zd3yjj-&!fP^VaUbcg811eSuE3u*R@`5Jd%uB4B*UE@()^wXs^f{6Ael#QU66RFqi0 zd1g$1YsK)$x_t#5EOV+OjBig6;I%Ev^)I=5%>-CEPgp$7G0{8J;GWG@Hf(plr%kNV zUaK>0f-{NDJCzrARoK(#(!2T7BNmKPPF#?2^lY~mirOCl000FJNkl(x+Tm~XSVwA;`-P6$kz5Pu_Y?XTE>d5W2 zlu2FgVX}HXBeOz1bs#22nB9`n*6N<^8XU4f%xJ?=YpuYSjuXCcaw`xjxQ5?;aU7t3 zTz&Hp-?-cJo-5hEatpQ)xbx@2eO&pBALLgBqxqAHrXnzDQVf)dc=HcO`Q9SGv#LhO ztH(C;ivkZk7Hoz|QvUALRw5C$?a4S|u>(nfZ+<9dIIH^slsFa)))ymO1Zt-4YFNWZ zzG|kxKd^=8IX>xcNmx)I*l>8(?g|H)F_ zH3xS7Fs~{ip$~CccKs+%LrYtb@tjk=$_BmH@166#2>%~zeuU3WM{vRh` z6(V)+9~q2TCUsQ+<;3Nk9u606K6BD|zW2m-8ktgyV0L%Hft?K!56rIKh`OJD_&VAX zTBBjc`O@ORNRyqz3B3aiI;$;A8fS>(jP@3{65HFaT=xgV_y3@Dj7!HcWlWKJL2*Ao!8CEDxlFnJWy{od;oK9HmN??Z^AeWLaSGb7wN8Dc!fTr|W>17=3#$D3<3mjD ztf0V?>r-eZDA26qcu}R3tah0~{ ziwWm zpdpZf4-*QBfcg*-tXJUV`O2BA9o>KUZG--Lf+WJZ2d8}Whzc!#HN$hS*SX@ch^%f9 zfw)Dv`h<+-3##-FrCk45liN2Ys1?L0C(LT{+2bQ7j!Rg-d6a*=SJ*ccGv;5;g`?!w zIiR-Gru;o`OJUh#UKT3K+@m6{ICml^PN>qW%C*mJKrUXtO+U3{IuWoXwcNIDfCrzc z^Um5j&3?t1VT7}PTI1r85r-)d>Xn3N1Hi>t!QYf1MTqbjLGV1c@#>T$QK?XuKdy+^ zspdD4xWaKztZOHzW7CJYF~9|jr1Tj`WZ^$xcmT(=*8+H~V^%C+F;&algKMllyu#Tl zIytoF{z=b0yZgD|%RffiKlUB{yKjGra~4fwoN*BKWR@L&Db#U++Nxl!VpGMYDQb&< z-=;ok(10?6in!lMe%`U^tM$2%;k@QDE0mIt0t7Ap40wzC5$4vQV#H%3@9{T*@UXdv z`tJci4{op#aZ67z1`|d8`B)(m=ZI4xnC5r*8mc_GtCuT(aSxk*^A!INzF { + const pageElem = document.createElement('div'); + pageElem.className = 'news-page'; + + pageStories.forEach((story) => { + const storyElem = document.createElement('div'); + storyElem.className = 'story'; + + const headlineElem = document.createElement('div'); + headlineElem.className = 'headline'; + headlineElem.textContent = story.headline; + + const blurbElem = document.createElement('div'); + blurbElem.className = 'blurb'; + blurbElem.textContent = story.blurb; + + storyElem.append(headlineElem, blurbElem); + pageElem.appendChild(storyElem); + }); + + outputElem.appendChild(pageElem); + }); + + this.pageHeight = container.offsetHeight; + this.timing.totalScreens = Math.max(1, pages.length); + this.timing.delay = new Array(this.timing.totalScreens).fill(1); + this.calcNavTiming(); + + const top = -this.screenIndex * this.pageHeight; + outputElem.style.top = `${top}px`; + + this.finishDraw(); + } +} + +registerDisplay(new LinuxNews(14, 'linux-news')); diff --git a/server/styles/scss/_linux-news.scss b/server/styles/scss/_linux-news.scss new file mode 100644 index 0000000..75ab2ed --- /dev/null +++ b/server/styles/scss/_linux-news.scss @@ -0,0 +1,54 @@ +@use 'shared/_utils' as u; + +.weather-display .linux-news { + &.main { + height: auto !important; + min-height: 250px; + } + + .container { + position: relative; + top: 15px; + margin: 0px 10px; + box-sizing: border-box; + height: 250px; + overflow: hidden; + } + + .news-output { + position: relative; + + .news-page { + height: 250px; + box-sizing: border-box; + padding: 0 8px; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .story { + height: 116px; + overflow: hidden; + } + + .headline { + font-family: 'Star4000'; + font-size: 17pt; + line-height: 22px; + color: #ff0; + text-transform: uppercase; + @include u.text-shadow(); + margin-bottom: 4px; + } + + .blurb { + font-family: 'Star4000'; + font-size: 14pt; + line-height: 16px; + color: #fff; + @include u.text-shadow(); + overflow: hidden; + } + } +} diff --git a/server/styles/scss/ws.scss b/server/styles/scss/ws.scss index 3403782..2644340 100644 --- a/server/styles/scss/ws.scss +++ b/server/styles/scss/ws.scss @@ -15,4 +15,5 @@ @use 'media'; @use 'spc-outlook'; @use 'server-observations'; -@use 'shared/scanlines'; \ No newline at end of file +@use 'linux-news'; +@use 'shared/scanlines'; diff --git a/server/styles/ws.min.css b/server/styles/ws.min.css index 80f6e8f..fa41163 100644 --- a/server/styles/ws.min.css +++ b/server/styles/ws.min.css @@ -1,2 +1,2 @@ -@font-face{font-family:"Star4000";src:url("../fonts/Star4000.woff") format("woff");font-display:swap}body{font-family:"Star4000";margin:0}@media(prefers-color-scheme: dark){body{background-color:#000;color:#fff}}@media(prefers-color-scheme: dark){body a{color:#add8e6}}body.kiosk{margin:0px;padding:0px;overflow:hidden;width:100vw;background-color:#000 !important}#divQuery{max-width:640px;padding:8px}#divQuery .buttons{display:inline-block;width:150px;text-align:right}#divQuery .buttons #imgGetGps{height:13px;vertical-align:middle}#divQuery .buttons button{font-size:16pt;border:1px solid #a9a9a9}@media(prefers-color-scheme: dark){#divQuery .buttons button{background-color:#000;color:#fff}}#divQuery .buttons #btnGetGps img.dark{display:none}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.dark{display:inline-block}}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.light{display:none}}#divQuery .buttons #btnGetGps.active{background-color:#000}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps.active{background-color:#fff}}#divQuery .buttons #btnGetGps.active img{filter:invert(1)}#divQuery input,#divQuery button{font-family:"Star4000"}#divQuery #txtLocation{width:calc(100% - 170px);max-width:490px;font-size:16pt;min-width:200px;display:inline-block;background-color:#fff;color:#000;border:2px inset gray}@media(prefers-color-scheme: dark){#divQuery #txtLocation{background-color:#000;color:#fff;border:2px inset gray}}.autocomplete-suggestions{background-color:#fff;border:1px solid #000;position:absolute;z-index:9999}@media(prefers-color-scheme: dark){.autocomplete-suggestions{background-color:#000}}.autocomplete-suggestions div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16pt}.autocomplete-suggestions div.selected{background-color:blue;color:#fff}#divTwc{display:block;background-color:#000;color:#fff;width:100%;max-width:640px;margin:0}#divTwc.wide{max-width:854px}.content-wrapper{padding:8px}#divTwcMain{width:640px;height:480px;position:relative}.wide #divTwcMain{width:854px}.kiosk #divTwc{max-width:unset}#divTwcLeft{display:none;text-align:right;flex-direction:column;vertical-align:middle}#divTwcLeft>div{flex:1;padding-right:12px;display:flex;flex-direction:column;justify-content:center}#divTwcRight{text-align:left;display:none;flex-direction:column;vertical-align:middle}#divTwcRight>div{flex:1;padding-left:12px;display:flex;flex-direction:column;justify-content:center}#divTwcBottom{display:flex;flex-direction:row;background-color:#000;color:#fff;width:640px}.wide #divTwcBottom{width:854px}@media(prefers-color-scheme: dark){#divTwcBottom{background-color:#303030}}#divTwcBottom>div{padding-left:6px;padding-right:6px}@media(max-width: 550px){#divTwcBottom>div{font-size:.9em}}@media(max-width: 500px){#divTwcBottom>div{font-size:.8em}}@media(max-width: 450px){#divTwcBottom>div{font-size:.7em}}@media(max-width: 400px){#divTwcBottom>div{font-size:.6em}}@media(max-width: 350px){#divTwcBottom>div{font-size:.5em}}#divTwcBottomLeft{flex:1;text-align:left}#divTwcBottomMiddle{flex:0;text-align:center}#divTwcBottomRight{flex:1;text-align:right}#divTwcNavContainer{display:none}#divTwcNav{width:100%;display:flex;flex-direction:row;background-color:#000;color:#fff;max-width:640px}#divTwcNav>div{padding-left:6px;padding-right:6px}#divTwcNavLeft{flex:1;text-align:left}#divTwcNavMiddle{flex:0;text-align:center}#divTwcNavRight{flex:1;text-align:right}#imgPause1x{visibility:hidden;position:absolute}.HideCursor{cursor:none !important}#txtScrollText{width:475px}@font-face{font-family:"Star4000 Extended";src:url("../fonts/Star4000 Extended.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Large";src:url("../fonts/Star4000 Large.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Small";src:url("../fonts/Star4000 Small.woff") format("woff");font-display:swap}#display{font-family:"Star4000";margin:0 0 0 0;width:100%}#container{position:relative;width:640px;height:480px;background-image:url(../images/backgrounds/1.png);transform-origin:0 0;background-repeat:no-repeat}.wide #container{padding-left:107px;padding-right:107px;background:url(../images/backgrounds/1-wide.png);background-repeat:no-repeat}#divTwc:fullscreen #container,.kiosk #divTwc #container{width:unset;height:unset}#loading{width:640px;height:480px;max-width:100%;text-shadow:4px 4px #000;display:flex;align-items:center;text-align:center;justify-content:center}#loading .title{font-family:Star4000 Large;font-size:36px;color:#ff0;margin-bottom:0px}#loading .version{margin-bottom:35px}#loading .instructions{font-size:18pt}.heading{font-weight:bold;margin-top:15px}#settings{margin-bottom:15px}#enabledDisplays,#settings{margin-bottom:15px}#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#ff0}#enabledDisplays .press-here,#settings .press-here{color:lime;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:red}#enabledDisplays .no-data,#settings .no-data{color:silver}#enabledDisplays .disabled,#settings .disabled{color:silver}#enabledDisplays .press-here,#settings .press-here{color:#fff}@media(prefers-color-scheme: light){#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#990}#enabledDisplays .press-here,#settings .press-here{color:#000;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:#900}#enabledDisplays .no-data,#settings .no-data{color:hsl(0,0%,30%)}#enabledDisplays .disabled,#settings .disabled{color:hsl(0,0%,30%)}}#enabledDisplays label,#settings label{display:block;max-width:fit-content;cursor:pointer}#enabledDisplays label .alert,#settings label .alert{display:none}#enabledDisplays label .alert.show,#settings label .alert.show{display:inline;color:red}#divTwcBottom img{transform:scale(0.75)}@media(max-width: 550px){.wide #divTwcBottom img{transform:scale(1)}}#divTwc:fullscreen,.kiosk #divTwc{display:flex;align-items:center;justify-content:center;align-content:center}#divTwc:fullscreen.no-cursor,.kiosk #divTwc.no-cursor{cursor:none}#divTwc:fullscreen #display,.kiosk #divTwc #display{position:relative}#divTwc:fullscreen #divTwcBottom,.kiosk #divTwc #divTwcBottom{display:flex;flex-direction:row;background-color:rgba(0,0,0,.5);color:#fff;width:100%;position:absolute;bottom:0px}.kiosk #divTwc #divTwcBottom{display:none}.navButton{cursor:pointer}#ToggleScanlines{display:inline-block}#ToggleScanlines .on{display:none}#ToggleScanlines .off{display:inline-block}#ToggleScanlines.on .on{display:inline-block}#ToggleScanlines.on .off{display:none}.visible{visibility:visible;opacity:1;transition:opacity .1s linear}#divTwc:fullscreen .hidden{visibility:hidden;opacity:0;transition:visibility 0s 1s,opacity 1s linear}.github-links{width:610px;max-width:calc(100vw - 30px);display:flex;justify-content:space-evenly;flex-wrap:wrap}.github-links span a{text-decoration:none;outline:0}.github-links span .widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.github-links span .btn,.github-links span .social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.github-links span .btn{border-radius:.25em}.github-links span .btn:not(:last-child){border-radius:.25em 0 0 .25em}.github-links span .social-count{border-left:0;border-radius:0 .25em .25em 0}.github-links span .widget-lg .btn,.github-links span .widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.github-links span .octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}@media(prefers-color-scheme: light){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}}@media(prefers-color-scheme: dark){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #58a6ff;outline-offset:-2px}.github-links span .btn{color:#c9d1d9;background-color:#1a1e23;border-color:#2f3439;border-color:rgba(240,246,252,.1);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #21262d, #1a1e23 90%);background-image:linear-gradient(180deg, #21262d, #1a1e23 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#292e33;background-position:0 -0.5em;border-color:#8b949e;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #30363d, #292e33 90%);background-image:linear-gradient(180deg, #30363d, #292e33 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#161719;border-color:#8b949e;box-shadow:inset 0 .15em .3em rgba(1,4,9,.15);background-image:none;filter:none}.github-links span .social-count{color:#c9d1d9;background-color:#0d1117;border-color:#24282e;border-color:rgba(240,246,252,.1)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#58a6ff}.github-links span .octicon-heart{color:#db61a2}}#share-link-copied{color:#990;display:none}#share-link-instructions{display:none}body.kiosk #loading .instructions{display:none !important}.kiosk>*:not(#divTwc){display:none !important}#divInfo{display:grid;grid-template-columns:1fr 1fr;max-width:250px}.weather-display{width:640px;height:480px;overflow:hidden;position:relative;background-image:url(../images/backgrounds/1.png);height:0px}.weather-display.show{height:480px}.weather-display .template{display:none}.weather-display .header{width:640px;height:60px;padding-top:30px}.weather-display .header .title{color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000";font-size:24pt;position:absolute;width:250px}.weather-display .header .title.single{left:170px;top:25px}.weather-display .header .title.dual{left:170px}.weather-display .header .title.dual>div{position:absolute}.weather-display .header .title.dual .top{top:-3px}.weather-display .header .title.dual .bottom{top:26px}.weather-display .header .logo{top:30px;left:50px;position:absolute;z-index:10}.weather-display .header .noaa-logo{position:absolute;top:39px;left:356px}.weather-display .header .title.single{top:40px}.weather-display .header .date-time{white-space:pre;color:#fff;font-family:"Star4000 Small";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;left:415px;width:170px;text-align:right;position:absolute}.weather-display .header .date-time.date{padding-top:22px}.weather-display .main{position:relative}.weather-display .main.has-scroll{width:640px;margin-top:0;height:310px;overflow:hidden}.weather-display .main.has-scroll.no-header{height:400px;margin-top:0}.weather-display .main.has-box{margin-left:64px;margin-right:64px;width:calc(100% - 128px)}#container>.scroll{display:none;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;width:640px;height:77px;overflow:hidden;margin-top:3px;position:absolute;bottom:0px;z-index:1}#container>.scroll.hazard{background-color:#702323}#container>.scroll .scroll-container{width:640px}#container>.scroll .scroll-container .fixed,#container>.scroll .scroll-container .scroll-header{margin-left:55px;margin-right:55px;overflow:hidden;white-space:nowrap}#container>.scroll .scroll-container .scroll-header{height:26px;font-family:"Star4000 Small";font-size:20pt;margin-top:-10px}#container>.scroll .scroll-container .fixed{font-family:"Star4000";font-size:24pt}#container>.scroll .scroll-container .fixed .scroll-area{text-wrap:nowrap;position:relative}.wide #container>.scroll{width:854px;margin-left:-107px}.wide #container>.scroll .scroll-container{margin-left:107px}.weather-display .main.current-weather.main .col{height:50px;width:255px;display:inline-block;margin-top:10px;padding-top:10px;position:absolute;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.current-weather.main .col.left{font-family:"Star4000 Extended";font-size:24pt}.weather-display .main.current-weather.main .col.right{right:0px;font-family:"Star4000 Large";font-size:20px;font-weight:bold;line-height:24px}.weather-display .main.current-weather.main .col.right .row{margin-bottom:12px}.weather-display .main.current-weather.main .col.right .row .label,.weather-display .main.current-weather.main .col.right .row .value{display:inline-block}.weather-display .main.current-weather.main .col.right .row .label{margin-left:20px}.weather-display .main.current-weather.main .col.right .row .value{float:right;margin-right:10px}.weather-display .main.current-weather.main .center{text-align:center}.weather-display .main.current-weather.main .temp{font-family:"Star4000 Large";font-size:24pt}.weather-display .main.current-weather.main .icon img{margin:0 auto;display:block}.weather-display .main.current-weather.main .wind-container{margin-left:10px;display:flex}.weather-display .main.current-weather.main .wind-container>div{width:50%}.weather-display .main.current-weather.main .wind-container .wind{text-align:right}.weather-display .main.current-weather.main .wind-gusts{text-align:right;font-size:28px}.weather-display .main.current-weather.main .location{color:#ff0;max-height:32px;margin-bottom:10px;padding-top:4px;overflow:hidden;text-wrap:nowrap}#extended-forecast-html.weather-display{background-image:url("../images/backgrounds/2.png")}.weather-display .main.extended-forecast .day-container{margin-top:16px;margin-left:27px}.weather-display .main.extended-forecast .day{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding:5px;height:285px;width:155px;display:inline-block;margin:0px 15px;font-family:"Star4000";font-size:24pt}.weather-display .main.extended-forecast .day .date{text-transform:uppercase;text-align:center;color:#ff0}.weather-display .main.extended-forecast .day .condition{text-align:center;height:74px;margin-top:5px}.weather-display .main.extended-forecast .day .icon{text-align:center;height:75px}.weather-display .main.extended-forecast .day .icon img{max-height:75px}.weather-display .main.extended-forecast .day .temperatures{width:100%}.weather-display .main.extended-forecast .day .temperatures .temperature-block{display:inline-block;width:44%;vertical-align:top}.weather-display .main.extended-forecast .day .temperatures .temperature-block>div{text-align:center}.weather-display .main.extended-forecast .day .temperatures .temperature-block .value{font-family:"Star4000 Large";margin-top:4px}.weather-display .main.extended-forecast .day .temperatures .temperature-block.lo .label{color:#8080ff}.weather-display .main.extended-forecast .day .temperatures .temperature-block.hi .label{color:#ff0}.weather-display .main.hourly.main{overflow-y:hidden}.weather-display .main.hourly.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.hourly.main .column-headers .temp{left:355px}.weather-display .main.hourly.main .column-headers .like{left:435px}.weather-display .main.hourly.main .column-headers .wind{left:535px}.weather-display .main.hourly.main .hourly-lines{min-height:338px;padding-top:10px;background:repeating-linear-gradient(0deg, #001040 0px, #102080 136px, #102080 202px, #001040 338px)}.weather-display .main.hourly.main .hourly-lines .hourly-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.hourly.main .hourly-lines .hourly-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.hourly.main .hourly-lines .hourly-row .hour{left:25px}.weather-display .main.hourly.main .hourly-lines .hourly-row .icon{left:255px;width:70px;text-align:center;top:unset}.weather-display .main.hourly.main .hourly-lines .hourly-row .temp{left:355px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like{left:425px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.heat-index{color:#e00}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.wind-chill{color:#8080ff}.weather-display .main.hourly.main .hourly-lines .hourly-row .wind{left:505px;width:100px;text-align:right}#hourly-graph-html{background-image:url(../images/backgrounds/1-chart.png)}#hourly-graph-html .header .right{position:absolute;top:35px;right:60px;width:360px;font-family:"Star4000 Small";font-size:28px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:right}#hourly-graph-html .header .right div{margin-top:-18px}#hourly-graph-html .header .right .temperature{color:red}#hourly-graph-html .header .right .dewpoint{color:green}#hourly-graph-html .header .right .cloud{color:#d3d3d3}#hourly-graph-html .header .right .rain{color:aqua}.weather-display .main.hourly-graph.main>div{position:absolute}.weather-display .main.hourly-graph.main .label{font-family:"Star4000 Small";font-size:24pt;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-top:-15px;position:absolute}.weather-display .main.hourly-graph.main .x-axis{bottom:0px;left:54px;width:532px;height:20px}.weather-display .main.hourly-graph.main .x-axis .label{text-align:center;transform:translateX(-50%);white-space:nowrap}.weather-display .main.hourly-graph.main .x-axis .label.l-1{left:0px}.weather-display .main.hourly-graph.main .x-axis .label.l-2{left:133px}.weather-display .main.hourly-graph.main .x-axis .label.l-3{left:266px}.weather-display .main.hourly-graph.main .x-axis .label.l-4{left:399px}.weather-display .main.hourly-graph.main .x-axis .label.l-5{left:532px}.weather-display .main.hourly-graph.main .chart{top:0px;left:50px}.weather-display .main.hourly-graph.main .chart img{width:532px;height:285px}.weather-display .main.hourly-graph.main .y-axis{top:0px;left:0px;width:50px;height:285px}.weather-display .main.hourly-graph.main .y-axis .label{text-align:right;right:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-1{top:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-2{top:93.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-3{bottom:82.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-4{bottom:0px}.weather-display .main.hourly-graph.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly-graph.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly-graph.main .column-headers .temp{left:355px}.weather-display .main.hourly-graph.main .column-headers .like{left:435px}.weather-display .main.hourly-graph.main .column-headers .wind{left:535px}.weather-display .main.travel.main{overflow-y:hidden}.weather-display .main.travel.main .column-headers{background-color:#200057;height:20px;position:sticky;top:0px;width:100%;z-index:5;overflow:hidden}.weather-display .main.travel.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.travel.main .column-headers .temp{width:50px;text-align:center}.weather-display .main.travel.main .column-headers .temp.low{left:455px}.weather-display .main.travel.main .column-headers .temp.high{left:510px;width:60px}.weather-display .main.travel.main .travel-lines{min-height:338px;padding-top:10px;background:repeating-linear-gradient(0deg, #001040 0px, #102080 136px, #102080 202px, #001040 338px)}.weather-display .main.travel.main .travel-lines .travel-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.travel.main .travel-lines .travel-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.travel.main .travel-lines .travel-row .city{left:80px}.weather-display .main.travel.main .travel-lines .travel-row .icon{left:330px;width:70px;text-align:center;top:unset}.weather-display .main.travel.main .travel-lines .travel-row .icon img{max-width:47px}.weather-display .main.travel.main .travel-lines .travel-row .temp{width:50px;text-align:center}.weather-display .main.travel.main .travel-lines .travel-row .temp.low{left:455px}.weather-display .main.travel.main .travel-lines .travel-row .temp.high{left:510px;width:60px}.weather-display .latest-observations.main{overflow-y:hidden}.weather-display .latest-observations.main .column-headers{height:20px;position:absolute;width:100%}.weather-display .latest-observations.main .column-headers{top:0px}.weather-display .latest-observations.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;position:absolute;top:-14px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .latest-observations.main .column-headers .temp{display:none}.weather-display .latest-observations.main .column-headers .temp.show{display:inline-block}.weather-display .latest-observations.main .temp{left:230px}.weather-display .latest-observations.main .weather{left:280px}.weather-display .latest-observations.main .wind{left:430px}.weather-display .latest-observations.main .observation-lines{min-height:338px;padding-top:10px}.weather-display .latest-observations.main .observation-lines .observation-row{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;height:40px}.weather-display .latest-observations.main .observation-lines .observation-row>div{position:absolute;top:8px}.weather-display .latest-observations.main .observation-lines .observation-row .wind{white-space:pre;text-align:right}.weather-display .local-forecast .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:280px;overflow:hidden}.weather-display .local-forecast .forecasts{position:relative}.weather-display .local-forecast .forecast{font-family:"Star4000";font-size:24pt;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;min-height:280px;line-height:40px}.weather-display .progress{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000 Extended";font-size:18pt}.weather-display .progress .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:310px;overflow:hidden;line-height:26px}.weather-display .progress .container .item{position:relative}.weather-display .progress .container .item .name{white-space:nowrap}.weather-display .progress .container .item .name::after{content:"........................................................................"}.weather-display .progress .container .item .links{position:absolute;text-align:right;right:0px;top:0px}.weather-display .progress .container .item .links>div{background-color:#26235a;display:none;padding-left:4px}.weather-display .progress .container .item .links .loading,.weather-display .progress .container .item .links .retrying{color:#ff0}.weather-display .progress .container .item .links .press-here{color:lime;cursor:pointer}.weather-display .progress .container .item .links .failed{color:red}.weather-display .progress .container .item .links .no-data{color:silver}.weather-display .progress .container .item .links .disabled{color:silver}.weather-display .progress .container .item .links.loading .loading,.weather-display .progress .container .item .links.press-here .press-here,.weather-display .progress .container .item .links.failed .failed,.weather-display .progress .container .item .links.no-data .no-data,.weather-display .progress .container .item .links.disabled .disabled,.weather-display .progress .container .item .links.retrying .retrying{display:block}@keyframes progress-scroll{0%{background-position:-40px 0}100%{background-position:40px 0}}#progress-html.weather-display .scroll .progress-bar-container{border:2px solid #000;background-color:#fff;margin:20px auto;width:524px;position:relative;display:none}#progress-html.weather-display .scroll .progress-bar-container.show{display:block}#progress-html.weather-display .scroll .progress-bar-container .progress-bar{height:20px;margin:2px;width:520px;background:repeating-linear-gradient(90deg, #09246f 0px, #09246f 5px, #364ac0 5px, #364ac0 10px, #4f99f9 10px, #4f99f9 15px, #8ffdfa 15px, #8ffdfa 20px, #4f99f9 20px, #4f99f9 25px, #364ac0 25px, #364ac0 30px, #09246f 30px, #09246f 40px);animation-duration:2s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:progress-scroll;animation-timing-function:steps(8, end)}#progress-html.weather-display .scroll .progress-bar-container .cover{position:absolute;top:0px;right:0px;background-color:#fff;width:100%;height:24px;transition:width 1s steps(6)}#radar-html.weather-display{background-image:url("../images/backgrounds/4.png")}#radar-html.weather-display .header{height:83px}#radar-html.weather-display .header .title.dual{color:#fff;font-family:"Arial",sans-serif;font-weight:bold;font-size:28pt;left:155px}#radar-html.weather-display .header .title.dual .top{top:-4px}#radar-html.weather-display .header .title.dual .bottom{top:31px}#radar-html.weather-display .header .right{position:absolute;right:0px;width:360px;margin-top:2px;font-family:"Star4000";font-size:18pt;font-weight:bold;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:center}#radar-html.weather-display .header .right .scale>div{display:inline-block}#radar-html.weather-display .header .right .scale-table{display:table-row;border-collapse:collapse}#radar-html.weather-display .header .right .scale-table .box{display:table-cell;border:2px solid #000;width:17px;height:24px;padding:0}#radar-html.weather-display .header .right .scale-table .box-1{background-color:#31d216}#radar-html.weather-display .header .right .scale-table .box-2{background-color:#1c8a12}#radar-html.weather-display .header .right .scale-table .box-3{background-color:#145a0f}#radar-html.weather-display .header .right .scale-table .box-4{background-color:#0a280a}#radar-html.weather-display .header .right .scale-table .box-5{background-color:#c4b346}#radar-html.weather-display .header .right .scale-table .box-6{background-color:#be4813}#radar-html.weather-display .header .right .scale-table .box-7{background-color:#ab0e0e}#radar-html.weather-display .header .right .scale-table .box-8{background-color:#731f04}#radar-html.weather-display .header .right .scale .text{position:relative;top:-5px}#radar-html.weather-display .header .right .time{position:relative;font-weight:normal;top:-14px;font-family:"Star4000 Small";font-size:24pt}.weather-display .main.radar{overflow:hidden;height:367px}.weather-display .main.radar .container .tiles{position:absolute;width:1400px}.weather-display .main.radar .container .tiles img{vertical-align:middle}.weather-display .main.radar .container .scroll-area{position:relative}.wide.radar #container{background:url(../images/backgrounds/4-wide.png)}#regional-forecast-html.weather-display{background-image:url("../images/backgrounds/5.png")}.weather-display .main.regional-forecast{position:relative}.weather-display .main.regional-forecast .map{position:absolute;transform-origin:0 0}.weather-display .main.regional-forecast .location{position:absolute;width:140px;margin-left:-40px;margin-top:-35px}.weather-display .main.regional-forecast .location>div{position:absolute;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.regional-forecast .location .icon{top:26px;left:44px}.weather-display .main.regional-forecast .location .icon img{max-height:32px}.weather-display .main.regional-forecast .location .temp{font-family:"Star4000 Large";font-size:28px;padding-top:2px;color:#ff0;top:28px;text-align:right;width:40px}.weather-display .main.regional-forecast .location .city{font-family:Star4000;font-size:20px}#almanac-html.weather-display{background-image:url("../images/backgrounds/3.png")}.weather-display .main.almanac{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.almanac .sun{display:grid;grid-template-columns:auto auto auto;grid-template-rows:auto auto auto;gap:0px 90px;margin:3px auto 5px auto;width:fit-content;line-height:30px}.weather-display .main.almanac .sun .grid-item{width:auto;height:auto;padding:0;margin:0;position:relative}.weather-display .main.almanac .sun .grid-item.header{color:#ff0;text-align:center}.weather-display .main.almanac .sun .grid-item.row-label{text-align:right}.weather-display .main.almanac .sun .grid-item.time{text-align:center}.weather-display .main.almanac .moon{position:relative;padding:7px 50px;line-height:36px}.weather-display .main.almanac .moon .title{color:#ff0;padding-left:13px}.weather-display .main.almanac .moon .day{display:inline-block;text-align:center;width:132px}.weather-display .main.almanac .moon .day .icon{padding-left:10px}.weather-display .main.almanac .moon .day .date{position:relative;top:-10px}#hazards-html.weather-display{background-image:url("../images/backgrounds/7.png")}.weather-display .main.hazards.main{overflow-y:hidden;height:480px;background-color:#702323}.weather-display .main.hazards.main .hazard-lines{min-height:400px;padding-top:10px}.weather-display .main.hazards.main .hazard-lines .hazard{font-family:"Star4000";font-size:24pt;color:#fff;text-shadow:0px 0px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;text-transform:uppercase;margin-top:10px;margin-left:80px;margin-right:80px;padding-bottom:10px}.wide.hazards #container{background:url(../images/backgrounds/7-wide.png)}.media{display:none}#ToggleMediaContainer{display:none;position:relative}#ToggleMediaContainer.available{display:inline-block}#ToggleMediaContainer.available img.on{display:none}#ToggleMediaContainer.available img.off{display:block}#ToggleMediaContainer.available.playing img.on{display:block}#ToggleMediaContainer.available.playing img.off{display:none}#ToggleMediaContainer .volume-slider{display:none;position:absolute;top:0px;transform:translateY(-100%);width:100%;background-color:#000;text-align:center;z-index:100}@media(prefers-color-scheme: dark){#ToggleMediaContainer .volume-slider{background-color:#303030}}#ToggleMediaContainer .volume-slider input[type=range]{writing-mode:vertical-lr;direction:rtl;margin-top:20px;margin-bottom:20px}#ToggleMediaContainer .volume-slider.show{display:block}#spc-outlook-html.weather-display{background-image:url("../images/backgrounds/6.png")}.weather-display .spc-outlook .container{position:relative;top:0px;margin:0px 10px;box-sizing:border-box;height:300px;overflow:hidden}.weather-display .spc-outlook .risk-levels{position:absolute;left:206px;font-family:"Star4000 Small";font-size:32px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .spc-outlook .risk-levels .risk-level{position:relative;top:-14px;height:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(1){left:100px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(2){left:80px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(3){left:60px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(4){left:40px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(5){left:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(6){left:0px}.weather-display .spc-outlook .days{position:absolute;top:120px}.weather-display .spc-outlook .days .day{height:60px}.weather-display .spc-outlook .days .day .day-name{position:absolute;font-family:"Star4000";font-size:24pt;width:200px;text-align:right;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding-top:20px}.weather-display .spc-outlook .days .day .risk-bar{position:absolute;width:150px;height:40px;left:210px;margin-top:20px;border:3px outset hsl(0,0%,70%);background:linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%)}#server-observations-html.weather-display .header .title.single{font-size:20pt}.weather-display .server-observations.main{height:auto !important;min-height:250px}.weather-display .server-observations .container{position:relative;top:15px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .server-observations .server-output{position:relative;font-family:"Star4000";font-size:20pt;line-height:32px;color:#fff;text-transform:uppercase;text-align:center;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .server-observations .server-output .server-page{height:250px;padding:0 8px;box-sizing:border-box}.weather-display .server-observations .server-output .server-line{white-space:normal;overflow-wrap:anywhere;word-break:break-word;margin-bottom:6px}.scanlines{position:relative;overflow:hidden;isolation:isolate}.scanlines #container{position:relative;z-index:1;transform:translateZ(0);will-change:filter;filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98)}.scanlines #container::before,.scanlines #container::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3}.scanlines #container::before{background:linear-gradient(to right, rgba(255, 0, 0, 0.04) 0%, rgba(255, 0, 0, 0.01) 15%, rgba(255, 0, 0, 0) 50%, rgba(255, 0, 0, 0.01) 85%, rgba(255, 0, 0, 0.04) 100%);transform:translateX(-0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines #container::after{background:linear-gradient(to right, rgba(0, 140, 255, 0.04) 0%, rgba(0, 140, 255, 0.01) 15%, rgba(0, 140, 255, 0) 50%, rgba(0, 140, 255, 0.01) 85%, rgba(0, 140, 255, 0.04) 100%);transform:translateX(0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines:before,.scanlines:after{display:block;pointer-events:none;content:"";position:absolute;left:0;right:0}.scanlines:before{height:var(--scanline-thickness, 1px);z-index:2147483650;background:rgba(0,0,0,.3);opacity:.75;animation:scanline 6s linear infinite}.scanlines:after{top:0;bottom:0;z-index:2147483648;background:repeating-linear-gradient(to bottom, transparent 0, transparent var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) calc(var(--scanline-thickness, 1px) * 2));animation:none}.scanlines{box-shadow:inset 0 0 80px rgba(0,0,0,.16),inset 0 0 18px hsla(0,0%,100%,.05)}.scanlines.crt-panels-only #container{filter:none}.scanlines.crt-panels-only .weather-display{filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98);transform:translateZ(0)}.scanlines .header,.scanlines .main,.scanlines .scroll,.scanlines .date-time,.scanlines .city,.scanlines .temp,.scanlines .condition,.scanlines .location,.scanlines .label,.scanlines .value,.scanlines .title{text-shadow:0 0 1px hsla(0,0%,100%,.18),0 0 2px hsla(0,0%,100%,.06)}@keyframes scanline{0%{transform:translate3d(0, 200000%, 0)}}@keyframes scanlines{0%{background-position:0 50%}} +@font-face{font-family:"Star4000";src:url("../fonts/Star4000.woff") format("woff");font-display:swap}body{font-family:"Star4000";margin:0}@media(prefers-color-scheme: dark){body{background-color:#000;color:#fff}}@media(prefers-color-scheme: dark){body a{color:#add8e6}}body.kiosk{margin:0px;padding:0px;overflow:hidden;width:100vw;background-color:#000 !important}#divQuery{max-width:640px;padding:8px}#divQuery .buttons{display:inline-block;width:150px;text-align:right}#divQuery .buttons #imgGetGps{height:13px;vertical-align:middle}#divQuery .buttons button{font-size:16pt;border:1px solid #a9a9a9}@media(prefers-color-scheme: dark){#divQuery .buttons button{background-color:#000;color:#fff}}#divQuery .buttons #btnGetGps img.dark{display:none}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.dark{display:inline-block}}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.light{display:none}}#divQuery .buttons #btnGetGps.active{background-color:#000}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps.active{background-color:#fff}}#divQuery .buttons #btnGetGps.active img{filter:invert(1)}#divQuery input,#divQuery button{font-family:"Star4000"}#divQuery #txtLocation{width:calc(100% - 170px);max-width:490px;font-size:16pt;min-width:200px;display:inline-block;background-color:#fff;color:#000;border:2px inset gray}@media(prefers-color-scheme: dark){#divQuery #txtLocation{background-color:#000;color:#fff;border:2px inset gray}}.autocomplete-suggestions{background-color:#fff;border:1px solid #000;position:absolute;z-index:9999}@media(prefers-color-scheme: dark){.autocomplete-suggestions{background-color:#000}}.autocomplete-suggestions div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16pt}.autocomplete-suggestions div.selected{background-color:blue;color:#fff}#divTwc{display:block;background-color:#000;color:#fff;width:100%;max-width:640px;margin:0}#divTwc.wide{max-width:854px}.content-wrapper{padding:8px}#divTwcMain{width:640px;height:480px;position:relative}.wide #divTwcMain{width:854px}.kiosk #divTwc{max-width:unset}#divTwcLeft{display:none;text-align:right;flex-direction:column;vertical-align:middle}#divTwcLeft>div{flex:1;padding-right:12px;display:flex;flex-direction:column;justify-content:center}#divTwcRight{text-align:left;display:none;flex-direction:column;vertical-align:middle}#divTwcRight>div{flex:1;padding-left:12px;display:flex;flex-direction:column;justify-content:center}#divTwcBottom{display:flex;flex-direction:row;background-color:#000;color:#fff;width:640px}.wide #divTwcBottom{width:854px}@media(prefers-color-scheme: dark){#divTwcBottom{background-color:#303030}}#divTwcBottom>div{padding-left:6px;padding-right:6px}@media(max-width: 550px){#divTwcBottom>div{font-size:.9em}}@media(max-width: 500px){#divTwcBottom>div{font-size:.8em}}@media(max-width: 450px){#divTwcBottom>div{font-size:.7em}}@media(max-width: 400px){#divTwcBottom>div{font-size:.6em}}@media(max-width: 350px){#divTwcBottom>div{font-size:.5em}}#divTwcBottomLeft{flex:1;text-align:left}#divTwcBottomMiddle{flex:0;text-align:center}#divTwcBottomRight{flex:1;text-align:right}#divTwcNavContainer{display:none}#divTwcNav{width:100%;display:flex;flex-direction:row;background-color:#000;color:#fff;max-width:640px}#divTwcNav>div{padding-left:6px;padding-right:6px}#divTwcNavLeft{flex:1;text-align:left}#divTwcNavMiddle{flex:0;text-align:center}#divTwcNavRight{flex:1;text-align:right}#imgPause1x{visibility:hidden;position:absolute}.HideCursor{cursor:none !important}#txtScrollText{width:475px}@font-face{font-family:"Star4000 Extended";src:url("../fonts/Star4000 Extended.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Large";src:url("../fonts/Star4000 Large.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Small";src:url("../fonts/Star4000 Small.woff") format("woff");font-display:swap}#display{font-family:"Star4000";margin:0 0 0 0;width:100%}#container{position:relative;width:640px;height:480px;background-image:url(../images/backgrounds/1.png);transform-origin:0 0;background-repeat:no-repeat}.wide #container{padding-left:107px;padding-right:107px;background:url(../images/backgrounds/1-wide.png);background-repeat:no-repeat}#divTwc:fullscreen #container,.kiosk #divTwc #container{width:unset;height:unset}#loading{width:640px;height:480px;max-width:100%;text-shadow:4px 4px #000;display:flex;align-items:center;text-align:center;justify-content:center}#loading .title{font-family:Star4000 Large;font-size:36px;color:#ff0;margin-bottom:0px}#loading .version{margin-bottom:35px}#loading .instructions{font-size:18pt}.heading{font-weight:bold;margin-top:15px}#settings{margin-bottom:15px}#enabledDisplays,#settings{margin-bottom:15px}#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#ff0}#enabledDisplays .press-here,#settings .press-here{color:lime;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:red}#enabledDisplays .no-data,#settings .no-data{color:silver}#enabledDisplays .disabled,#settings .disabled{color:silver}#enabledDisplays .press-here,#settings .press-here{color:#fff}@media(prefers-color-scheme: light){#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#990}#enabledDisplays .press-here,#settings .press-here{color:#000;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:#900}#enabledDisplays .no-data,#settings .no-data{color:hsl(0,0%,30%)}#enabledDisplays .disabled,#settings .disabled{color:hsl(0,0%,30%)}}#enabledDisplays label,#settings label{display:block;max-width:fit-content;cursor:pointer}#enabledDisplays label .alert,#settings label .alert{display:none}#enabledDisplays label .alert.show,#settings label .alert.show{display:inline;color:red}#divTwcBottom img{transform:scale(0.75)}@media(max-width: 550px){.wide #divTwcBottom img{transform:scale(1)}}#divTwc:fullscreen,.kiosk #divTwc{display:flex;align-items:center;justify-content:center;align-content:center}#divTwc:fullscreen.no-cursor,.kiosk #divTwc.no-cursor{cursor:none}#divTwc:fullscreen #display,.kiosk #divTwc #display{position:relative}#divTwc:fullscreen #divTwcBottom,.kiosk #divTwc #divTwcBottom{display:flex;flex-direction:row;background-color:rgba(0,0,0,.5);color:#fff;width:100%;position:absolute;bottom:0px}.kiosk #divTwc #divTwcBottom{display:none}.navButton{cursor:pointer}#ToggleScanlines{display:inline-block}#ToggleScanlines .on{display:none}#ToggleScanlines .off{display:inline-block}#ToggleScanlines.on .on{display:inline-block}#ToggleScanlines.on .off{display:none}.visible{visibility:visible;opacity:1;transition:opacity .1s linear}#divTwc:fullscreen .hidden{visibility:hidden;opacity:0;transition:visibility 0s 1s,opacity 1s linear}.github-links{width:610px;max-width:calc(100vw - 30px);display:flex;justify-content:space-evenly;flex-wrap:wrap}.github-links span a{text-decoration:none;outline:0}.github-links span .widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.github-links span .btn,.github-links span .social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.github-links span .btn{border-radius:.25em}.github-links span .btn:not(:last-child){border-radius:.25em 0 0 .25em}.github-links span .social-count{border-left:0;border-radius:0 .25em .25em 0}.github-links span .widget-lg .btn,.github-links span .widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.github-links span .octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}@media(prefers-color-scheme: light){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}}@media(prefers-color-scheme: dark){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #58a6ff;outline-offset:-2px}.github-links span .btn{color:#c9d1d9;background-color:#1a1e23;border-color:#2f3439;border-color:rgba(240,246,252,.1);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #21262d, #1a1e23 90%);background-image:linear-gradient(180deg, #21262d, #1a1e23 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#292e33;background-position:0 -0.5em;border-color:#8b949e;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #30363d, #292e33 90%);background-image:linear-gradient(180deg, #30363d, #292e33 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#161719;border-color:#8b949e;box-shadow:inset 0 .15em .3em rgba(1,4,9,.15);background-image:none;filter:none}.github-links span .social-count{color:#c9d1d9;background-color:#0d1117;border-color:#24282e;border-color:rgba(240,246,252,.1)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#58a6ff}.github-links span .octicon-heart{color:#db61a2}}#share-link-copied{color:#990;display:none}#share-link-instructions{display:none}body.kiosk #loading .instructions{display:none !important}.kiosk>*:not(#divTwc){display:none !important}#divInfo{display:grid;grid-template-columns:1fr 1fr;max-width:250px}.weather-display{width:640px;height:480px;overflow:hidden;position:relative;background-image:url(../images/backgrounds/1.png);height:0px}.weather-display.show{height:480px}.weather-display .template{display:none}.weather-display .header{width:640px;height:60px;padding-top:30px}.weather-display .header .title{color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000";font-size:24pt;position:absolute;width:250px}.weather-display .header .title.single{left:170px;top:25px}.weather-display .header .title.dual{left:170px}.weather-display .header .title.dual>div{position:absolute}.weather-display .header .title.dual .top{top:-3px}.weather-display .header .title.dual .bottom{top:26px}.weather-display .header .logo{top:30px;left:50px;position:absolute;z-index:10}.weather-display .header .noaa-logo{position:absolute;top:39px;left:356px}.weather-display .header .title.single{top:40px}.weather-display .header .date-time{white-space:pre;color:#fff;font-family:"Star4000 Small";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;left:415px;width:170px;text-align:right;position:absolute}.weather-display .header .date-time.date{padding-top:22px}.weather-display .main{position:relative}.weather-display .main.has-scroll{width:640px;margin-top:0;height:310px;overflow:hidden}.weather-display .main.has-scroll.no-header{height:400px;margin-top:0}.weather-display .main.has-box{margin-left:64px;margin-right:64px;width:calc(100% - 128px)}#container>.scroll{display:none;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;width:640px;height:77px;overflow:hidden;margin-top:3px;position:absolute;bottom:0px;z-index:1}#container>.scroll.hazard{background-color:#702323}#container>.scroll .scroll-container{width:640px}#container>.scroll .scroll-container .fixed,#container>.scroll .scroll-container .scroll-header{margin-left:55px;margin-right:55px;overflow:hidden;white-space:nowrap}#container>.scroll .scroll-container .scroll-header{height:26px;font-family:"Star4000 Small";font-size:20pt;margin-top:-10px}#container>.scroll .scroll-container .fixed{font-family:"Star4000";font-size:24pt}#container>.scroll .scroll-container .fixed .scroll-area{text-wrap:nowrap;position:relative}.wide #container>.scroll{width:854px;margin-left:-107px}.wide #container>.scroll .scroll-container{margin-left:107px}.weather-display .main.current-weather.main .col{height:50px;width:255px;display:inline-block;margin-top:10px;padding-top:10px;position:absolute;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.current-weather.main .col.left{font-family:"Star4000 Extended";font-size:24pt}.weather-display .main.current-weather.main .col.right{right:0px;font-family:"Star4000 Large";font-size:20px;font-weight:bold;line-height:24px}.weather-display .main.current-weather.main .col.right .row{margin-bottom:12px}.weather-display .main.current-weather.main .col.right .row .label,.weather-display .main.current-weather.main .col.right .row .value{display:inline-block}.weather-display .main.current-weather.main .col.right .row .label{margin-left:20px}.weather-display .main.current-weather.main .col.right .row .value{float:right;margin-right:10px}.weather-display .main.current-weather.main .center{text-align:center}.weather-display .main.current-weather.main .temp{font-family:"Star4000 Large";font-size:24pt}.weather-display .main.current-weather.main .icon img{margin:0 auto;display:block}.weather-display .main.current-weather.main .wind-container{margin-left:10px;display:flex}.weather-display .main.current-weather.main .wind-container>div{width:50%}.weather-display .main.current-weather.main .wind-container .wind{text-align:right}.weather-display .main.current-weather.main .wind-gusts{text-align:right;font-size:28px}.weather-display .main.current-weather.main .location{color:#ff0;max-height:32px;margin-bottom:10px;padding-top:4px;overflow:hidden;text-wrap:nowrap}#extended-forecast-html.weather-display{background-image:url("../images/backgrounds/2.png")}.weather-display .main.extended-forecast .day-container{margin-top:16px;margin-left:27px}.weather-display .main.extended-forecast .day{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding:5px;height:285px;width:155px;display:inline-block;margin:0px 15px;font-family:"Star4000";font-size:24pt}.weather-display .main.extended-forecast .day .date{text-transform:uppercase;text-align:center;color:#ff0}.weather-display .main.extended-forecast .day .condition{text-align:center;height:74px;margin-top:5px}.weather-display .main.extended-forecast .day .icon{text-align:center;height:75px}.weather-display .main.extended-forecast .day .icon img{max-height:75px}.weather-display .main.extended-forecast .day .temperatures{width:100%}.weather-display .main.extended-forecast .day .temperatures .temperature-block{display:inline-block;width:44%;vertical-align:top}.weather-display .main.extended-forecast .day .temperatures .temperature-block>div{text-align:center}.weather-display .main.extended-forecast .day .temperatures .temperature-block .value{font-family:"Star4000 Large";margin-top:4px}.weather-display .main.extended-forecast .day .temperatures .temperature-block.lo .label{color:#8080ff}.weather-display .main.extended-forecast .day .temperatures .temperature-block.hi .label{color:#ff0}.weather-display .main.hourly.main{overflow-y:hidden}.weather-display .main.hourly.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.hourly.main .column-headers .temp{left:355px}.weather-display .main.hourly.main .column-headers .like{left:435px}.weather-display .main.hourly.main .column-headers .wind{left:535px}.weather-display .main.hourly.main .hourly-lines{min-height:338px;padding-top:10px;background:repeating-linear-gradient(0deg, #001040 0px, #102080 136px, #102080 202px, #001040 338px)}.weather-display .main.hourly.main .hourly-lines .hourly-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.hourly.main .hourly-lines .hourly-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.hourly.main .hourly-lines .hourly-row .hour{left:25px}.weather-display .main.hourly.main .hourly-lines .hourly-row .icon{left:255px;width:70px;text-align:center;top:unset}.weather-display .main.hourly.main .hourly-lines .hourly-row .temp{left:355px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like{left:425px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.heat-index{color:#e00}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.wind-chill{color:#8080ff}.weather-display .main.hourly.main .hourly-lines .hourly-row .wind{left:505px;width:100px;text-align:right}#hourly-graph-html{background-image:url(../images/backgrounds/1-chart.png)}#hourly-graph-html .header .right{position:absolute;top:35px;right:60px;width:360px;font-family:"Star4000 Small";font-size:28px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:right}#hourly-graph-html .header .right div{margin-top:-18px}#hourly-graph-html .header .right .temperature{color:red}#hourly-graph-html .header .right .dewpoint{color:green}#hourly-graph-html .header .right .cloud{color:#d3d3d3}#hourly-graph-html .header .right .rain{color:aqua}.weather-display .main.hourly-graph.main>div{position:absolute}.weather-display .main.hourly-graph.main .label{font-family:"Star4000 Small";font-size:24pt;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-top:-15px;position:absolute}.weather-display .main.hourly-graph.main .x-axis{bottom:0px;left:54px;width:532px;height:20px}.weather-display .main.hourly-graph.main .x-axis .label{text-align:center;transform:translateX(-50%);white-space:nowrap}.weather-display .main.hourly-graph.main .x-axis .label.l-1{left:0px}.weather-display .main.hourly-graph.main .x-axis .label.l-2{left:133px}.weather-display .main.hourly-graph.main .x-axis .label.l-3{left:266px}.weather-display .main.hourly-graph.main .x-axis .label.l-4{left:399px}.weather-display .main.hourly-graph.main .x-axis .label.l-5{left:532px}.weather-display .main.hourly-graph.main .chart{top:0px;left:50px}.weather-display .main.hourly-graph.main .chart img{width:532px;height:285px}.weather-display .main.hourly-graph.main .y-axis{top:0px;left:0px;width:50px;height:285px}.weather-display .main.hourly-graph.main .y-axis .label{text-align:right;right:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-1{top:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-2{top:93.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-3{bottom:82.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-4{bottom:0px}.weather-display .main.hourly-graph.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly-graph.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly-graph.main .column-headers .temp{left:355px}.weather-display .main.hourly-graph.main .column-headers .like{left:435px}.weather-display .main.hourly-graph.main .column-headers .wind{left:535px}.weather-display .main.travel.main{overflow-y:hidden}.weather-display .main.travel.main .column-headers{background-color:#200057;height:20px;position:sticky;top:0px;width:100%;z-index:5;overflow:hidden}.weather-display .main.travel.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.travel.main .column-headers .temp{width:50px;text-align:center}.weather-display .main.travel.main .column-headers .temp.low{left:455px}.weather-display .main.travel.main .column-headers .temp.high{left:510px;width:60px}.weather-display .main.travel.main .travel-lines{min-height:338px;padding-top:10px;background:repeating-linear-gradient(0deg, #001040 0px, #102080 136px, #102080 202px, #001040 338px)}.weather-display .main.travel.main .travel-lines .travel-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.travel.main .travel-lines .travel-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.travel.main .travel-lines .travel-row .city{left:80px}.weather-display .main.travel.main .travel-lines .travel-row .icon{left:330px;width:70px;text-align:center;top:unset}.weather-display .main.travel.main .travel-lines .travel-row .icon img{max-width:47px}.weather-display .main.travel.main .travel-lines .travel-row .temp{width:50px;text-align:center}.weather-display .main.travel.main .travel-lines .travel-row .temp.low{left:455px}.weather-display .main.travel.main .travel-lines .travel-row .temp.high{left:510px;width:60px}.weather-display .latest-observations.main{overflow-y:hidden}.weather-display .latest-observations.main .column-headers{height:20px;position:absolute;width:100%}.weather-display .latest-observations.main .column-headers{top:0px}.weather-display .latest-observations.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;position:absolute;top:-14px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .latest-observations.main .column-headers .temp{display:none}.weather-display .latest-observations.main .column-headers .temp.show{display:inline-block}.weather-display .latest-observations.main .temp{left:230px}.weather-display .latest-observations.main .weather{left:280px}.weather-display .latest-observations.main .wind{left:430px}.weather-display .latest-observations.main .observation-lines{min-height:338px;padding-top:10px}.weather-display .latest-observations.main .observation-lines .observation-row{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;height:40px}.weather-display .latest-observations.main .observation-lines .observation-row>div{position:absolute;top:8px}.weather-display .latest-observations.main .observation-lines .observation-row .wind{white-space:pre;text-align:right}.weather-display .local-forecast .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:280px;overflow:hidden}.weather-display .local-forecast .forecasts{position:relative}.weather-display .local-forecast .forecast{font-family:"Star4000";font-size:24pt;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;min-height:280px;line-height:40px}.weather-display .progress{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000 Extended";font-size:18pt}.weather-display .progress .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:310px;overflow:hidden;line-height:26px}.weather-display .progress .container .item{position:relative}.weather-display .progress .container .item .name{white-space:nowrap}.weather-display .progress .container .item .name::after{content:"........................................................................"}.weather-display .progress .container .item .links{position:absolute;text-align:right;right:0px;top:0px}.weather-display .progress .container .item .links>div{background-color:#26235a;display:none;padding-left:4px}.weather-display .progress .container .item .links .loading,.weather-display .progress .container .item .links .retrying{color:#ff0}.weather-display .progress .container .item .links .press-here{color:lime;cursor:pointer}.weather-display .progress .container .item .links .failed{color:red}.weather-display .progress .container .item .links .no-data{color:silver}.weather-display .progress .container .item .links .disabled{color:silver}.weather-display .progress .container .item .links.loading .loading,.weather-display .progress .container .item .links.press-here .press-here,.weather-display .progress .container .item .links.failed .failed,.weather-display .progress .container .item .links.no-data .no-data,.weather-display .progress .container .item .links.disabled .disabled,.weather-display .progress .container .item .links.retrying .retrying{display:block}@keyframes progress-scroll{0%{background-position:-40px 0}100%{background-position:40px 0}}#progress-html.weather-display .scroll .progress-bar-container{border:2px solid #000;background-color:#fff;margin:20px auto;width:524px;position:relative;display:none}#progress-html.weather-display .scroll .progress-bar-container.show{display:block}#progress-html.weather-display .scroll .progress-bar-container .progress-bar{height:20px;margin:2px;width:520px;background:repeating-linear-gradient(90deg, #09246f 0px, #09246f 5px, #364ac0 5px, #364ac0 10px, #4f99f9 10px, #4f99f9 15px, #8ffdfa 15px, #8ffdfa 20px, #4f99f9 20px, #4f99f9 25px, #364ac0 25px, #364ac0 30px, #09246f 30px, #09246f 40px);animation-duration:2s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:progress-scroll;animation-timing-function:steps(8, end)}#progress-html.weather-display .scroll .progress-bar-container .cover{position:absolute;top:0px;right:0px;background-color:#fff;width:100%;height:24px;transition:width 1s steps(6)}#radar-html.weather-display{background-image:url("../images/backgrounds/4.png")}#radar-html.weather-display .header{height:83px}#radar-html.weather-display .header .title.dual{color:#fff;font-family:"Arial",sans-serif;font-weight:bold;font-size:28pt;left:155px}#radar-html.weather-display .header .title.dual .top{top:-4px}#radar-html.weather-display .header .title.dual .bottom{top:31px}#radar-html.weather-display .header .right{position:absolute;right:0px;width:360px;margin-top:2px;font-family:"Star4000";font-size:18pt;font-weight:bold;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:center}#radar-html.weather-display .header .right .scale>div{display:inline-block}#radar-html.weather-display .header .right .scale-table{display:table-row;border-collapse:collapse}#radar-html.weather-display .header .right .scale-table .box{display:table-cell;border:2px solid #000;width:17px;height:24px;padding:0}#radar-html.weather-display .header .right .scale-table .box-1{background-color:#31d216}#radar-html.weather-display .header .right .scale-table .box-2{background-color:#1c8a12}#radar-html.weather-display .header .right .scale-table .box-3{background-color:#145a0f}#radar-html.weather-display .header .right .scale-table .box-4{background-color:#0a280a}#radar-html.weather-display .header .right .scale-table .box-5{background-color:#c4b346}#radar-html.weather-display .header .right .scale-table .box-6{background-color:#be4813}#radar-html.weather-display .header .right .scale-table .box-7{background-color:#ab0e0e}#radar-html.weather-display .header .right .scale-table .box-8{background-color:#731f04}#radar-html.weather-display .header .right .scale .text{position:relative;top:-5px}#radar-html.weather-display .header .right .time{position:relative;font-weight:normal;top:-14px;font-family:"Star4000 Small";font-size:24pt}.weather-display .main.radar{overflow:hidden;height:367px}.weather-display .main.radar .container .tiles{position:absolute;width:1400px}.weather-display .main.radar .container .tiles img{vertical-align:middle}.weather-display .main.radar .container .scroll-area{position:relative}.wide.radar #container{background:url(../images/backgrounds/4-wide.png)}#regional-forecast-html.weather-display{background-image:url("../images/backgrounds/5.png")}.weather-display .main.regional-forecast{position:relative}.weather-display .main.regional-forecast .map{position:absolute;transform-origin:0 0}.weather-display .main.regional-forecast .location{position:absolute;width:140px;margin-left:-40px;margin-top:-35px}.weather-display .main.regional-forecast .location>div{position:absolute;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.regional-forecast .location .icon{top:26px;left:44px}.weather-display .main.regional-forecast .location .icon img{max-height:32px}.weather-display .main.regional-forecast .location .temp{font-family:"Star4000 Large";font-size:28px;padding-top:2px;color:#ff0;top:28px;text-align:right;width:40px}.weather-display .main.regional-forecast .location .city{font-family:Star4000;font-size:20px}#almanac-html.weather-display{background-image:url("../images/backgrounds/3.png")}.weather-display .main.almanac{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.almanac .sun{display:grid;grid-template-columns:auto auto auto;grid-template-rows:auto auto auto;gap:0px 90px;margin:3px auto 5px auto;width:fit-content;line-height:30px}.weather-display .main.almanac .sun .grid-item{width:auto;height:auto;padding:0;margin:0;position:relative}.weather-display .main.almanac .sun .grid-item.header{color:#ff0;text-align:center}.weather-display .main.almanac .sun .grid-item.row-label{text-align:right}.weather-display .main.almanac .sun .grid-item.time{text-align:center}.weather-display .main.almanac .moon{position:relative;padding:7px 50px;line-height:36px}.weather-display .main.almanac .moon .title{color:#ff0;padding-left:13px}.weather-display .main.almanac .moon .day{display:inline-block;text-align:center;width:132px}.weather-display .main.almanac .moon .day .icon{padding-left:10px}.weather-display .main.almanac .moon .day .date{position:relative;top:-10px}#hazards-html.weather-display{background-image:url("../images/backgrounds/7.png")}.weather-display .main.hazards.main{overflow-y:hidden;height:480px;background-color:#702323}.weather-display .main.hazards.main .hazard-lines{min-height:400px;padding-top:10px}.weather-display .main.hazards.main .hazard-lines .hazard{font-family:"Star4000";font-size:24pt;color:#fff;text-shadow:0px 0px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;text-transform:uppercase;margin-top:10px;margin-left:80px;margin-right:80px;padding-bottom:10px}.wide.hazards #container{background:url(../images/backgrounds/7-wide.png)}.media{display:none}#ToggleMediaContainer{display:none;position:relative}#ToggleMediaContainer.available{display:inline-block}#ToggleMediaContainer.available img.on{display:none}#ToggleMediaContainer.available img.off{display:block}#ToggleMediaContainer.available.playing img.on{display:block}#ToggleMediaContainer.available.playing img.off{display:none}#ToggleMediaContainer .volume-slider{display:none;position:absolute;top:0px;transform:translateY(-100%);width:100%;background-color:#000;text-align:center;z-index:100}@media(prefers-color-scheme: dark){#ToggleMediaContainer .volume-slider{background-color:#303030}}#ToggleMediaContainer .volume-slider input[type=range]{writing-mode:vertical-lr;direction:rtl;margin-top:20px;margin-bottom:20px}#ToggleMediaContainer .volume-slider.show{display:block}#spc-outlook-html.weather-display{background-image:url("../images/backgrounds/6.png")}.weather-display .spc-outlook .container{position:relative;top:0px;margin:0px 10px;box-sizing:border-box;height:300px;overflow:hidden}.weather-display .spc-outlook .risk-levels{position:absolute;left:206px;font-family:"Star4000 Small";font-size:32px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .spc-outlook .risk-levels .risk-level{position:relative;top:-14px;height:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(1){left:100px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(2){left:80px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(3){left:60px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(4){left:40px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(5){left:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(6){left:0px}.weather-display .spc-outlook .days{position:absolute;top:120px}.weather-display .spc-outlook .days .day{height:60px}.weather-display .spc-outlook .days .day .day-name{position:absolute;font-family:"Star4000";font-size:24pt;width:200px;text-align:right;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding-top:20px}.weather-display .spc-outlook .days .day .risk-bar{position:absolute;width:150px;height:40px;left:210px;margin-top:20px;border:3px outset hsl(0,0%,70%);background:linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%)}#server-observations-html.weather-display .header .title.single{font-size:20pt}.weather-display .server-observations.main{height:auto !important;min-height:250px}.weather-display .server-observations .container{position:relative;top:15px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .server-observations .server-output{position:relative;font-family:"Star4000";font-size:20pt;line-height:32px;color:#fff;text-transform:uppercase;text-align:center;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .server-observations .server-output .server-page{height:250px;padding:0 8px;box-sizing:border-box}.weather-display .server-observations .server-output .server-line{white-space:normal;overflow-wrap:anywhere;word-break:break-word;margin-bottom:6px}.weather-display .linux-news.main{height:auto !important;min-height:250px}.weather-display .linux-news .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .linux-news .news-output{position:relative}.weather-display .linux-news .news-output .news-page{height:250px;box-sizing:border-box;padding:0 8px;display:flex;flex-direction:column;justify-content:space-between}.weather-display .linux-news .news-output .story{height:116px;overflow:hidden}.weather-display .linux-news .news-output .headline{font-family:"Star4000";font-size:17pt;line-height:22px;color:#ff0;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-bottom:4px}.weather-display .linux-news .news-output .blurb{font-family:"Star4000";font-size:14pt;line-height:16px;color:#fff;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;overflow:hidden}.scanlines{position:relative;overflow:hidden;isolation:isolate}.scanlines #container{position:relative;z-index:1;transform:translateZ(0);will-change:filter;filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98)}.scanlines #container::before,.scanlines #container::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3}.scanlines #container::before{background:linear-gradient(to right, rgba(255, 0, 0, 0.04) 0%, rgba(255, 0, 0, 0.01) 15%, rgba(255, 0, 0, 0) 50%, rgba(255, 0, 0, 0.01) 85%, rgba(255, 0, 0, 0.04) 100%);transform:translateX(-0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines #container::after{background:linear-gradient(to right, rgba(0, 140, 255, 0.04) 0%, rgba(0, 140, 255, 0.01) 15%, rgba(0, 140, 255, 0) 50%, rgba(0, 140, 255, 0.01) 85%, rgba(0, 140, 255, 0.04) 100%);transform:translateX(0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines:before,.scanlines:after{display:block;pointer-events:none;content:"";position:absolute;left:0;right:0}.scanlines:before{height:var(--scanline-thickness, 1px);z-index:2147483650;background:rgba(0,0,0,.3);opacity:.75;animation:scanline 6s linear infinite}.scanlines:after{top:0;bottom:0;z-index:2147483648;background:repeating-linear-gradient(to bottom, transparent 0, transparent var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) calc(var(--scanline-thickness, 1px) * 2));animation:none}.scanlines{box-shadow:inset 0 0 80px rgba(0,0,0,.16),inset 0 0 18px hsla(0,0%,100%,.05)}.scanlines.crt-panels-only #container{filter:none}.scanlines.crt-panels-only .weather-display{filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98);transform:translateZ(0)}.scanlines .header,.scanlines .main,.scanlines .scroll,.scanlines .date-time,.scanlines .city,.scanlines .temp,.scanlines .condition,.scanlines .location,.scanlines .label,.scanlines .value,.scanlines .title{text-shadow:0 0 1px hsla(0,0%,100%,.18),0 0 2px hsla(0,0%,100%,.06)}@keyframes scanline{0%{transform:translate3d(0, 200000%, 0)}}@keyframes scanlines{0%{background-position:0 50%}} /*# sourceMappingURL=ws.min.css.map */ diff --git a/server/styles/ws.min.css.map b/server/styles/ws.min.css.map index 995ef3b..7a3a49f 100644 --- a/server/styles/ws.min.css.map +++ b/server/styles/ws.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_page.scss","shared/_utils.scss","_weather-display.scss","shared/_colors.scss","_current-weather.scss","_extended-forecast.scss","_hourly.scss","_hourly-graph.scss","_travel.scss","_latest-observations.scss","_local-forecast.scss","_progress.scss","_radar.scss","_regional-forecast.scss","_almanac.scss","_hazards.scss","_media.scss","_spc-outlook.scss","_server-observations.scss","shared/_scanlines.scss"],"names":[],"mappings":"AAGA,WACC,uBACA,iDACA,kBAGD,KACC,uBACA,SAEA,mCAJD,KAKE,sBACA,YAIA,mCADD,OAEE,eAIF,WACC,WACA,YACA,gBACA,YAEA,iCAIF,UACC,gBACA,YAEA,mBACC,qBACA,YACA,iBAEA,8BACC,YACA,sBAGD,0BACC,eACA,yBAEA,mCAJD,0BAKE,sBACA,YAQA,uCACC,aAEA,mCAHD,uCAIE,sBAKD,mCADD,wCAEE,cAKH,qCACC,sBAEA,mCAHD,qCAIE,uBAGD,yCACC,iBAMJ,iCAEC,uBAGD,uBACC,yBACA,gBACA,eACA,gBACA,qBAGA,sBACA,WACA,sBAEA,mCAZD,uBAaE,sBACA,WACA,uBAOH,0BACC,sBACA,sBACA,kBACA,aAEA,mCAND,0BAOE,uBAGD,8BAEC,mBACA,gBACA,uBACA,eAEA,uCACC,sBACA,WAMH,QACC,cACA,sBACA,WACA,WACA,gBACA,SAEA,aACC,gBAIF,iBACC,YAGD,YACC,YACA,aACA,kBAEA,kBACC,YAIF,eACC,gBAGD,YACC,aACA,iBACA,sBACA,sBAGD,gBACC,OACA,mBACA,aACA,sBACA,uBAGD,aACC,gBACA,aACA,sBACA,sBAGD,iBACC,OACA,kBACA,aACA,sBACA,uBAGD,cAEC,aACA,mBACA,sBAEA,WACA,YAEA,oBACC,YAGD,mCAbD,cAcE,0BAKF,kBACC,iBACA,kBAIA,yBAND,kBAOE,gBAGD,yBAVD,kBAWE,gBAGD,yBAdD,kBAeE,gBAGD,yBAlBD,kBAmBE,gBAGD,yBAtBD,kBAuBE,gBAIF,kBACC,OACA,gBAID,oBACC,OACA,kBAGD,mBACC,OACA,iBAGD,oBACC,aAGD,WACC,WACA,aACA,mBACA,sBACA,WACA,gBAGD,eACC,iBACA,kBAGD,eACC,OACA,gBAGD,iBACC,OACA,kBAGD,gBACC,OACA,iBAGD,YACC,kBACA,kBAGD,YACC,uBAGD,eACC,YAGD,WACC,gCACA,0DACA,kBAGD,WACC,6BACA,uDACA,kBAGD,WACC,6BACA,uDACA,kBAGD,SACC,uBACA,eACA,WAGD,WACC,kBACA,YACA,aAEA,kDACA,qBACA,4BAGD,iBACC,mBACA,oBACA,iDACA,4BAGD,wDAGC,YACA,aAGD,SACC,YACA,aACA,eACA,yBACA,aACA,mBACA,kBACA,uBAEA,gBACC,2BACA,eACA,WACA,kBAGD,kBACC,mBAGD,uBACC,eAIF,SACC,iBACA,gBAGD,UACC,mBAGD,2BAEC,mBCzXA,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,UAGD,6CACC,aAGD,+CACC,aDyWD,mDACC,WAGD,oCAEC,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,WAGD,6CACC,oBAGD,+CACC,qBAIF,uCACC,cACA,sBACA,eAEA,qDACC,aAEA,+DACC,eACA,UAMJ,kBACC,sBAGA,yBACC,wBACC,oBAKH,kCAEC,aACA,mBACA,uBACA,qBAEA,sDACC,YAIF,oDAEC,kBAGD,8DAEC,aACA,mBACA,gCACA,WACA,WACA,kBACA,WAIA,6BACC,aAIF,WACC,eAGD,iBACC,qBAEA,qBACC,aAGD,sBACC,qBAKA,wBACC,qBAGD,yBACC,aAMH,SACC,mBACA,UACA,8BAGD,2BACC,kBACA,UACA,8CAGD,cACC,YACA,6BACA,aACA,6BACA,eAGC,qBACC,qBACA,UAGD,2BACC,qBACA,gBACA,iFACA,YACA,cACA,mBAGD,yDAEC,kBACA,qBACA,oBACA,YACA,gBACA,eACA,gBACA,iBACA,sBACA,eACA,yBACA,sBACA,qBACA,iBACA,2BACA,8BACA,0BACA,iBAGD,wBACC,oBAGD,yCACC,8BAGD,iCACC,cACA,8BAGD,+EAEC,YACA,iBACA,eACA,iBAGD,4BACC,qBACA,wBACA,kBACA,iBAGD,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,cAGD,oCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,eAIF,mCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,kCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,8CACA,sBACA,YAGD,iCACC,cACA,yBACA,qBACA,kCAGD,8EAEC,cAGD,kCACC,eAMJ,mBACC,WACA,aAGD,yBACC,aAID,kCACC,wBAMA,sBACC,wBAIF,SACC,aACA,8BACA,gBEnzBD,iBACC,YACA,aACA,gBACA,kBACA,kDAGA,WAEA,sBACC,aAGD,2BACC,aAGD,yBACC,YACA,YACA,iBAEA,gCACC,MC3BW,KFMb,YACC,6JCsBC,uBACA,eACA,kBACA,YAEA,uCACC,WACA,SAGD,qCACC,WAEA,yCACC,kBAGD,0CACC,SAGD,6CACC,SAMH,+BACC,SACA,UACA,kBACA,WAGD,oCACC,kBACA,SACA,WAGD,uCACC,SAGD,oCACC,gBACA,MC3ES,KD4ET,6BACA,eDxEF,YACC,6JCyEC,WACA,YACA,iBACA,kBAEA,yCACC,iBAKH,uBACC,kBAEA,kCACC,YACA,aACA,aACA,gBAEA,4CACC,aACA,aAIF,+BACC,iBACA,kBACA,yBAOH,mBACC,aD/GA,YACC,6JCgHD,YACA,YACA,gBACA,eACA,kBACA,WACA,UAEA,0BACC,yBAGD,qCACC,YAEA,gGAEC,iBACA,kBACA,gBACA,mBAGD,oDACC,YACA,6BACA,eACA,iBAGD,4CACC,uBACA,eAEA,yDACC,iBACA,kBAYJ,yBACC,YACA,mBAEA,2CACC,kBEtKA,iDACC,YACA,YACA,qBACA,gBACA,iBACA,kBHNF,YACC,6JGSC,sDACC,gCACA,eAID,uDACC,UACA,6BACA,eACA,iBACA,iBAEA,4DACC,mBAEA,sIAEC,qBAGD,mEACC,iBAGD,mEACC,YACA,kBAQJ,oDACC,kBAGD,kDACC,6BACA,eAIA,sDACC,cACA,cAIF,4DACC,iBACA,aAEA,gEACC,UAGD,kEACC,iBAIF,wDACC,iBACA,eAGD,sDACC,MDtFW,KCuFX,gBACA,mBACA,gBACA,gBACA,iBCxFH,wCACC,oDAIA,wDACC,gBACA,iBAGD,8CJPA,YACC,6JIQA,YACA,aACA,YACA,qBACA,gBACA,uBACA,eAEA,oDACC,yBACA,kBACA,MF1BW,KE6BZ,yDACC,kBACA,YACA,eAGD,oDACC,kBACA,YAEA,wDACC,gBAIF,4DACC,WAEA,+EACC,qBACA,UACA,mBAEA,mFACC,kBAGD,sFACC,6BACA,eAGD,yFACC,MFhDU,QEmDX,yFACC,MFlES,KGIb,mCACC,kBAEA,mDACC,iBHJa,QGKb,YACA,kBACA,WAGD,mDACC,gBACA,QACA,UAEA,uDACC,qBACA,6BACA,eACA,MHpBiB,KGqBjB,kBACA,UACA,ULpBH,YACC,6JKuBC,yDACC,WAGD,yDACC,WAGD,yDACC,WAIF,iDACC,iBACA,iBAEA,qGAMA,6DACC,6BACA,eACA,YACA,MHzDU,KFMb,YACC,6JKoDE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAGD,mEACC,WAGD,mEACC,WAEA,8EACC,WAGD,8EACC,MH5ES,QGgFX,mEACC,WACA,YACA,iBC9FL,mBACC,wDAGC,kCACC,kBACA,SACA,WACA,YACA,6BACA,eNPF,YACC,6JMQC,iBAEA,sCACC,iBAGD,+CACC,UAGD,4CACC,YAGD,yCACC,cAGD,wCACC,WASF,6CACC,kBAGD,gDACC,6BACA,eACA,MJ/CkB,KFGpB,YACC,6JM6CC,iBACA,kBAGD,iDACC,WACA,UACA,YACA,YAEA,wDACC,kBACA,2BACA,mBAEA,4DACC,SAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAQH,gDACC,QACA,UAEA,oDACC,YACA,aAIF,iDACC,QACA,SACA,WACA,aAEA,wDACC,iBACA,UAEA,4DACC,QAGD,4DACC,oBAGD,4DACC,uBAGD,4DACC,WAKH,yDACC,iBJ/Ha,QIgIb,YACA,kBACA,WAGD,yDACC,gBACA,QACA,UAGA,+DACC,WAGD,+DACC,WAGD,+DACC,WCpJH,mCACC,kBAEA,mDACC,iBLJa,QKKb,YACA,gBACA,QACA,WACA,UACA,gBAEA,uDACC,qBACA,6BACA,eACA,MLjBiB,KKkBjB,kBACA,UACA,UPjBH,YACC,6JOoBC,yDACC,WACA,kBAEA,6DACC,WAID,8DACC,WACA,WAKH,iDACC,iBACA,iBAEA,qGAMA,6DACC,6BACA,eACA,YACA,MLzDU,KFMb,YACC,6JOoDE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAEA,uEACC,eAIF,mEACC,WACA,kBAEA,uEACC,WAGD,wEACC,WACA,WCvFL,2CACC,kBAEA,2DACC,YACA,kBACA,WAGD,2DACC,QAEA,+DACC,qBACA,6BACA,eACA,kBACA,URhBH,YACC,6JQmBC,iEAEC,aAEA,sEACC,qBAKH,iDACC,WAGD,oDACC,WAGD,iDACC,WAGD,8DACC,iBACA,iBAEA,+EACC,uBACA,eRhDH,YACC,6JQiDE,kBACA,YAEA,mFACC,kBACA,QAGD,qFACC,gBACA,iBC9DJ,4CACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,4CACC,kBAGD,2CACC,uBACA,eACA,yBTdD,YACC,6JSeA,iBACA,iBCpBF,2BVGC,YACC,6JUFD,gCACA,eAEA,sCACC,kBACA,SACA,gBACA,sBACA,aACA,gBACA,iBAEA,4CACC,kBAEA,kDACC,mBAEA,yDACC,mFAIF,mDACC,kBACA,iBACA,UACA,QAEA,uDACC,iBRnBM,QQoBN,aACA,iBVjBJ,yHAEC,WAGD,+DACC,WACA,eAGD,2DACC,UAGD,4DACC,aAGD,6DACC,aUGE,gaAMC,cAYJ,2BACC,GACC,4BAGD,KACC,4BAIF,+DACC,sBACA,sBACA,iBACA,YACA,kBACA,aAEA,oEACC,cAGD,6EACC,YACA,WACA,YACA,6OAiBA,sBACA,6BACA,mCACA,+BACA,wCAGD,sEACC,kBACA,QACA,UACA,sBACA,WACA,YACA,6BClHH,4BACC,oDAEA,oCACC,YAEA,gDACC,WACA,+BACA,iBACA,eACA,WAEA,qDACC,SAGD,wDACC,SAIF,2CACC,kBACA,UACA,YACA,eACA,uBACA,eACA,iBX1BF,YACC,6JW2BC,kBAEA,sDACC,qBAGD,wDACC,kBACA,yBAEA,6DACC,mBACA,sBACA,WACA,YACA,UAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAKD,wDACC,kBACA,SAIF,iDACC,kBACA,mBACA,UACA,6BACA,eAMJ,6BACC,gBACA,aAIC,+CACC,kBACA,aAEA,mDACC,sBAIF,qDACC,kBAKH,uBACC,iDC1HD,wCACC,oDAGD,yCAGC,kBAEA,8CACC,kBACA,qBAGD,mDACC,kBACA,YACA,kBACA,iBAEA,uDACC,kBZlBF,YACC,6JYqBA,yDACC,SACA,UAEA,6DACC,gBAIF,yDACC,6BACA,eACA,gBACA,MVzCW,KU0CX,SACA,iBACA,WAGD,yDACC,qBACA,eC9CH,8BACC,oDAGD,+BACC,uBACA,ebHA,YACC,6JaKD,oCAGC,aACA,qCACA,kCACA,aACA,yBACA,kBACA,iBAEA,+CAEC,WACA,YACA,UACA,SACA,kBAGA,sDACC,MX9BiB,KW+BjB,kBAID,yDAEC,iBAID,oDACC,kBAKH,qCACC,kBACA,iBACA,iBAEA,4CACC,MXrDkB,KWsDlB,kBAGD,0CACC,qBACA,kBACA,YAEA,gDAEC,kBAGD,gDACC,kBACA,UCrEJ,8BACC,oDAIA,oCACC,kBACA,aACA,yBAGA,kDACC,iBACA,iBAEA,0DACC,uBACA,eACA,WdfH,YACC,6JcgBE,kBACA,yBACA,gBACA,iBACA,kBACA,oBAMJ,yBACC,iDCnCD,OACC,aAGD,sBACC,aACA,kBAEA,gCACC,qBAEA,uCACC,aAGD,wCACC,cAKA,+CACC,cAGD,gDACC,aAQH,qCACC,aACA,kBACA,QACA,4BACA,WACA,sBACA,kBACA,YAEA,mCAVD,qCAWE,0BAGD,uDACC,yBACA,cACA,gBACA,mBAGD,0CACC,cCrDH,kCACC,oDAKA,yCACC,kBACA,QACA,gBACA,sBACA,aACA,gBAGD,2CACC,kBACA,WACA,6BACA,ehBhBD,YACC,6JgBmBA,uDACC,kBACA,UACA,YAEA,oEACC,WAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,SAKH,oCACC,kBACA,UAEA,yCACC,YAEA,mDACC,kBACA,uBACA,eACA,YACA,iBhB/DH,YACC,6JgBgEE,iBAGD,mDACC,kBACA,YACA,YACA,WACA,gBACA,gCACA,gGC7EH,gEACC,eAMD,2CACC,uBACA,iBAGD,iDACC,kBACA,SACA,sBACA,aACA,gBAGD,qDACC,kBACA,uBACA,eACA,iBACA,WACA,yBACA,kBjBzBD,YACC,6JiB2BA,kEACC,aACA,cACA,sBAGD,kEACC,mBACA,uBACA,sBACA,kBCuBH,WACE,kBACA,gBACA,kBAMA,sBACE,kBACA,UACA,wBACA,mBAEA,OACE,4DASJ,2DAEE,WACA,kBACA,QACA,oBACA,UAGF,8BACE,WACE,8JAQF,6BACA,mBACA,sBAMF,6BACE,WACE,wKAQF,4BACA,mBACA,sBAMF,mCAEE,cACA,oBACA,WACA,kBACA,OACA,QAGF,kBACE,sCACA,mBACA,WA/IS,eAgJT,QA5IW,IAwCX,sCA2GF,iBACE,MACA,SACA,QAzJW,WA0JX,2NArHA,eAsBJ,WA6GE,WACE,kEAaF,sCACE,YAGF,4CACE,OACE,4DAKF,wBASF,gNAWE,YACE,wDASN,oBACE,GACE,sCAIJ,qBACE,GACE","sourcesContent":["@use 'shared/_utils'as u;\n@use 'shared/_colors'as c;\n\n@font-face {\n\tfont-family: \"Star4000\";\n\tsrc: url('../fonts/Star4000.woff') format('woff');\n\tfont-display: swap;\n}\n\nbody {\n\tfont-family: \"Star4000\";\n\tmargin: 0;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t\tcolor: white;\n\t}\n\n\ta {\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tcolor: lightblue;\n\t\t}\n\t}\n\n\t&.kiosk {\n\t\tmargin: 0px;\n\t\tpadding: 0px;\n\t\toverflow: hidden;\n\t\twidth: 100vw;\n\t\t// Always use black background in kiosk mode, regardless of light/dark preference\n\t\tbackground-color: #000000 !important;\n\t}\n}\n\n#divQuery {\n\tmax-width: 640px;\n\tpadding: 8px;\n\n\t.buttons {\n\t\tdisplay: inline-block;\n\t\twidth: 150px;\n\t\ttext-align: right;\n\n\t\t#imgGetGps {\n\t\t\theight: 13px;\n\t\t\tvertical-align: middle;\n\t\t}\n\n\t\tbutton {\n\t\t\tfont-size: 16pt;\n\t\t\tborder: 1px solid darkgray;\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbackground-color: #000000;\n\t\t\t\tcolor: white;\n\t\t\t}\n\n\t\t}\n\n\t\t#btnGetGps {\n\t\t\timg {\n\n\t\t\t\t&.dark {\n\t\t\t\t\tdisplay: none;\n\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t&.light {\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t&.active {\n\t\t\t\tbackground-color: black;\n\n\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\tbackground-color: white;\n\t\t\t\t}\n\n\t\t\t\timg {\n\t\t\t\t\tfilter: invert(1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinput,\n\tbutton {\n\t\tfont-family: \"Star4000\";\n\t}\n\n\t#txtLocation {\n\t\twidth: calc(100% - 170px);\n\t\tmax-width: 490px;\n\t\tfont-size: 16pt;\n\t\tmin-width: 200px;\n\t\tdisplay: inline-block;\n\n\t\t// Ensure consistent styling across light and dark modes\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t\tborder: 2px inset #808080;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #000000;\n\t\t\tcolor: white;\n\t\t\tborder: 2px inset #808080;\n\t\t}\n\t}\n\n\n}\n\n.autocomplete-suggestions {\n\tbackground-color: #ffffff;\n\tborder: 1px solid #000000;\n\tposition: absolute;\n\tz-index: 9999;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t}\n\n\tdiv {\n\t\t/*padding: 2px 5px;*/\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\tfont-size: 16pt;\n\n\t\t&.selected {\n\t\t\tbackground-color: #0000ff;\n\t\t\tcolor: #ffffff;\n\t\t}\n\t}\n\n}\n\n#divTwc {\n\tdisplay: block;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\twidth: 100%;\n\tmax-width: 640px;\n\tmargin: 0; // Ensure edge-to-edge display\n\n\t&.wide {\n\t\tmax-width: 854px;\n\t}\n}\n\n.content-wrapper {\n\tpadding: 8px;\n}\n\n#divTwcMain {\n\twidth: 640px;\n\theight: 480px;\n\tposition: relative;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n}\n\n.kiosk #divTwc {\n\tmax-width: unset;\n}\n\n#divTwcLeft {\n\tdisplay: none;\n\ttext-align: right;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcLeft>div {\n\tflex: 1;\n\tpadding-right: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcRight {\n\ttext-align: left;\n\tdisplay: none;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcRight>div {\n\tflex: 1;\n\tpadding-left: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcBottom {\n\t/* visibility: hidden; */\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\n\tcolor: #ffffff;\n\twidth: 640px;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: rgb(48, 48, 48);\n\t}\n\n}\n\n#divTwcBottom>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\n\t// Use font-size scaling instead of zoom/transform to avoid layout gaps and preserve icon tap targets.\n\t// While not semantically ideal, it works well for our fixed-layout design.\n\t@media (max-width: 550px) {\n\t\tfont-size: 0.90em;\n\t}\n\n\t@media (max-width: 500px) {\n\t\tfont-size: 0.80em;\n\t}\n\n\t@media (max-width: 450px) {\n\t\tfont-size: 0.70em;\n\t}\n\n\t@media (max-width: 400px) {\n\t\tfont-size: 0.60em;\n\t}\n\n\t@media (max-width: 350px) {\n\t\tfont-size: 0.50em;\n\t}\n}\n\n#divTwcBottomLeft {\n\tflex: 1;\n\ttext-align: left;\n\n}\n\n#divTwcBottomMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcBottomRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#divTwcNavContainer {\n\tdisplay: none;\n}\n\n#divTwcNav {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\tmax-width: 640px;\n}\n\n#divTwcNav>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n}\n\n#divTwcNavLeft {\n\tflex: 1;\n\ttext-align: left;\n}\n\n#divTwcNavMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcNavRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#imgPause1x {\n\tvisibility: hidden;\n\tposition: absolute;\n}\n\n.HideCursor {\n\tcursor: none !important;\n}\n\n#txtScrollText {\n\twidth: 475px;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Extended';\n\tsrc: url('../fonts/Star4000 Extended.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Large';\n\tsrc: url('../fonts/Star4000 Large.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Small';\n\tsrc: url('../fonts/Star4000 Small.woff') format('woff');\n\tfont-display: swap;\n}\n\n#display {\n\tfont-family: \"Star4000\";\n\tmargin: 0 0 0 0;\n\twidth: 100%;\n}\n\n#container {\n\tposition: relative;\n\twidth: 640px;\n\theight: 480px;\n\t// overflow: hidden;\n\tbackground-image: url(../images/backgrounds/1.png);\n\ttransform-origin: 0 0;\n\tbackground-repeat: no-repeat;\n}\n\n.wide #container {\n\tpadding-left: 107px;\n\tpadding-right: 107px;\n\tbackground: url(../images/backgrounds/1-wide.png);\n\tbackground-repeat: no-repeat;\n}\n\n#divTwc:fullscreen #container,\n.kiosk #divTwc #container {\n\t// background-image: none;\n\twidth: unset;\n\theight: unset;\n}\n\n#loading {\n\twidth: 640px;\n\theight: 480px;\n\tmax-width: 100%;\n\ttext-shadow: 4px 4px black;\n\tdisplay: flex;\n\talign-items: center;\n\ttext-align: center;\n\tjustify-content: center;\n\n\t.title {\n\t\tfont-family: Star4000 Large;\n\t\tfont-size: 36px;\n\t\tcolor: yellow;\n\t\tmargin-bottom: 0px;\n\t}\n\n\t.version {\n\t\tmargin-bottom: 35px;\n\t}\n\n\t.instructions {\n\t\tfont-size: 18pt;\n\t}\n}\n\n.heading {\n\tfont-weight: bold;\n\tmargin-top: 15px;\n}\n\n#settings {\n\tmargin-bottom: 15px;\n}\n\n#enabledDisplays,\n#settings {\n\tmargin-bottom: 15px;\n\t@include u.status-colors();\n\n\t.press-here {\n\t\tcolor: white;\n\t}\n\n\t@media (prefers-color-scheme: light) {\n\n\t\t.loading,\n\t\t.retrying {\n\t\t\tcolor: hsl(60, 100%, 30%);\n\t\t}\n\n\t\t.press-here {\n\t\t\tcolor: black;\n\t\t\tcursor: pointer;\n\t\t}\n\n\t\t.failed {\n\t\t\tcolor: hsl(0, 100%, 30%);\n\t\t}\n\n\t\t.no-data {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\n\t\t.disabled {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\t}\n\n\tlabel {\n\t\tdisplay: block;\n\t\tmax-width: fit-content;\n\t\tcursor: pointer;\n\n\t\t.alert {\n\t\t\tdisplay: none;\n\n\t\t\t&.show {\n\t\t\t\tdisplay: inline;\n\t\t\t\tcolor: red;\n\t\t\t}\n\t\t}\n\t}\n}\n\n#divTwcBottom img {\n\ttransform: scale(0.75);\n\n\t// Make icons larger in widescreen mode on mobile\n\t@media (max-width: 550px) {\n\t\t.wide & {\n\t\t\ttransform: scale(1.0); // Larger icons in widescreen\n\t\t}\n\t}\n}\n\n#divTwc:fullscreen,\n.kiosk #divTwc {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\talign-content: center;\n\n\t&.no-cursor {\n\t\tcursor: none;\n\t}\n}\n\n#divTwc:fullscreen #display,\n.kiosk #divTwc #display {\n\tposition: relative;\n}\n\n#divTwc:fullscreen #divTwcBottom,\n.kiosk #divTwc #divTwcBottom {\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: rgb(0 0 0 / 0.5);\n\tcolor: #ffffff;\n\twidth: 100%;\n\tposition: absolute;\n\tbottom: 0px;\n}\n\n.kiosk {\n\t#divTwc #divTwcBottom {\n\t\tdisplay: none;\n\t}\n}\n\n.navButton {\n\tcursor: pointer;\n}\n\n#ToggleScanlines {\n\tdisplay: inline-block;\n\n\t.on {\n\t\tdisplay: none;\n\t}\n\n\t.off {\n\t\tdisplay: inline-block;\n\t}\n\n\n\t&.on {\n\t\t.on {\n\t\t\tdisplay: inline-block;\n\t\t}\n\n\t\t.off {\n\t\t\tdisplay: none;\n\t\t}\n\n\t}\n}\n\n.visible {\n\tvisibility: visible;\n\topacity: 1;\n\ttransition: opacity 0.1s linear;\n}\n\n#divTwc:fullscreen .hidden {\n\tvisibility: hidden;\n\topacity: 0;\n\ttransition: visibility 0s 1s, opacity 1s linear\n}\n\n.github-links {\n\twidth: 610px;\n\tmax-width: calc(100vw - 30px);\n\tdisplay: flex;\n\tjustify-content: space-evenly;\n\tflex-wrap: wrap;\n\n\tspan {\n\t\ta {\n\t\t\ttext-decoration: none;\n\t\t\toutline: 0\n\t\t}\n\n\t\t.widget {\n\t\t\tdisplay: inline-block;\n\t\t\toverflow: hidden;\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;\n\t\t\tfont-size: 0;\n\t\t\tline-height: 0;\n\t\t\twhite-space: nowrap\n\t\t}\n\n\t\t.btn,\n\t\t.social-count {\n\t\t\tposition: relative;\n\t\t\tdisplay: inline-block;\n\t\t\tdisplay: inline-flex;\n\t\t\theight: 14px;\n\t\t\tpadding: 2px 5px;\n\t\t\tfont-size: 11px;\n\t\t\tfont-weight: 600;\n\t\t\tline-height: 14px;\n\t\t\tvertical-align: bottom;\n\t\t\tcursor: pointer;\n\t\t\t-webkit-user-select: none;\n\t\t\t-moz-user-select: none;\n\t\t\t-ms-user-select: none;\n\t\t\tuser-select: none;\n\t\t\tbackground-repeat: repeat-x;\n\t\t\tbackground-position: -1px -1px;\n\t\t\tbackground-size: 110% 110%;\n\t\t\tborder: 1px solid\n\t\t}\n\n\t\t.btn {\n\t\t\tborder-radius: .25em\n\t\t}\n\n\t\t.btn:not(:last-child) {\n\t\t\tborder-radius: .25em 0 0 .25em\n\t\t}\n\n\t\t.social-count {\n\t\t\tborder-left: 0;\n\t\t\tborder-radius: 0 .25em .25em 0\n\t\t}\n\n\t\t.widget-lg .btn,\n\t\t.widget-lg .social-count {\n\t\t\theight: 16px;\n\t\t\tpadding: 5px 10px;\n\t\t\tfont-size: 12px;\n\t\t\tline-height: 16px\n\t\t}\n\n\t\t.octicon {\n\t\t\tdisplay: inline-block;\n\t\t\tvertical-align: text-top;\n\t\t\tfill: currentColor;\n\t\t\toverflow: visible\n\t\t}\n\n\t\t.btn:focus-visible,\n\t\t.social-count:focus-visible {\n\t\t\toutline: 2px solid #0969da;\n\t\t\toutline-offset: -2px\n\t\t}\n\n\t\t.btn {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #ebf0f4;\n\t\t\tborder-color: #ccd1d5;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t}\n\n\t\t:root .btn {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:hover,\n\t\t.btn:focus {\n\t\t\tbackground-color: #e9ebef;\n\t\t\tbackground-position: 0 -0.5em;\n\t\t\tborder-color: #caccd1;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t}\n\n\t\t:root .btn:hover,\n\t\t:root .btn:focus {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:active {\n\t\t\tbackground-color: #e5e9ed;\n\t\t\tborder-color: #c7cbcf;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\tbackground-image: none;\n\t\t\tfilter: none\n\t\t}\n\n\t\t.social-count {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #fff;\n\t\t\tborder-color: #ddddde;\n\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t}\n\n\t\t.social-count:hover,\n\t\t.social-count:focus {\n\t\t\tcolor: #0969da\n\t\t}\n\n\t\t.octicon-heart {\n\t\t\tcolor: #bf3989\n\t\t}\n\n\t\t@media(prefers-color-scheme:light) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #0969da;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #ebf0f4;\n\t\t\t\tborder-color: #ccd1d5;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #e9ebef;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #caccd1;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #e5e9ed;\n\t\t\t\tborder-color: #c7cbcf;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #fff;\n\t\t\t\tborder-color: #ddddde;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #0969da\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #bf3989\n\t\t\t}\n\t\t}\n\n\t\t@media(prefers-color-scheme:dark) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #58a6ff;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #1a1e23;\n\t\t\t\tborder-color: #2f3439;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #21262d, #1a1e23 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #21262d, #1a1e23 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #292e33;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #30363d, #292e33 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #30363d, #292e33 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #161719;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(1, 4, 9, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #0d1117;\n\t\t\t\tborder-color: #24282e;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #58a6ff\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #db61a2\n\t\t\t}\n\t\t}\n\t}\n}\n\n#share-link-copied {\n\tcolor: hsl(60, 100%, 30%);\n\tdisplay: none;\n}\n\n#share-link-instructions {\n\tdisplay: none;\n}\n\n// Hide instructions in kiosk mode (higher specificity than the show rule)\nbody.kiosk #loading .instructions {\n\tdisplay: none !important;\n}\n\n.kiosk {\n\n\t// In kiosk mode, hide everything except the main weather display\n\t>*:not(#divTwc) {\n\t\tdisplay: none !important;\n\t}\n}\n\n#divInfo {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr;\n\tmax-width: 250px;\n}","@use 'colors'as c;\n\n@mixin text-shadow($offset: 3px, $outline: 1.5px) {\n\t/* eventually, when chrome supports paint-order for html elements */\n\t/* -webkit-text-stroke: 2px black; */\n\t/* paint-order: stroke fill; */\n\ttext-shadow:\n\t\t$offset $offset 0 c.$text-shadow,\n\t\t(-$outline) (-$outline) 0 c.$text-shadow,\n\t\t0 (-$outline) 0 c.$text-shadow,\n\t\t$outline (-$outline) 0 c.$text-shadow,\n\t\t$outline 0 0 c.$text-shadow,\n\t\t$outline $outline 0 c.$text-shadow,\n\t\t0 $outline 0 c.$text-shadow,\n\t\t(-$outline) $outline 0 c.$text-shadow,\n\t\t(-$outline) 0 0 c.$text-shadow;\n}\n\n@mixin status-colors() {\n\n\t.loading,\n\t.retrying {\n\t\tcolor: #ffff00;\n\t}\n\n\t.press-here {\n\t\tcolor: #00ff00;\n\t\tcursor: pointer;\n\t}\n\n\t.failed {\n\t\tcolor: #ff0000;\n\t}\n\n\t.no-data {\n\t\tcolor: #C0C0C0;\n\t}\n\n\t.disabled {\n\t\tcolor: #C0C0C0;\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display {\n\twidth: 640px;\n\theight: 480px;\n\toverflow: hidden;\n\tposition: relative;\n\tbackground-image: url(../images/backgrounds/1.png);\n\n\t/* this method is required to hide blocks so they can be measured while off screen */\n\theight: 0px;\n\n\t&.show {\n\t\theight: 480px;\n\t}\n\n\t.template {\n\t\tdisplay: none;\n\t}\n\n\t.header {\n\t\twidth: 640px;\n\t\theight: 60px;\n\t\tpadding-top: 30px;\n\n\t\t.title {\n\t\t\tcolor: c.$title-color;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\t\t\tposition: absolute;\n\t\t\twidth: 250px;\n\n\t\t\t&.single {\n\t\t\t\tleft: 170px;\n\t\t\t\ttop: 25px;\n\t\t\t}\n\n\t\t\t&.dual {\n\t\t\t\tleft: 170px;\n\n\t\t\t\t&>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t}\n\n\t\t\t\t.top {\n\t\t\t\t\ttop: -3px;\n\t\t\t\t}\n\n\t\t\t\t.bottom {\n\t\t\t\t\ttop: 26px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t.logo {\n\t\t\ttop: 30px;\n\t\t\tleft: 50px;\n\t\t\tposition: absolute;\n\t\t\tz-index: 10;\n\t\t}\n\n\t\t.noaa-logo {\n\t\t\tposition: absolute;\n\t\t\ttop: 39px;\n\t\t\tleft: 356px;\n\t\t}\n\n\t\t.title.single {\n\t\t\ttop: 40px;\n\t\t}\n\n\t\t.date-time {\n\t\t\twhite-space: pre;\n\t\t\tcolor: c.$date-time;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tleft: 415px;\n\t\t\twidth: 170px;\n\t\t\ttext-align: right;\n\t\t\tposition: absolute;\n\n\t\t\t&.date {\n\t\t\t\tpadding-top: 22px;\n\t\t\t}\n\t\t}\n\t}\n\n\t.main {\n\t\tposition: relative;\n\n\t\t&.has-scroll {\n\t\t\twidth: 640px;\n\t\t\tmargin-top: 0;\n\t\t\theight: 310px;\n\t\t\toverflow: hidden;\n\n\t\t\t&.no-header {\n\t\t\t\theight: 400px;\n\t\t\t\tmargin-top: 0; // Reset for no-header case since the gap issue is header-related\n\t\t\t}\n\t\t}\n\n\t\t&.has-box {\n\t\t\tmargin-left: 64px;\n\t\t\tmargin-right: 64px;\n\t\t\twidth: calc(100% - 128px);\n\t\t}\n\n\t}\n\n}\n\n#container>.scroll {\n\tdisplay: none;\n\t@include u.text-shadow(3px, 1.5px);\n\twidth: 640px;\n\theight: 77px;\n\toverflow: hidden;\n\tmargin-top: 3px;\n\tposition: absolute;\n\tbottom: 0px;\n\tz-index: 1;\n\n\t&.hazard {\n\t\tbackground-color: rgb(112, 35, 35);\n\t}\n\n\t.scroll-container {\n\t\twidth: 640px;\n\n\t\t.fixed,\n\t\t.scroll-header {\n\t\t\tmargin-left: 55px;\n\t\t\tmargin-right: 55px;\n\t\t\toverflow: hidden;\n\t\t\twhite-space: nowrap;\n\t\t}\n\n\t\t.scroll-header {\n\t\t\theight: 26px;\n\t\t\tfont-family: \"Star4000 Small\";\n\t\t\tfont-size: 20pt;\n\t\t\tmargin-top: -10px;\n\t\t}\n\n\t\t.fixed {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\n\t\t\t.scroll-area {\n\t\t\t\ttext-wrap: nowrap;\n\t\t\t\tposition: relative;\n\t\t\t\t// the following added by js code as it is dependent on the content of the element\n\t\t\t\t// transition: left (x)s;\n\t\t\t\t// left: calc((elem width) - 640px);\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n\n.wide #container>.scroll {\n\twidth: 854px;\n\tmargin-left: -107px;\n\n\t.scroll-container {\n\t\tmargin-left: 107px;\n\t}\n}","$title-color: yellow;\n$date-time: white;\n$text-shadow: black;\n$column-header-text: yellow;\n$column-header: rgb(32, 0, 87);\n\n$gradient-main-background-1: #102080;\n$gradient-main-background-2: #001040;\n\n$gradient-loading-1: #09246f;\n$gradient-loading-2: #364ac0;\n$gradient-loading-3: #4f99f9;\n$gradient-loading-4: #8ffdfa;\n\n$extended-low: #8080FF;\n\n$blue-box: #26235a;","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.current-weather {\n\t&.main {\n\n\t\t.col {\n\t\t\theight: 50px;\n\t\t\twidth: 255px;\n\t\t\tdisplay: inline-block;\n\t\t\tmargin-top: 10px;\n\t\t\tpadding-top: 10px;\n\t\t\tposition: absolute;\n\n\t\t\t@include u.text-shadow();\n\n\t\t\t&.left {\n\t\t\t\tfont-family: 'Star4000 Extended';\n\t\t\t\tfont-size: 24pt;\n\n\t\t\t}\n\n\t\t\t&.right {\n\t\t\t\tright: 0px;\n\t\t\t\tfont-family: \"Star4000 Large\";\n\t\t\t\tfont-size: 20px;\n\t\t\t\tfont-weight: bold;\n\t\t\t\tline-height: 24px;\n\n\t\t\t\t.row {\n\t\t\t\t\tmargin-bottom: 12px;\n\n\t\t\t\t\t.label,\n\t\t\t\t\t.value {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\n\t\t\t\t\t.label {\n\t\t\t\t\t\tmargin-left: 20px;\n\t\t\t\t\t}\n\n\t\t\t\t\t.value {\n\t\t\t\t\t\tfloat: right;\n\t\t\t\t\t\tmargin-right: 10px;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\t.center {\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000 Large';\n\t\t\tfont-size: 24pt;\n\t\t}\n\n\t\t.icon {\n\t\t\timg {\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tdisplay: block;\n\t\t\t}\n\t\t}\n\n\t\t.wind-container {\n\t\t\tmargin-left: 10px;\n\t\t\tdisplay: flex;\n\n\t\t\t&>div {\n\t\t\t\twidth: 50%;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\ttext-align: right;\n\t\t\t}\n\t\t}\n\n\t\t.wind-gusts {\n\t\t\ttext-align: right;\n\t\t\tfont-size: 28px;\n\t\t}\n\n\t\t.location {\n\t\t\tcolor: c.$title-color;\n\t\t\tmax-height: 32px;\n\t\t\tmargin-bottom: 10px;\n\t\t\tpadding-top: 4px;\n\t\t\toverflow: hidden;\n\t\t\ttext-wrap: nowrap;\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#extended-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/2.png');\n}\n\n.weather-display .main.extended-forecast {\n\t.day-container {\n\t\tmargin-top: 16px;\n\t\tmargin-left: 27px;\n\t}\n\n\t.day {\n\t\t@include u.text-shadow();\n\t\tpadding: 5px;\n\t\theight: 285px;\n\t\twidth: 155px;\n\t\tdisplay: inline-block;\n\t\tmargin: 0px 15px;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\n\t\t.date {\n\t\t\ttext-transform: uppercase;\n\t\t\ttext-align: center;\n\t\t\tcolor: c.$title-color;\n\t\t}\n\n\t\t.condition {\n\t\t\ttext-align: center;\n\t\t\theight: 74px;\n\t\t\tmargin-top: 5px;\n\t\t}\n\n\t\t.icon {\n\t\t\ttext-align: center;\n\t\t\theight: 75px;\n\n\t\t\timg {\n\t\t\t\tmax-height: 75px;\n\t\t\t}\n\t\t}\n\n\t\t.temperatures {\n\t\t\twidth: 100%;\n\n\t\t\t.temperature-block {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 44%;\n\t\t\t\tvertical-align: top;\n\n\t\t\t\t>div {\n\t\t\t\t\ttext-align: center;\n\t\t\t\t}\n\n\t\t\t\t.value {\n\t\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\t\tmargin-top: 4px;\n\t\t\t\t}\n\n\t\t\t\t&.lo .label {\n\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t}\n\n\t\t\t\t&.hi .label {\n\t\t\t\t\tcolor: c.$title-color;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .main.hourly {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\t\t.hourly-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\tbackground: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px,\n\t\t\t\t\tc.$gradient-main-background-1 136px,\n\t\t\t\t\tc.$gradient-main-background-1 202px,\n\t\t\t\t\tc.$gradient-main-background-2 338px,\n\t\t\t\t);\n\n\t\t\t.hourly-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.hour {\n\t\t\t\t\tleft: 25px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 255px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\tleft: 355px;\n\t\t\t\t}\n\n\t\t\t\t.like {\n\t\t\t\t\tleft: 425px;\n\n\t\t\t\t\t&.heat-index {\n\t\t\t\t\t\tcolor: #e00;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.wind-chill {\n\t\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\tleft: 505px;\n\t\t\t\t\twidth: 100px;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hourly-graph-html {\n\tbackground-image: url(../images/backgrounds/1-chart.png);\n\n\t.header {\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\ttop: 35px;\n\t\t\tright: 60px;\n\t\t\twidth: 360px;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 28px;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: right;\n\n\t\t\tdiv {\n\t\t\t\tmargin-top: -18px;\n\t\t\t}\n\n\t\t\t.temperature {\n\t\t\t\tcolor: red;\n\t\t\t}\n\n\t\t\t.dewpoint {\n\t\t\t\tcolor: green;\n\t\t\t}\n\n\t\t\t.cloud {\n\t\t\t\tcolor: lightgrey;\n\t\t\t}\n\n\t\t\t.rain {\n\t\t\t\tcolor: aqua;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.hourly-graph {\n\n\t&.main {\n\t\t>div {\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.label {\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\tcolor: c.$column-header-text;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-top: -15px;\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.x-axis {\n\t\t\tbottom: 0px;\n\t\t\tleft: 54px;\n\t\t\twidth: 532px;\n\t\t\theight: 20px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: center;\n\t\t\t\ttransform: translateX(-50%);\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\tleft: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\tleft: calc(532px / 4 * 1);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tleft: calc(532px / 4 * 2);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tleft: calc(532px / 4 * 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-5 {\n\t\t\t\t\tleft: calc(532px / 4 * 4);\n\t\t\t\t}\n\t\t\t}\n\n\n\n\t\t}\n\n\t\t.chart {\n\t\t\ttop: 0px;\n\t\t\tleft: 50px;\n\n\t\t\timg {\n\t\t\t\twidth: 532px;\n\t\t\t\theight: 285px;\n\t\t\t}\n\t\t}\n\n\t\t.y-axis {\n\t\t\ttop: 0px;\n\t\t\tleft: 0px;\n\t\t\twidth: 50px;\n\t\t\theight: 285px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\ttop: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\ttop: calc(280px / 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tbottom: calc(280px / 3 - 11px);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tbottom: 0px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.travel {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\twidth: 100%;\n\t\t\tz-index: 5;\n\t\t\toverflow: hidden; // prevent thin gaps between header and content\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\twidth: 50px;\n\t\t\t\ttext-align: center;\n\n\t\t\t\t&.low {\n\t\t\t\t\tleft: 455px;\n\n\t\t\t\t}\n\n\t\t\t\t&.high {\n\t\t\t\t\tleft: 510px;\n\t\t\t\t\twidth: 60px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.travel-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\tbackground: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px,\n\t\t\t\t\tc.$gradient-main-background-1 136px,\n\t\t\t\t\tc.$gradient-main-background-1 202px,\n\t\t\t\t\tc.$gradient-main-background-2 338px,\n\t\t\t\t);\n\n\t\t\t.travel-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.city {\n\t\t\t\t\tleft: 80px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 330px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\n\t\t\t\t\timg {\n\t\t\t\t\t\tmax-width: 47px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\twidth: 50px;\n\t\t\t\t\ttext-align: center;\n\n\t\t\t\t\t&.low {\n\t\t\t\t\t\tleft: 455px;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.high {\n\t\t\t\t\t\tleft: 510px;\n\t\t\t\t\t\twidth: 60px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .latest-observations {\n\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\ttop: 0px;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\t// hidden initially for english/metric switching\n\t\t\t\tdisplay: none;\n\n\t\t\t\t&.show {\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.temp {\n\t\t\tleft: 230px;\n\t\t}\n\n\t\t.weather {\n\t\t\tleft: 280px;\n\t\t}\n\n\t\t.wind {\n\t\t\tleft: 430px;\n\t\t}\n\n\t\t.observation-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.observation-row {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\t\t\t\theight: 40px;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .local-forecast {\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 280px;\n\t\toverflow: hidden;\n\t}\n\n\t.forecasts {\n\t\tposition: relative;\n\t}\n\n\t.forecast {\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\t\ttext-transform: uppercase;\n\t\t@include u.text-shadow();\n\t\tmin-height: 280px;\n\t\tline-height: 40px;\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .progress {\n\t@include u.text-shadow();\n\tfont-family: 'Star4000 Extended';\n\tfont-size: 18pt;\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 310px;\n\t\toverflow: hidden;\n\t\tline-height: 26px;\n\n\t\t.item {\n\t\t\tposition: relative;\n\n\t\t\t.name {\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&::after {\n\t\t\t\t\tcontent: '........................................................................';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.links {\n\t\t\t\tposition: absolute;\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\t\t\t\ttop: 0px;\n\n\t\t\t\t>div {\n\t\t\t\t\tbackground-color: c.$blue-box;\n\t\t\t\t\tdisplay: none;\n\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t}\n\n\t\t\t\t@include u.status-colors();\n\n\t\t\t\t&.loading .loading,\n\t\t\t\t&.press-here .press-here,\n\t\t\t\t&.failed .failed,\n\t\t\t\t&.no-data .no-data,\n\t\t\t\t&.disabled .disabled,\n\t\t\t\t&.retrying .retrying {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\n}\n\n#progress-html.weather-display .scroll {\n\n\t@keyframes progress-scroll {\n\t\t0% {\n\t\t\tbackground-position: -40px 0;\n\t\t}\n\n\t\t100% {\n\t\t\tbackground-position: 40px 0;\n\t\t}\n\t}\n\n\t.progress-bar-container {\n\t\tborder: 2px solid black;\n\t\tbackground-color: white;\n\t\tmargin: 20px auto;\n\t\twidth: 524px;\n\t\tposition: relative;\n\t\tdisplay: none;\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t.progress-bar {\n\t\t\theight: 20px;\n\t\t\tmargin: 2px;\n\t\t\twidth: 520px;\n\t\t\tbackground: repeating-linear-gradient(90deg,\n\t\t\t\t\tc.$gradient-loading-1 0px,\n\t\t\t\t\tc.$gradient-loading-1 5px,\n\t\t\t\t\tc.$gradient-loading-2 5px,\n\t\t\t\t\tc.$gradient-loading-2 10px,\n\t\t\t\t\tc.$gradient-loading-3 10px,\n\t\t\t\t\tc.$gradient-loading-3 15px,\n\t\t\t\t\tc.$gradient-loading-4 15px,\n\t\t\t\t\tc.$gradient-loading-4 20px,\n\t\t\t\t\tc.$gradient-loading-3 20px,\n\t\t\t\t\tc.$gradient-loading-3 25px,\n\t\t\t\t\tc.$gradient-loading-2 25px,\n\t\t\t\t\tc.$gradient-loading-2 30px,\n\t\t\t\t\tc.$gradient-loading-1 30px,\n\t\t\t\t\tc.$gradient-loading-1 40px,\n\t\t\t\t);\n\t\t\t// animation\n\t\t\tanimation-duration: 2s;\n\t\t\tanimation-fill-mode: forwards;\n\t\t\tanimation-iteration-count: infinite;\n\t\t\tanimation-name: progress-scroll;\n\t\t\tanimation-timing-function: steps(8, end);\n\t\t}\n\n\t\t.cover {\n\t\t\tposition: absolute;\n\t\t\ttop: 0px;\n\t\t\tright: 0px;\n\t\t\tbackground-color: white;\n\t\t\twidth: 100%;\n\t\t\theight: 24px;\n\t\t\ttransition: width 1s steps(6);\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#radar-html.weather-display {\n\tbackground-image: url('../images/backgrounds/4.png');\n\n\t.header {\n\t\theight: 83px;\n\n\t\t.title.dual {\n\t\t\tcolor: white;\n\t\t\tfont-family: 'Arial', sans-serif;\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 28pt;\n\t\t\tleft: 155px;\n\n\t\t\t.top {\n\t\t\t\ttop: -4px;\n\t\t\t}\n\n\t\t\t.bottom {\n\t\t\t\ttop: 31px;\n\t\t\t}\n\t\t}\n\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\tright: 0px;\n\t\t\twidth: 360px;\n\t\t\tmargin-top: 2px;\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 18pt;\n\t\t\tfont-weight: bold;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: center;\n\n\t\t\t.scale>div {\n\t\t\t\tdisplay: inline-block;\n\t\t\t}\n\n\t\t\t.scale-table {\n\t\t\t\tdisplay: table-row;\n\t\t\t\tborder-collapse: collapse;\n\n\t\t\t\t.box {\n\t\t\t\t\tdisplay: table-cell;\n\t\t\t\t\tborder: 2px solid black;\n\t\t\t\t\twidth: 17px;\n\t\t\t\t\theight: 24px;\n\t\t\t\t\tpadding: 0\n\t\t\t\t}\n\n\t\t\t\t.box-1 {\n\t\t\t\t\tbackground-color: rgb(49, 210, 22);\n\t\t\t\t}\n\n\t\t\t\t.box-2 {\n\t\t\t\t\tbackground-color: rgb(28, 138, 18);\n\t\t\t\t}\n\n\t\t\t\t.box-3 {\n\t\t\t\t\tbackground-color: rgb(20, 90, 15);\n\t\t\t\t}\n\n\t\t\t\t.box-4 {\n\t\t\t\t\tbackground-color: rgb(10, 40, 10);\n\t\t\t\t}\n\n\t\t\t\t.box-5 {\n\t\t\t\t\tbackground-color: rgb(196, 179, 70);\n\t\t\t\t}\n\n\t\t\t\t.box-6 {\n\t\t\t\t\tbackground-color: rgb(190, 72, 19);\n\t\t\t\t}\n\n\t\t\t\t.box-7 {\n\t\t\t\t\tbackground-color: rgb(171, 14, 14);\n\t\t\t\t}\n\n\t\t\t\t.box-8 {\n\t\t\t\t\tbackground-color: rgb(115, 31, 4);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.scale {\n\t\t\t\t.text {\n\t\t\t\t\tposition: relative;\n\t\t\t\t\ttop: -5px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.time {\n\t\t\t\tposition: relative;\n\t\t\t\tfont-weight: normal;\n\t\t\t\ttop: -14px;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.radar {\n\toverflow: hidden;\n\theight: 367px;\n\n\t.container {\n\n\t\t.tiles {\n\t\t\tposition: absolute;\n\t\t\twidth: 1400px;\n\n\t\t\timg {\n\t\t\t\tvertical-align: middle;\n\t\t\t}\n\t\t}\n\n\t\t.scroll-area {\n\t\t\tposition: relative;\n\t\t}\n\t}\n}\n\n.wide.radar #container {\n\tbackground: url(../images/backgrounds/4-wide.png);\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#regional-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/5.png');\n}\n\n.weather-display .main.regional-forecast {\n\n\n\tposition: relative;\n\n\t.map {\n\t\tposition: absolute;\n\t\ttransform-origin: 0 0;\n\t}\n\n\t.location {\n\t\tposition: absolute;\n\t\twidth: 140px;\n\t\tmargin-left: -40px;\n\t\tmargin-top: -35px;\n\n\t\t>div {\n\t\t\tposition: absolute;\n\t\t\t@include u.text-shadow();\n\t\t}\n\n\t\t.icon {\n\t\t\ttop: 26px;\n\t\t\tleft: 44px;\n\n\t\t\timg {\n\t\t\t\tmax-height: 32px;\n\t\t\t}\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000 Large';\n\t\t\tfont-size: 28px;\n\t\t\tpadding-top: 2px;\n\t\t\tcolor: c.$title-color;\n\t\t\ttop: 28px;\n\t\t\ttext-align: right;\n\t\t\twidth: 40px;\n\t\t}\n\n\t\t.city {\n\t\t\tfont-family: Star4000;\n\t\t\tfont-size: 20px;\n\t\t}\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n#almanac-html.weather-display {\n\tbackground-image: url('../images/backgrounds/3.png');\n}\n\n.weather-display .main.almanac {\n\tfont-family: 'Star4000';\n\tfont-size: 24pt;\n\t@include u.text-shadow();\n\n\t.sun {\n\t\t// Use CSS Grid for cross-browser consistency\n\t\t// Grid is populated in reading order (left-to-right, top-to-bottom):\n\t\tdisplay: grid;\n\t\tgrid-template-columns: auto auto auto;\n\t\tgrid-template-rows: auto auto auto;\n\t\tgap: 0px 90px;\n\t\tmargin: 3px auto 5px auto; // align the bottom of the div with the background\n\t\twidth: fit-content;\n\t\tline-height: 30px;\n\n\t\t.grid-item {\n\t\t\t// Reset inherited styles that interfere with grid layout\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tpadding: 0;\n\t\t\tmargin: 0;\n\t\t\tposition: relative;\n\n\t\t\t// Column headers (day names)\n\t\t\t&.header {\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t// Row labels (Sunrise:, Sunset:)\n\t\t\t&.row-label {\n\t\t\t\t// color: c.$column-header-text; // screenshots show labels were white\n\t\t\t\ttext-align: right;\n\t\t\t}\n\n\t\t\t// Time values (sunrise/sunset)\n\t\t\t&.time {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t}\n\t}\n\n\t.moon {\n\t\tposition: relative;\n\t\tpadding: 7px 50px;\n\t\tline-height: 36px;\n\n\t\t.title {\n\t\t\tcolor: c.$column-header-text;\n\t\t\tpadding-left: 13px;\n\t\t}\n\n\t\t.day {\n\t\t\tdisplay: inline-block;\n\t\t\ttext-align: center;\n\t\t\twidth: 132px;\n\n\t\t\t.icon {\n\t\t\t\t// shadow in image make it look off center\n\t\t\t\tpadding-left: 10px;\n\t\t\t}\n\n\t\t\t.date {\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -10px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hazards-html.weather-display {\n\tbackground-image: url('../images/backgrounds/7.png');\n}\n\n.weather-display .main.hazards {\n\t&.main {\n\t\toverflow-y: hidden;\n\t\theight: 480px;\n\t\tbackground-color: rgb(112, 35, 35);\n\n\n\t\t.hazard-lines {\n\t\t\tmin-height: 400px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.hazard {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: white;\n\t\t\t\t@include u.text-shadow(0px);\n\t\t\t\tposition: relative;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\tmargin-left: 80px;\n\t\t\t\tmargin-right: 80px;\n\t\t\t\tpadding-bottom: 10px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.wide.hazards #container {\n\tbackground: url(../images/backgrounds/7-wide.png);\n}",".media {\n\tdisplay: none;\n}\n\n#ToggleMediaContainer {\n\tdisplay: none;\n\tposition: relative;\n\n\t&.available {\n\t\tdisplay: inline-block;\n\n\t\timg.on {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\timg.off {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t// icon switch is handled by adding/removing the .playing class\n\t\t&.playing {\n\t\t\timg.on {\n\t\t\t\tdisplay: block;\n\t\t\t}\n\n\t\t\timg.off {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\n\t\t}\n\n\n\t}\n\n\t.volume-slider {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\ttop: 0px;\n\t\ttransform: translateY(-100%);\n\t\twidth: 100%;\n\t\tbackground-color: #000;\n\t\ttext-align: center;\n\t\tz-index: 100;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #303030;\n\t\t}\n\n\t\tinput[type=\"range\"] {\n\t\t\twriting-mode: vertical-lr;\n\t\t\tdirection: rtl;\n\t\t\tmargin-top: 20px;\n\t\t\tmargin-bottom: 20px;\n\t\t}\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\t}\n\n\n\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#spc-outlook-html.weather-display {\n\tbackground-image: url('../images/backgrounds/6.png');\n}\n\n.weather-display .spc-outlook {\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 0px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 300px;\n\t\toverflow: hidden;\n\t}\n\n\t.risk-levels {\n\t\tposition: absolute;\n\t\tleft: 206px;\n\t\tfont-family: 'Star4000 Small';\n\t\tfont-size: 32px;\n\t\t@include u.text-shadow();\n\n\n\t\t.risk-level {\n\t\t\tposition: relative;\n\t\t\ttop: -14px;\n\t\t\theight: 20px;\n\n\t\t\t&:nth-child(1) {\n\t\t\t\tleft: calc(20px * 5);\n\t\t\t}\n\n\t\t\t&:nth-child(2) {\n\t\t\t\tleft: calc(20px * 4);\n\t\t\t}\n\n\t\t\t&:nth-child(3) {\n\t\t\t\tleft: calc(20px * 3);\n\t\t\t}\n\n\t\t\t&:nth-child(4) {\n\t\t\t\tleft: calc(20px * 2);\n\t\t\t}\n\n\t\t\t&:nth-child(5) {\n\t\t\t\tleft: calc(20px * 1);\n\t\t\t}\n\n\t\t\t&:nth-child(6) {\n\t\t\t\tleft: calc(20px * 0);\n\t\t\t}\n\t\t}\n\t}\n\n\t.days {\n\t\tposition: absolute;\n\t\ttop: 120px;\n\n\t\t.day {\n\t\t\theight: 60px;\n\n\t\t\t.day-name {\n\t\t\t\tposition: absolute;\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\twidth: 200px;\n\t\t\t\ttext-align: right;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tpadding-top: 20px;\n\t\t\t}\n\n\t\t\t.risk-bar {\n\t\t\t\tposition: absolute;\n\t\t\t\twidth: 150px;\n\t\t\t\theight: 40px;\n\t\t\t\tleft: 210px;\n\t\t\t\tmargin-top: 20px;\n\t\t\t\tborder: 3px outset hsl(0, 0%, 70%);\n\t\t\t\tbackground: linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%);\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#server-observations-html.weather-display {\n\t.header .title.single {\n\t\tfont-size: 20pt;\n\t}\n}\n\n.weather-display .server-observations {\n\t// Override the default has-scroll height to fit content properly\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.server-output {\n\t\tposition: relative;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 20pt;\n\t\tline-height: 32px;\n\t\tcolor: #fff;\n\t\ttext-transform: uppercase;\n\t\ttext-align: center;\n\t\t@include u.text-shadow();\n\n\t\t.server-page {\n\t\t\theight: 250px;\n\t\t\tpadding: 0 8px;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\n\t\t.server-line {\n\t\t\twhite-space: normal;\n\t\t\toverflow-wrap: anywhere;\n\t\t\tword-break: break-word;\n\t\t\tmargin-bottom: 6px;\n\t\t}\n\t}\n}\n","/* =========================================================\n REGULAR SCANLINES SETTINGS\n ========================================================= */\n\n$scan-width: 1px;\n$scan-crt: false;\n$scan-fps: 20;\n$scan-color: rgba(#000, 0.30);\n$scan-z-index: 2147483648;\n\n$scan-moving-line: true;\n$scan-opacity: 0.75;\n\n/* =========================================================\n CRT / S-VIDEO EFFECT SETTINGS\n ========================================================= */\n\n// whole-screen softness\n$crt-soft-blur: 0.45px;\n\n// mild brightening / contrast to keep blur from looking muddy\n$crt-contrast: 1.04;\n$crt-saturation: 1.08;\n$crt-brightness: 0.98;\n\n// fake horizontal chroma bleed\n$crt-r-shift: -0.7px;\n$crt-b-shift: 0.7px;\n$crt-bleed-blur: 1.2px;\n$crt-rgb-opacity: 0.04;\n\n// subtle tube edge darkening\n$crt-vignette-opacity: 0.16;\n\n// optional tiny bloom\n$crt-glow-opacity: 0.05;\n\n/* =========================================================\n MIXINS\n ========================================================= */\n\n@mixin scan-crt($enabled) {\n @if $enabled == true {\n animation: scanlines 1s steps($scan-fps) infinite;\n } @else {\n animation: none;\n }\n}\n\n@mixin scan-moving($enabled) {\n @if $enabled == true {\n animation: scanline 6s linear infinite;\n } @else {\n animation: none;\n }\n}\n\n/* =========================================================\n APPLY TO THE REAL APP CONTAINER\n ========================================================= */\n\n/*\n You can add class=\"scanlines\" to #divTwcMain or #container.\n Example:\n

\n*/\n\n.scanlines {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n\n /*\n This is the actual rendered weather area in your HTML.\n Applying the softness here affects the maps/text/icons themselves.\n */\n #container {\n position: relative;\n z-index: 1;\n transform: translateZ(0);\n will-change: filter;\n\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n }\n\n /*\n Red fringe overlay\n */\n #container::before,\n #container::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n }\n\n #container::before {\n background:\n linear-gradient(\n to right,\n rgba(255, 0, 0, $crt-rgb-opacity) 0%,\n rgba(255, 0, 0, 0.01) 15%,\n rgba(255, 0, 0, 0.00) 50%,\n rgba(255, 0, 0, 0.01) 85%,\n rgba(255, 0, 0, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-r-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Blue fringe overlay\n */\n #container::after {\n background:\n linear-gradient(\n to right,\n rgba(0, 140, 255, $crt-rgb-opacity) 0%,\n rgba(0, 140, 255, 0.01) 15%,\n rgba(0, 140, 255, 0.00) 50%,\n rgba(0, 140, 255, 0.01) 85%,\n rgba(0, 140, 255, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-b-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Moving scanline\n */\n &:before,\n &:after {\n display: block;\n pointer-events: none;\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n }\n\n &:before {\n height: var(--scanline-thickness, $scan-width);\n z-index: $scan-z-index + 2;\n background: $scan-color;\n opacity: $scan-opacity;\n @include scan-moving($scan-moving-line);\n }\n\n /*\n Regular scanline mask\n */\n &:after {\n top: 0;\n bottom: 0;\n z-index: $scan-z-index;\n background: repeating-linear-gradient(\n to bottom,\n transparent 0,\n transparent var(--scanline-thickness, $scan-width),\n $scan-color var(--scanline-thickness, $scan-width),\n $scan-color calc(var(--scanline-thickness, $scan-width) * 2)\n );\n @include scan-crt($scan-crt);\n }\n\n /*\n Vignette layer\n Added as an inset shadow so you don't need extra HTML\n */\n box-shadow:\n inset 0 0 80px rgba(0, 0, 0, $crt-vignette-opacity),\n inset 0 0 18px rgba(255, 255, 255, $crt-glow-opacity);\n}\n\n/* =========================================================\n OPTIONAL: only affect active weather panels, not menus\n ========================================================= */\n\n/*\n If the controls / bottom nav get too blurry, move the blur\n from #container to the weather slides only:\n*/\n.scanlines.crt-panels-only {\n #container {\n filter: none;\n }\n\n .weather-display {\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n\n transform: translateZ(0);\n }\n}\n\n/* =========================================================\n OPTIONAL: make text slightly glow like old TV phosphors\n ========================================================= */\n\n.scanlines {\n .header,\n .main,\n .scroll,\n .date-time,\n .city,\n .temp,\n .condition,\n .location,\n .label,\n .value,\n .title {\n text-shadow:\n 0 0 1px rgba(255, 255, 255, 0.18),\n 0 0 2px rgba(255, 255, 255, 0.06);\n }\n}\n\n/* =========================================================\n ANIMATIONS\n ========================================================= */\n\n@keyframes scanline {\n 0% {\n transform: translate3d(0, 200000%, 0);\n }\n}\n\n@keyframes scanlines {\n 0% {\n background-position: 0 50%;\n }\n}\n\n"],"file":"ws.min.css"} \ No newline at end of file +{"version":3,"sources":["_page.scss","shared/_utils.scss","_weather-display.scss","shared/_colors.scss","_current-weather.scss","_extended-forecast.scss","_hourly.scss","_hourly-graph.scss","_travel.scss","_latest-observations.scss","_local-forecast.scss","_progress.scss","_radar.scss","_regional-forecast.scss","_almanac.scss","_hazards.scss","_media.scss","_spc-outlook.scss","_server-observations.scss","_linux-news.scss","shared/_scanlines.scss"],"names":[],"mappings":"AAGA,WACC,uBACA,iDACA,kBAGD,KACC,uBACA,SAEA,mCAJD,KAKE,sBACA,YAIA,mCADD,OAEE,eAIF,WACC,WACA,YACA,gBACA,YAEA,iCAIF,UACC,gBACA,YAEA,mBACC,qBACA,YACA,iBAEA,8BACC,YACA,sBAGD,0BACC,eACA,yBAEA,mCAJD,0BAKE,sBACA,YAQA,uCACC,aAEA,mCAHD,uCAIE,sBAKD,mCADD,wCAEE,cAKH,qCACC,sBAEA,mCAHD,qCAIE,uBAGD,yCACC,iBAMJ,iCAEC,uBAGD,uBACC,yBACA,gBACA,eACA,gBACA,qBAGA,sBACA,WACA,sBAEA,mCAZD,uBAaE,sBACA,WACA,uBAOH,0BACC,sBACA,sBACA,kBACA,aAEA,mCAND,0BAOE,uBAGD,8BAEC,mBACA,gBACA,uBACA,eAEA,uCACC,sBACA,WAMH,QACC,cACA,sBACA,WACA,WACA,gBACA,SAEA,aACC,gBAIF,iBACC,YAGD,YACC,YACA,aACA,kBAEA,kBACC,YAIF,eACC,gBAGD,YACC,aACA,iBACA,sBACA,sBAGD,gBACC,OACA,mBACA,aACA,sBACA,uBAGD,aACC,gBACA,aACA,sBACA,sBAGD,iBACC,OACA,kBACA,aACA,sBACA,uBAGD,cAEC,aACA,mBACA,sBAEA,WACA,YAEA,oBACC,YAGD,mCAbD,cAcE,0BAKF,kBACC,iBACA,kBAIA,yBAND,kBAOE,gBAGD,yBAVD,kBAWE,gBAGD,yBAdD,kBAeE,gBAGD,yBAlBD,kBAmBE,gBAGD,yBAtBD,kBAuBE,gBAIF,kBACC,OACA,gBAID,oBACC,OACA,kBAGD,mBACC,OACA,iBAGD,oBACC,aAGD,WACC,WACA,aACA,mBACA,sBACA,WACA,gBAGD,eACC,iBACA,kBAGD,eACC,OACA,gBAGD,iBACC,OACA,kBAGD,gBACC,OACA,iBAGD,YACC,kBACA,kBAGD,YACC,uBAGD,eACC,YAGD,WACC,gCACA,0DACA,kBAGD,WACC,6BACA,uDACA,kBAGD,WACC,6BACA,uDACA,kBAGD,SACC,uBACA,eACA,WAGD,WACC,kBACA,YACA,aAEA,kDACA,qBACA,4BAGD,iBACC,mBACA,oBACA,iDACA,4BAGD,wDAGC,YACA,aAGD,SACC,YACA,aACA,eACA,yBACA,aACA,mBACA,kBACA,uBAEA,gBACC,2BACA,eACA,WACA,kBAGD,kBACC,mBAGD,uBACC,eAIF,SACC,iBACA,gBAGD,UACC,mBAGD,2BAEC,mBCzXA,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,UAGD,6CACC,aAGD,+CACC,aDyWD,mDACC,WAGD,oCAEC,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,WAGD,6CACC,oBAGD,+CACC,qBAIF,uCACC,cACA,sBACA,eAEA,qDACC,aAEA,+DACC,eACA,UAMJ,kBACC,sBAGA,yBACC,wBACC,oBAKH,kCAEC,aACA,mBACA,uBACA,qBAEA,sDACC,YAIF,oDAEC,kBAGD,8DAEC,aACA,mBACA,gCACA,WACA,WACA,kBACA,WAIA,6BACC,aAIF,WACC,eAGD,iBACC,qBAEA,qBACC,aAGD,sBACC,qBAKA,wBACC,qBAGD,yBACC,aAMH,SACC,mBACA,UACA,8BAGD,2BACC,kBACA,UACA,8CAGD,cACC,YACA,6BACA,aACA,6BACA,eAGC,qBACC,qBACA,UAGD,2BACC,qBACA,gBACA,iFACA,YACA,cACA,mBAGD,yDAEC,kBACA,qBACA,oBACA,YACA,gBACA,eACA,gBACA,iBACA,sBACA,eACA,yBACA,sBACA,qBACA,iBACA,2BACA,8BACA,0BACA,iBAGD,wBACC,oBAGD,yCACC,8BAGD,iCACC,cACA,8BAGD,+EAEC,YACA,iBACA,eACA,iBAGD,4BACC,qBACA,wBACA,kBACA,iBAGD,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,cAGD,oCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,eAIF,mCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,kCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,8CACA,sBACA,YAGD,iCACC,cACA,yBACA,qBACA,kCAGD,8EAEC,cAGD,kCACC,eAMJ,mBACC,WACA,aAGD,yBACC,aAID,kCACC,wBAMA,sBACC,wBAIF,SACC,aACA,8BACA,gBEnzBD,iBACC,YACA,aACA,gBACA,kBACA,kDAGA,WAEA,sBACC,aAGD,2BACC,aAGD,yBACC,YACA,YACA,iBAEA,gCACC,MC3BW,KFMb,YACC,6JCsBC,uBACA,eACA,kBACA,YAEA,uCACC,WACA,SAGD,qCACC,WAEA,yCACC,kBAGD,0CACC,SAGD,6CACC,SAMH,+BACC,SACA,UACA,kBACA,WAGD,oCACC,kBACA,SACA,WAGD,uCACC,SAGD,oCACC,gBACA,MC3ES,KD4ET,6BACA,eDxEF,YACC,6JCyEC,WACA,YACA,iBACA,kBAEA,yCACC,iBAKH,uBACC,kBAEA,kCACC,YACA,aACA,aACA,gBAEA,4CACC,aACA,aAIF,+BACC,iBACA,kBACA,yBAOH,mBACC,aD/GA,YACC,6JCgHD,YACA,YACA,gBACA,eACA,kBACA,WACA,UAEA,0BACC,yBAGD,qCACC,YAEA,gGAEC,iBACA,kBACA,gBACA,mBAGD,oDACC,YACA,6BACA,eACA,iBAGD,4CACC,uBACA,eAEA,yDACC,iBACA,kBAYJ,yBACC,YACA,mBAEA,2CACC,kBEtKA,iDACC,YACA,YACA,qBACA,gBACA,iBACA,kBHNF,YACC,6JGSC,sDACC,gCACA,eAID,uDACC,UACA,6BACA,eACA,iBACA,iBAEA,4DACC,mBAEA,sIAEC,qBAGD,mEACC,iBAGD,mEACC,YACA,kBAQJ,oDACC,kBAGD,kDACC,6BACA,eAIA,sDACC,cACA,cAIF,4DACC,iBACA,aAEA,gEACC,UAGD,kEACC,iBAIF,wDACC,iBACA,eAGD,sDACC,MDtFW,KCuFX,gBACA,mBACA,gBACA,gBACA,iBCxFH,wCACC,oDAIA,wDACC,gBACA,iBAGD,8CJPA,YACC,6JIQA,YACA,aACA,YACA,qBACA,gBACA,uBACA,eAEA,oDACC,yBACA,kBACA,MF1BW,KE6BZ,yDACC,kBACA,YACA,eAGD,oDACC,kBACA,YAEA,wDACC,gBAIF,4DACC,WAEA,+EACC,qBACA,UACA,mBAEA,mFACC,kBAGD,sFACC,6BACA,eAGD,yFACC,MFhDU,QEmDX,yFACC,MFlES,KGIb,mCACC,kBAEA,mDACC,iBHJa,QGKb,YACA,kBACA,WAGD,mDACC,gBACA,QACA,UAEA,uDACC,qBACA,6BACA,eACA,MHpBiB,KGqBjB,kBACA,UACA,ULpBH,YACC,6JKuBC,yDACC,WAGD,yDACC,WAGD,yDACC,WAIF,iDACC,iBACA,iBAEA,qGAMA,6DACC,6BACA,eACA,YACA,MHzDU,KFMb,YACC,6JKoDE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAGD,mEACC,WAGD,mEACC,WAEA,8EACC,WAGD,8EACC,MH5ES,QGgFX,mEACC,WACA,YACA,iBC9FL,mBACC,wDAGC,kCACC,kBACA,SACA,WACA,YACA,6BACA,eNPF,YACC,6JMQC,iBAEA,sCACC,iBAGD,+CACC,UAGD,4CACC,YAGD,yCACC,cAGD,wCACC,WASF,6CACC,kBAGD,gDACC,6BACA,eACA,MJ/CkB,KFGpB,YACC,6JM6CC,iBACA,kBAGD,iDACC,WACA,UACA,YACA,YAEA,wDACC,kBACA,2BACA,mBAEA,4DACC,SAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAQH,gDACC,QACA,UAEA,oDACC,YACA,aAIF,iDACC,QACA,SACA,WACA,aAEA,wDACC,iBACA,UAEA,4DACC,QAGD,4DACC,oBAGD,4DACC,uBAGD,4DACC,WAKH,yDACC,iBJ/Ha,QIgIb,YACA,kBACA,WAGD,yDACC,gBACA,QACA,UAGA,+DACC,WAGD,+DACC,WAGD,+DACC,WCpJH,mCACC,kBAEA,mDACC,iBLJa,QKKb,YACA,gBACA,QACA,WACA,UACA,gBAEA,uDACC,qBACA,6BACA,eACA,MLjBiB,KKkBjB,kBACA,UACA,UPjBH,YACC,6JOoBC,yDACC,WACA,kBAEA,6DACC,WAID,8DACC,WACA,WAKH,iDACC,iBACA,iBAEA,qGAMA,6DACC,6BACA,eACA,YACA,MLzDU,KFMb,YACC,6JOoDE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAEA,uEACC,eAIF,mEACC,WACA,kBAEA,uEACC,WAGD,wEACC,WACA,WCvFL,2CACC,kBAEA,2DACC,YACA,kBACA,WAGD,2DACC,QAEA,+DACC,qBACA,6BACA,eACA,kBACA,URhBH,YACC,6JQmBC,iEAEC,aAEA,sEACC,qBAKH,iDACC,WAGD,oDACC,WAGD,iDACC,WAGD,8DACC,iBACA,iBAEA,+EACC,uBACA,eRhDH,YACC,6JQiDE,kBACA,YAEA,mFACC,kBACA,QAGD,qFACC,gBACA,iBC9DJ,4CACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,4CACC,kBAGD,2CACC,uBACA,eACA,yBTdD,YACC,6JSeA,iBACA,iBCpBF,2BVGC,YACC,6JUFD,gCACA,eAEA,sCACC,kBACA,SACA,gBACA,sBACA,aACA,gBACA,iBAEA,4CACC,kBAEA,kDACC,mBAEA,yDACC,mFAIF,mDACC,kBACA,iBACA,UACA,QAEA,uDACC,iBRnBM,QQoBN,aACA,iBVjBJ,yHAEC,WAGD,+DACC,WACA,eAGD,2DACC,UAGD,4DACC,aAGD,6DACC,aUGE,gaAMC,cAYJ,2BACC,GACC,4BAGD,KACC,4BAIF,+DACC,sBACA,sBACA,iBACA,YACA,kBACA,aAEA,oEACC,cAGD,6EACC,YACA,WACA,YACA,6OAiBA,sBACA,6BACA,mCACA,+BACA,wCAGD,sEACC,kBACA,QACA,UACA,sBACA,WACA,YACA,6BClHH,4BACC,oDAEA,oCACC,YAEA,gDACC,WACA,+BACA,iBACA,eACA,WAEA,qDACC,SAGD,wDACC,SAIF,2CACC,kBACA,UACA,YACA,eACA,uBACA,eACA,iBX1BF,YACC,6JW2BC,kBAEA,sDACC,qBAGD,wDACC,kBACA,yBAEA,6DACC,mBACA,sBACA,WACA,YACA,UAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAKD,wDACC,kBACA,SAIF,iDACC,kBACA,mBACA,UACA,6BACA,eAMJ,6BACC,gBACA,aAIC,+CACC,kBACA,aAEA,mDACC,sBAIF,qDACC,kBAKH,uBACC,iDC1HD,wCACC,oDAGD,yCAGC,kBAEA,8CACC,kBACA,qBAGD,mDACC,kBACA,YACA,kBACA,iBAEA,uDACC,kBZlBF,YACC,6JYqBA,yDACC,SACA,UAEA,6DACC,gBAIF,yDACC,6BACA,eACA,gBACA,MVzCW,KU0CX,SACA,iBACA,WAGD,yDACC,qBACA,eC9CH,8BACC,oDAGD,+BACC,uBACA,ebHA,YACC,6JaKD,oCAGC,aACA,qCACA,kCACA,aACA,yBACA,kBACA,iBAEA,+CAEC,WACA,YACA,UACA,SACA,kBAGA,sDACC,MX9BiB,KW+BjB,kBAID,yDAEC,iBAID,oDACC,kBAKH,qCACC,kBACA,iBACA,iBAEA,4CACC,MXrDkB,KWsDlB,kBAGD,0CACC,qBACA,kBACA,YAEA,gDAEC,kBAGD,gDACC,kBACA,UCrEJ,8BACC,oDAIA,oCACC,kBACA,aACA,yBAGA,kDACC,iBACA,iBAEA,0DACC,uBACA,eACA,WdfH,YACC,6JcgBE,kBACA,yBACA,gBACA,iBACA,kBACA,oBAMJ,yBACC,iDCnCD,OACC,aAGD,sBACC,aACA,kBAEA,gCACC,qBAEA,uCACC,aAGD,wCACC,cAKA,+CACC,cAGD,gDACC,aAQH,qCACC,aACA,kBACA,QACA,4BACA,WACA,sBACA,kBACA,YAEA,mCAVD,qCAWE,0BAGD,uDACC,yBACA,cACA,gBACA,mBAGD,0CACC,cCrDH,kCACC,oDAKA,yCACC,kBACA,QACA,gBACA,sBACA,aACA,gBAGD,2CACC,kBACA,WACA,6BACA,ehBhBD,YACC,6JgBmBA,uDACC,kBACA,UACA,YAEA,oEACC,WAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,SAKH,oCACC,kBACA,UAEA,yCACC,YAEA,mDACC,kBACA,uBACA,eACA,YACA,iBhB/DH,YACC,6JgBgEE,iBAGD,mDACC,kBACA,YACA,YACA,WACA,gBACA,gCACA,gGC7EH,gEACC,eAMD,2CACC,uBACA,iBAGD,iDACC,kBACA,SACA,sBACA,aACA,gBAGD,qDACC,kBACA,uBACA,eACA,iBACA,WACA,yBACA,kBjBzBD,YACC,6JiB2BA,kEACC,aACA,cACA,sBAGD,kEACC,mBACA,uBACA,sBACA,kBCzCF,kCACC,uBACA,iBAGD,wCACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,0CACC,kBAEA,qDACC,aACA,sBACA,cACA,aACA,sBACA,8BAGD,iDACC,aACA,gBAGD,oDACC,uBACA,eACA,iBACA,WACA,yBlBjCF,YACC,6JkBkCC,kBAGD,iDACC,uBACA,eACA,iBACA,WlB1CF,YACC,6JkB2CC,gBCiBH,WACE,kBACA,gBACA,kBAMA,sBACE,kBACA,UACA,wBACA,mBAEA,OACE,4DASJ,2DAEE,WACA,kBACA,QACA,oBACA,UAGF,8BACE,WACE,8JAQF,6BACA,mBACA,sBAMF,6BACE,WACE,wKAQF,4BACA,mBACA,sBAMF,mCAEE,cACA,oBACA,WACA,kBACA,OACA,QAGF,kBACE,sCACA,mBACA,WA/IS,eAgJT,QA5IW,IAwCX,sCA2GF,iBACE,MACA,SACA,QAzJW,WA0JX,2NArHA,eAsBJ,WA6GE,WACE,kEAaF,sCACE,YAGF,4CACE,OACE,4DAKF,wBASF,gNAWE,YACE,wDASN,oBACE,GACE,sCAIJ,qBACE,GACE","sourcesContent":["@use 'shared/_utils'as u;\n@use 'shared/_colors'as c;\n\n@font-face {\n\tfont-family: \"Star4000\";\n\tsrc: url('../fonts/Star4000.woff') format('woff');\n\tfont-display: swap;\n}\n\nbody {\n\tfont-family: \"Star4000\";\n\tmargin: 0;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t\tcolor: white;\n\t}\n\n\ta {\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tcolor: lightblue;\n\t\t}\n\t}\n\n\t&.kiosk {\n\t\tmargin: 0px;\n\t\tpadding: 0px;\n\t\toverflow: hidden;\n\t\twidth: 100vw;\n\t\t// Always use black background in kiosk mode, regardless of light/dark preference\n\t\tbackground-color: #000000 !important;\n\t}\n}\n\n#divQuery {\n\tmax-width: 640px;\n\tpadding: 8px;\n\n\t.buttons {\n\t\tdisplay: inline-block;\n\t\twidth: 150px;\n\t\ttext-align: right;\n\n\t\t#imgGetGps {\n\t\t\theight: 13px;\n\t\t\tvertical-align: middle;\n\t\t}\n\n\t\tbutton {\n\t\t\tfont-size: 16pt;\n\t\t\tborder: 1px solid darkgray;\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbackground-color: #000000;\n\t\t\t\tcolor: white;\n\t\t\t}\n\n\t\t}\n\n\t\t#btnGetGps {\n\t\t\timg {\n\n\t\t\t\t&.dark {\n\t\t\t\t\tdisplay: none;\n\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t&.light {\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t&.active {\n\t\t\t\tbackground-color: black;\n\n\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\tbackground-color: white;\n\t\t\t\t}\n\n\t\t\t\timg {\n\t\t\t\t\tfilter: invert(1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinput,\n\tbutton {\n\t\tfont-family: \"Star4000\";\n\t}\n\n\t#txtLocation {\n\t\twidth: calc(100% - 170px);\n\t\tmax-width: 490px;\n\t\tfont-size: 16pt;\n\t\tmin-width: 200px;\n\t\tdisplay: inline-block;\n\n\t\t// Ensure consistent styling across light and dark modes\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t\tborder: 2px inset #808080;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #000000;\n\t\t\tcolor: white;\n\t\t\tborder: 2px inset #808080;\n\t\t}\n\t}\n\n\n}\n\n.autocomplete-suggestions {\n\tbackground-color: #ffffff;\n\tborder: 1px solid #000000;\n\tposition: absolute;\n\tz-index: 9999;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t}\n\n\tdiv {\n\t\t/*padding: 2px 5px;*/\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\tfont-size: 16pt;\n\n\t\t&.selected {\n\t\t\tbackground-color: #0000ff;\n\t\t\tcolor: #ffffff;\n\t\t}\n\t}\n\n}\n\n#divTwc {\n\tdisplay: block;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\twidth: 100%;\n\tmax-width: 640px;\n\tmargin: 0; // Ensure edge-to-edge display\n\n\t&.wide {\n\t\tmax-width: 854px;\n\t}\n}\n\n.content-wrapper {\n\tpadding: 8px;\n}\n\n#divTwcMain {\n\twidth: 640px;\n\theight: 480px;\n\tposition: relative;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n}\n\n.kiosk #divTwc {\n\tmax-width: unset;\n}\n\n#divTwcLeft {\n\tdisplay: none;\n\ttext-align: right;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcLeft>div {\n\tflex: 1;\n\tpadding-right: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcRight {\n\ttext-align: left;\n\tdisplay: none;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcRight>div {\n\tflex: 1;\n\tpadding-left: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcBottom {\n\t/* visibility: hidden; */\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\n\tcolor: #ffffff;\n\twidth: 640px;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: rgb(48, 48, 48);\n\t}\n\n}\n\n#divTwcBottom>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\n\t// Use font-size scaling instead of zoom/transform to avoid layout gaps and preserve icon tap targets.\n\t// While not semantically ideal, it works well for our fixed-layout design.\n\t@media (max-width: 550px) {\n\t\tfont-size: 0.90em;\n\t}\n\n\t@media (max-width: 500px) {\n\t\tfont-size: 0.80em;\n\t}\n\n\t@media (max-width: 450px) {\n\t\tfont-size: 0.70em;\n\t}\n\n\t@media (max-width: 400px) {\n\t\tfont-size: 0.60em;\n\t}\n\n\t@media (max-width: 350px) {\n\t\tfont-size: 0.50em;\n\t}\n}\n\n#divTwcBottomLeft {\n\tflex: 1;\n\ttext-align: left;\n\n}\n\n#divTwcBottomMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcBottomRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#divTwcNavContainer {\n\tdisplay: none;\n}\n\n#divTwcNav {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\tmax-width: 640px;\n}\n\n#divTwcNav>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n}\n\n#divTwcNavLeft {\n\tflex: 1;\n\ttext-align: left;\n}\n\n#divTwcNavMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcNavRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#imgPause1x {\n\tvisibility: hidden;\n\tposition: absolute;\n}\n\n.HideCursor {\n\tcursor: none !important;\n}\n\n#txtScrollText {\n\twidth: 475px;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Extended';\n\tsrc: url('../fonts/Star4000 Extended.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Large';\n\tsrc: url('../fonts/Star4000 Large.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Small';\n\tsrc: url('../fonts/Star4000 Small.woff') format('woff');\n\tfont-display: swap;\n}\n\n#display {\n\tfont-family: \"Star4000\";\n\tmargin: 0 0 0 0;\n\twidth: 100%;\n}\n\n#container {\n\tposition: relative;\n\twidth: 640px;\n\theight: 480px;\n\t// overflow: hidden;\n\tbackground-image: url(../images/backgrounds/1.png);\n\ttransform-origin: 0 0;\n\tbackground-repeat: no-repeat;\n}\n\n.wide #container {\n\tpadding-left: 107px;\n\tpadding-right: 107px;\n\tbackground: url(../images/backgrounds/1-wide.png);\n\tbackground-repeat: no-repeat;\n}\n\n#divTwc:fullscreen #container,\n.kiosk #divTwc #container {\n\t// background-image: none;\n\twidth: unset;\n\theight: unset;\n}\n\n#loading {\n\twidth: 640px;\n\theight: 480px;\n\tmax-width: 100%;\n\ttext-shadow: 4px 4px black;\n\tdisplay: flex;\n\talign-items: center;\n\ttext-align: center;\n\tjustify-content: center;\n\n\t.title {\n\t\tfont-family: Star4000 Large;\n\t\tfont-size: 36px;\n\t\tcolor: yellow;\n\t\tmargin-bottom: 0px;\n\t}\n\n\t.version {\n\t\tmargin-bottom: 35px;\n\t}\n\n\t.instructions {\n\t\tfont-size: 18pt;\n\t}\n}\n\n.heading {\n\tfont-weight: bold;\n\tmargin-top: 15px;\n}\n\n#settings {\n\tmargin-bottom: 15px;\n}\n\n#enabledDisplays,\n#settings {\n\tmargin-bottom: 15px;\n\t@include u.status-colors();\n\n\t.press-here {\n\t\tcolor: white;\n\t}\n\n\t@media (prefers-color-scheme: light) {\n\n\t\t.loading,\n\t\t.retrying {\n\t\t\tcolor: hsl(60, 100%, 30%);\n\t\t}\n\n\t\t.press-here {\n\t\t\tcolor: black;\n\t\t\tcursor: pointer;\n\t\t}\n\n\t\t.failed {\n\t\t\tcolor: hsl(0, 100%, 30%);\n\t\t}\n\n\t\t.no-data {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\n\t\t.disabled {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\t}\n\n\tlabel {\n\t\tdisplay: block;\n\t\tmax-width: fit-content;\n\t\tcursor: pointer;\n\n\t\t.alert {\n\t\t\tdisplay: none;\n\n\t\t\t&.show {\n\t\t\t\tdisplay: inline;\n\t\t\t\tcolor: red;\n\t\t\t}\n\t\t}\n\t}\n}\n\n#divTwcBottom img {\n\ttransform: scale(0.75);\n\n\t// Make icons larger in widescreen mode on mobile\n\t@media (max-width: 550px) {\n\t\t.wide & {\n\t\t\ttransform: scale(1.0); // Larger icons in widescreen\n\t\t}\n\t}\n}\n\n#divTwc:fullscreen,\n.kiosk #divTwc {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\talign-content: center;\n\n\t&.no-cursor {\n\t\tcursor: none;\n\t}\n}\n\n#divTwc:fullscreen #display,\n.kiosk #divTwc #display {\n\tposition: relative;\n}\n\n#divTwc:fullscreen #divTwcBottom,\n.kiosk #divTwc #divTwcBottom {\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: rgb(0 0 0 / 0.5);\n\tcolor: #ffffff;\n\twidth: 100%;\n\tposition: absolute;\n\tbottom: 0px;\n}\n\n.kiosk {\n\t#divTwc #divTwcBottom {\n\t\tdisplay: none;\n\t}\n}\n\n.navButton {\n\tcursor: pointer;\n}\n\n#ToggleScanlines {\n\tdisplay: inline-block;\n\n\t.on {\n\t\tdisplay: none;\n\t}\n\n\t.off {\n\t\tdisplay: inline-block;\n\t}\n\n\n\t&.on {\n\t\t.on {\n\t\t\tdisplay: inline-block;\n\t\t}\n\n\t\t.off {\n\t\t\tdisplay: none;\n\t\t}\n\n\t}\n}\n\n.visible {\n\tvisibility: visible;\n\topacity: 1;\n\ttransition: opacity 0.1s linear;\n}\n\n#divTwc:fullscreen .hidden {\n\tvisibility: hidden;\n\topacity: 0;\n\ttransition: visibility 0s 1s, opacity 1s linear\n}\n\n.github-links {\n\twidth: 610px;\n\tmax-width: calc(100vw - 30px);\n\tdisplay: flex;\n\tjustify-content: space-evenly;\n\tflex-wrap: wrap;\n\n\tspan {\n\t\ta {\n\t\t\ttext-decoration: none;\n\t\t\toutline: 0\n\t\t}\n\n\t\t.widget {\n\t\t\tdisplay: inline-block;\n\t\t\toverflow: hidden;\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;\n\t\t\tfont-size: 0;\n\t\t\tline-height: 0;\n\t\t\twhite-space: nowrap\n\t\t}\n\n\t\t.btn,\n\t\t.social-count {\n\t\t\tposition: relative;\n\t\t\tdisplay: inline-block;\n\t\t\tdisplay: inline-flex;\n\t\t\theight: 14px;\n\t\t\tpadding: 2px 5px;\n\t\t\tfont-size: 11px;\n\t\t\tfont-weight: 600;\n\t\t\tline-height: 14px;\n\t\t\tvertical-align: bottom;\n\t\t\tcursor: pointer;\n\t\t\t-webkit-user-select: none;\n\t\t\t-moz-user-select: none;\n\t\t\t-ms-user-select: none;\n\t\t\tuser-select: none;\n\t\t\tbackground-repeat: repeat-x;\n\t\t\tbackground-position: -1px -1px;\n\t\t\tbackground-size: 110% 110%;\n\t\t\tborder: 1px solid\n\t\t}\n\n\t\t.btn {\n\t\t\tborder-radius: .25em\n\t\t}\n\n\t\t.btn:not(:last-child) {\n\t\t\tborder-radius: .25em 0 0 .25em\n\t\t}\n\n\t\t.social-count {\n\t\t\tborder-left: 0;\n\t\t\tborder-radius: 0 .25em .25em 0\n\t\t}\n\n\t\t.widget-lg .btn,\n\t\t.widget-lg .social-count {\n\t\t\theight: 16px;\n\t\t\tpadding: 5px 10px;\n\t\t\tfont-size: 12px;\n\t\t\tline-height: 16px\n\t\t}\n\n\t\t.octicon {\n\t\t\tdisplay: inline-block;\n\t\t\tvertical-align: text-top;\n\t\t\tfill: currentColor;\n\t\t\toverflow: visible\n\t\t}\n\n\t\t.btn:focus-visible,\n\t\t.social-count:focus-visible {\n\t\t\toutline: 2px solid #0969da;\n\t\t\toutline-offset: -2px\n\t\t}\n\n\t\t.btn {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #ebf0f4;\n\t\t\tborder-color: #ccd1d5;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t}\n\n\t\t:root .btn {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:hover,\n\t\t.btn:focus {\n\t\t\tbackground-color: #e9ebef;\n\t\t\tbackground-position: 0 -0.5em;\n\t\t\tborder-color: #caccd1;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t}\n\n\t\t:root .btn:hover,\n\t\t:root .btn:focus {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:active {\n\t\t\tbackground-color: #e5e9ed;\n\t\t\tborder-color: #c7cbcf;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\tbackground-image: none;\n\t\t\tfilter: none\n\t\t}\n\n\t\t.social-count {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #fff;\n\t\t\tborder-color: #ddddde;\n\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t}\n\n\t\t.social-count:hover,\n\t\t.social-count:focus {\n\t\t\tcolor: #0969da\n\t\t}\n\n\t\t.octicon-heart {\n\t\t\tcolor: #bf3989\n\t\t}\n\n\t\t@media(prefers-color-scheme:light) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #0969da;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #ebf0f4;\n\t\t\t\tborder-color: #ccd1d5;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #e9ebef;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #caccd1;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #e5e9ed;\n\t\t\t\tborder-color: #c7cbcf;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #fff;\n\t\t\t\tborder-color: #ddddde;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #0969da\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #bf3989\n\t\t\t}\n\t\t}\n\n\t\t@media(prefers-color-scheme:dark) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #58a6ff;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #1a1e23;\n\t\t\t\tborder-color: #2f3439;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #21262d, #1a1e23 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #21262d, #1a1e23 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #292e33;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #30363d, #292e33 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #30363d, #292e33 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #161719;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(1, 4, 9, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #0d1117;\n\t\t\t\tborder-color: #24282e;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #58a6ff\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #db61a2\n\t\t\t}\n\t\t}\n\t}\n}\n\n#share-link-copied {\n\tcolor: hsl(60, 100%, 30%);\n\tdisplay: none;\n}\n\n#share-link-instructions {\n\tdisplay: none;\n}\n\n// Hide instructions in kiosk mode (higher specificity than the show rule)\nbody.kiosk #loading .instructions {\n\tdisplay: none !important;\n}\n\n.kiosk {\n\n\t// In kiosk mode, hide everything except the main weather display\n\t>*:not(#divTwc) {\n\t\tdisplay: none !important;\n\t}\n}\n\n#divInfo {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr;\n\tmax-width: 250px;\n}","@use 'colors'as c;\n\n@mixin text-shadow($offset: 3px, $outline: 1.5px) {\n\t/* eventually, when chrome supports paint-order for html elements */\n\t/* -webkit-text-stroke: 2px black; */\n\t/* paint-order: stroke fill; */\n\ttext-shadow:\n\t\t$offset $offset 0 c.$text-shadow,\n\t\t(-$outline) (-$outline) 0 c.$text-shadow,\n\t\t0 (-$outline) 0 c.$text-shadow,\n\t\t$outline (-$outline) 0 c.$text-shadow,\n\t\t$outline 0 0 c.$text-shadow,\n\t\t$outline $outline 0 c.$text-shadow,\n\t\t0 $outline 0 c.$text-shadow,\n\t\t(-$outline) $outline 0 c.$text-shadow,\n\t\t(-$outline) 0 0 c.$text-shadow;\n}\n\n@mixin status-colors() {\n\n\t.loading,\n\t.retrying {\n\t\tcolor: #ffff00;\n\t}\n\n\t.press-here {\n\t\tcolor: #00ff00;\n\t\tcursor: pointer;\n\t}\n\n\t.failed {\n\t\tcolor: #ff0000;\n\t}\n\n\t.no-data {\n\t\tcolor: #C0C0C0;\n\t}\n\n\t.disabled {\n\t\tcolor: #C0C0C0;\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display {\n\twidth: 640px;\n\theight: 480px;\n\toverflow: hidden;\n\tposition: relative;\n\tbackground-image: url(../images/backgrounds/1.png);\n\n\t/* this method is required to hide blocks so they can be measured while off screen */\n\theight: 0px;\n\n\t&.show {\n\t\theight: 480px;\n\t}\n\n\t.template {\n\t\tdisplay: none;\n\t}\n\n\t.header {\n\t\twidth: 640px;\n\t\theight: 60px;\n\t\tpadding-top: 30px;\n\n\t\t.title {\n\t\t\tcolor: c.$title-color;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\t\t\tposition: absolute;\n\t\t\twidth: 250px;\n\n\t\t\t&.single {\n\t\t\t\tleft: 170px;\n\t\t\t\ttop: 25px;\n\t\t\t}\n\n\t\t\t&.dual {\n\t\t\t\tleft: 170px;\n\n\t\t\t\t&>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t}\n\n\t\t\t\t.top {\n\t\t\t\t\ttop: -3px;\n\t\t\t\t}\n\n\t\t\t\t.bottom {\n\t\t\t\t\ttop: 26px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t.logo {\n\t\t\ttop: 30px;\n\t\t\tleft: 50px;\n\t\t\tposition: absolute;\n\t\t\tz-index: 10;\n\t\t}\n\n\t\t.noaa-logo {\n\t\t\tposition: absolute;\n\t\t\ttop: 39px;\n\t\t\tleft: 356px;\n\t\t}\n\n\t\t.title.single {\n\t\t\ttop: 40px;\n\t\t}\n\n\t\t.date-time {\n\t\t\twhite-space: pre;\n\t\t\tcolor: c.$date-time;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tleft: 415px;\n\t\t\twidth: 170px;\n\t\t\ttext-align: right;\n\t\t\tposition: absolute;\n\n\t\t\t&.date {\n\t\t\t\tpadding-top: 22px;\n\t\t\t}\n\t\t}\n\t}\n\n\t.main {\n\t\tposition: relative;\n\n\t\t&.has-scroll {\n\t\t\twidth: 640px;\n\t\t\tmargin-top: 0;\n\t\t\theight: 310px;\n\t\t\toverflow: hidden;\n\n\t\t\t&.no-header {\n\t\t\t\theight: 400px;\n\t\t\t\tmargin-top: 0; // Reset for no-header case since the gap issue is header-related\n\t\t\t}\n\t\t}\n\n\t\t&.has-box {\n\t\t\tmargin-left: 64px;\n\t\t\tmargin-right: 64px;\n\t\t\twidth: calc(100% - 128px);\n\t\t}\n\n\t}\n\n}\n\n#container>.scroll {\n\tdisplay: none;\n\t@include u.text-shadow(3px, 1.5px);\n\twidth: 640px;\n\theight: 77px;\n\toverflow: hidden;\n\tmargin-top: 3px;\n\tposition: absolute;\n\tbottom: 0px;\n\tz-index: 1;\n\n\t&.hazard {\n\t\tbackground-color: rgb(112, 35, 35);\n\t}\n\n\t.scroll-container {\n\t\twidth: 640px;\n\n\t\t.fixed,\n\t\t.scroll-header {\n\t\t\tmargin-left: 55px;\n\t\t\tmargin-right: 55px;\n\t\t\toverflow: hidden;\n\t\t\twhite-space: nowrap;\n\t\t}\n\n\t\t.scroll-header {\n\t\t\theight: 26px;\n\t\t\tfont-family: \"Star4000 Small\";\n\t\t\tfont-size: 20pt;\n\t\t\tmargin-top: -10px;\n\t\t}\n\n\t\t.fixed {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\n\t\t\t.scroll-area {\n\t\t\t\ttext-wrap: nowrap;\n\t\t\t\tposition: relative;\n\t\t\t\t// the following added by js code as it is dependent on the content of the element\n\t\t\t\t// transition: left (x)s;\n\t\t\t\t// left: calc((elem width) - 640px);\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n\n.wide #container>.scroll {\n\twidth: 854px;\n\tmargin-left: -107px;\n\n\t.scroll-container {\n\t\tmargin-left: 107px;\n\t}\n}","$title-color: yellow;\n$date-time: white;\n$text-shadow: black;\n$column-header-text: yellow;\n$column-header: rgb(32, 0, 87);\n\n$gradient-main-background-1: #102080;\n$gradient-main-background-2: #001040;\n\n$gradient-loading-1: #09246f;\n$gradient-loading-2: #364ac0;\n$gradient-loading-3: #4f99f9;\n$gradient-loading-4: #8ffdfa;\n\n$extended-low: #8080FF;\n\n$blue-box: #26235a;","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.current-weather {\n\t&.main {\n\n\t\t.col {\n\t\t\theight: 50px;\n\t\t\twidth: 255px;\n\t\t\tdisplay: inline-block;\n\t\t\tmargin-top: 10px;\n\t\t\tpadding-top: 10px;\n\t\t\tposition: absolute;\n\n\t\t\t@include u.text-shadow();\n\n\t\t\t&.left {\n\t\t\t\tfont-family: 'Star4000 Extended';\n\t\t\t\tfont-size: 24pt;\n\n\t\t\t}\n\n\t\t\t&.right {\n\t\t\t\tright: 0px;\n\t\t\t\tfont-family: \"Star4000 Large\";\n\t\t\t\tfont-size: 20px;\n\t\t\t\tfont-weight: bold;\n\t\t\t\tline-height: 24px;\n\n\t\t\t\t.row {\n\t\t\t\t\tmargin-bottom: 12px;\n\n\t\t\t\t\t.label,\n\t\t\t\t\t.value {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\n\t\t\t\t\t.label {\n\t\t\t\t\t\tmargin-left: 20px;\n\t\t\t\t\t}\n\n\t\t\t\t\t.value {\n\t\t\t\t\t\tfloat: right;\n\t\t\t\t\t\tmargin-right: 10px;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\t.center {\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000 Large';\n\t\t\tfont-size: 24pt;\n\t\t}\n\n\t\t.icon {\n\t\t\timg {\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tdisplay: block;\n\t\t\t}\n\t\t}\n\n\t\t.wind-container {\n\t\t\tmargin-left: 10px;\n\t\t\tdisplay: flex;\n\n\t\t\t&>div {\n\t\t\t\twidth: 50%;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\ttext-align: right;\n\t\t\t}\n\t\t}\n\n\t\t.wind-gusts {\n\t\t\ttext-align: right;\n\t\t\tfont-size: 28px;\n\t\t}\n\n\t\t.location {\n\t\t\tcolor: c.$title-color;\n\t\t\tmax-height: 32px;\n\t\t\tmargin-bottom: 10px;\n\t\t\tpadding-top: 4px;\n\t\t\toverflow: hidden;\n\t\t\ttext-wrap: nowrap;\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#extended-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/2.png');\n}\n\n.weather-display .main.extended-forecast {\n\t.day-container {\n\t\tmargin-top: 16px;\n\t\tmargin-left: 27px;\n\t}\n\n\t.day {\n\t\t@include u.text-shadow();\n\t\tpadding: 5px;\n\t\theight: 285px;\n\t\twidth: 155px;\n\t\tdisplay: inline-block;\n\t\tmargin: 0px 15px;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\n\t\t.date {\n\t\t\ttext-transform: uppercase;\n\t\t\ttext-align: center;\n\t\t\tcolor: c.$title-color;\n\t\t}\n\n\t\t.condition {\n\t\t\ttext-align: center;\n\t\t\theight: 74px;\n\t\t\tmargin-top: 5px;\n\t\t}\n\n\t\t.icon {\n\t\t\ttext-align: center;\n\t\t\theight: 75px;\n\n\t\t\timg {\n\t\t\t\tmax-height: 75px;\n\t\t\t}\n\t\t}\n\n\t\t.temperatures {\n\t\t\twidth: 100%;\n\n\t\t\t.temperature-block {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 44%;\n\t\t\t\tvertical-align: top;\n\n\t\t\t\t>div {\n\t\t\t\t\ttext-align: center;\n\t\t\t\t}\n\n\t\t\t\t.value {\n\t\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\t\tmargin-top: 4px;\n\t\t\t\t}\n\n\t\t\t\t&.lo .label {\n\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t}\n\n\t\t\t\t&.hi .label {\n\t\t\t\t\tcolor: c.$title-color;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .main.hourly {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\t\t.hourly-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\tbackground: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px,\n\t\t\t\t\tc.$gradient-main-background-1 136px,\n\t\t\t\t\tc.$gradient-main-background-1 202px,\n\t\t\t\t\tc.$gradient-main-background-2 338px,\n\t\t\t\t);\n\n\t\t\t.hourly-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.hour {\n\t\t\t\t\tleft: 25px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 255px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\tleft: 355px;\n\t\t\t\t}\n\n\t\t\t\t.like {\n\t\t\t\t\tleft: 425px;\n\n\t\t\t\t\t&.heat-index {\n\t\t\t\t\t\tcolor: #e00;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.wind-chill {\n\t\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\tleft: 505px;\n\t\t\t\t\twidth: 100px;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hourly-graph-html {\n\tbackground-image: url(../images/backgrounds/1-chart.png);\n\n\t.header {\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\ttop: 35px;\n\t\t\tright: 60px;\n\t\t\twidth: 360px;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 28px;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: right;\n\n\t\t\tdiv {\n\t\t\t\tmargin-top: -18px;\n\t\t\t}\n\n\t\t\t.temperature {\n\t\t\t\tcolor: red;\n\t\t\t}\n\n\t\t\t.dewpoint {\n\t\t\t\tcolor: green;\n\t\t\t}\n\n\t\t\t.cloud {\n\t\t\t\tcolor: lightgrey;\n\t\t\t}\n\n\t\t\t.rain {\n\t\t\t\tcolor: aqua;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.hourly-graph {\n\n\t&.main {\n\t\t>div {\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.label {\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\tcolor: c.$column-header-text;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-top: -15px;\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.x-axis {\n\t\t\tbottom: 0px;\n\t\t\tleft: 54px;\n\t\t\twidth: 532px;\n\t\t\theight: 20px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: center;\n\t\t\t\ttransform: translateX(-50%);\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\tleft: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\tleft: calc(532px / 4 * 1);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tleft: calc(532px / 4 * 2);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tleft: calc(532px / 4 * 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-5 {\n\t\t\t\t\tleft: calc(532px / 4 * 4);\n\t\t\t\t}\n\t\t\t}\n\n\n\n\t\t}\n\n\t\t.chart {\n\t\t\ttop: 0px;\n\t\t\tleft: 50px;\n\n\t\t\timg {\n\t\t\t\twidth: 532px;\n\t\t\t\theight: 285px;\n\t\t\t}\n\t\t}\n\n\t\t.y-axis {\n\t\t\ttop: 0px;\n\t\t\tleft: 0px;\n\t\t\twidth: 50px;\n\t\t\theight: 285px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\ttop: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\ttop: calc(280px / 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tbottom: calc(280px / 3 - 11px);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tbottom: 0px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.travel {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\twidth: 100%;\n\t\t\tz-index: 5;\n\t\t\toverflow: hidden; // prevent thin gaps between header and content\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\twidth: 50px;\n\t\t\t\ttext-align: center;\n\n\t\t\t\t&.low {\n\t\t\t\t\tleft: 455px;\n\n\t\t\t\t}\n\n\t\t\t\t&.high {\n\t\t\t\t\tleft: 510px;\n\t\t\t\t\twidth: 60px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.travel-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\tbackground: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px,\n\t\t\t\t\tc.$gradient-main-background-1 136px,\n\t\t\t\t\tc.$gradient-main-background-1 202px,\n\t\t\t\t\tc.$gradient-main-background-2 338px,\n\t\t\t\t);\n\n\t\t\t.travel-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.city {\n\t\t\t\t\tleft: 80px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 330px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\n\t\t\t\t\timg {\n\t\t\t\t\t\tmax-width: 47px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\twidth: 50px;\n\t\t\t\t\ttext-align: center;\n\n\t\t\t\t\t&.low {\n\t\t\t\t\t\tleft: 455px;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.high {\n\t\t\t\t\t\tleft: 510px;\n\t\t\t\t\t\twidth: 60px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .latest-observations {\n\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\ttop: 0px;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\t// hidden initially for english/metric switching\n\t\t\t\tdisplay: none;\n\n\t\t\t\t&.show {\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.temp {\n\t\t\tleft: 230px;\n\t\t}\n\n\t\t.weather {\n\t\t\tleft: 280px;\n\t\t}\n\n\t\t.wind {\n\t\t\tleft: 430px;\n\t\t}\n\n\t\t.observation-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.observation-row {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\t\t\t\theight: 40px;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .local-forecast {\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 280px;\n\t\toverflow: hidden;\n\t}\n\n\t.forecasts {\n\t\tposition: relative;\n\t}\n\n\t.forecast {\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\t\ttext-transform: uppercase;\n\t\t@include u.text-shadow();\n\t\tmin-height: 280px;\n\t\tline-height: 40px;\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .progress {\n\t@include u.text-shadow();\n\tfont-family: 'Star4000 Extended';\n\tfont-size: 18pt;\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 310px;\n\t\toverflow: hidden;\n\t\tline-height: 26px;\n\n\t\t.item {\n\t\t\tposition: relative;\n\n\t\t\t.name {\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&::after {\n\t\t\t\t\tcontent: '........................................................................';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.links {\n\t\t\t\tposition: absolute;\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\t\t\t\ttop: 0px;\n\n\t\t\t\t>div {\n\t\t\t\t\tbackground-color: c.$blue-box;\n\t\t\t\t\tdisplay: none;\n\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t}\n\n\t\t\t\t@include u.status-colors();\n\n\t\t\t\t&.loading .loading,\n\t\t\t\t&.press-here .press-here,\n\t\t\t\t&.failed .failed,\n\t\t\t\t&.no-data .no-data,\n\t\t\t\t&.disabled .disabled,\n\t\t\t\t&.retrying .retrying {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\n}\n\n#progress-html.weather-display .scroll {\n\n\t@keyframes progress-scroll {\n\t\t0% {\n\t\t\tbackground-position: -40px 0;\n\t\t}\n\n\t\t100% {\n\t\t\tbackground-position: 40px 0;\n\t\t}\n\t}\n\n\t.progress-bar-container {\n\t\tborder: 2px solid black;\n\t\tbackground-color: white;\n\t\tmargin: 20px auto;\n\t\twidth: 524px;\n\t\tposition: relative;\n\t\tdisplay: none;\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t.progress-bar {\n\t\t\theight: 20px;\n\t\t\tmargin: 2px;\n\t\t\twidth: 520px;\n\t\t\tbackground: repeating-linear-gradient(90deg,\n\t\t\t\t\tc.$gradient-loading-1 0px,\n\t\t\t\t\tc.$gradient-loading-1 5px,\n\t\t\t\t\tc.$gradient-loading-2 5px,\n\t\t\t\t\tc.$gradient-loading-2 10px,\n\t\t\t\t\tc.$gradient-loading-3 10px,\n\t\t\t\t\tc.$gradient-loading-3 15px,\n\t\t\t\t\tc.$gradient-loading-4 15px,\n\t\t\t\t\tc.$gradient-loading-4 20px,\n\t\t\t\t\tc.$gradient-loading-3 20px,\n\t\t\t\t\tc.$gradient-loading-3 25px,\n\t\t\t\t\tc.$gradient-loading-2 25px,\n\t\t\t\t\tc.$gradient-loading-2 30px,\n\t\t\t\t\tc.$gradient-loading-1 30px,\n\t\t\t\t\tc.$gradient-loading-1 40px,\n\t\t\t\t);\n\t\t\t// animation\n\t\t\tanimation-duration: 2s;\n\t\t\tanimation-fill-mode: forwards;\n\t\t\tanimation-iteration-count: infinite;\n\t\t\tanimation-name: progress-scroll;\n\t\t\tanimation-timing-function: steps(8, end);\n\t\t}\n\n\t\t.cover {\n\t\t\tposition: absolute;\n\t\t\ttop: 0px;\n\t\t\tright: 0px;\n\t\t\tbackground-color: white;\n\t\t\twidth: 100%;\n\t\t\theight: 24px;\n\t\t\ttransition: width 1s steps(6);\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#radar-html.weather-display {\n\tbackground-image: url('../images/backgrounds/4.png');\n\n\t.header {\n\t\theight: 83px;\n\n\t\t.title.dual {\n\t\t\tcolor: white;\n\t\t\tfont-family: 'Arial', sans-serif;\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 28pt;\n\t\t\tleft: 155px;\n\n\t\t\t.top {\n\t\t\t\ttop: -4px;\n\t\t\t}\n\n\t\t\t.bottom {\n\t\t\t\ttop: 31px;\n\t\t\t}\n\t\t}\n\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\tright: 0px;\n\t\t\twidth: 360px;\n\t\t\tmargin-top: 2px;\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 18pt;\n\t\t\tfont-weight: bold;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: center;\n\n\t\t\t.scale>div {\n\t\t\t\tdisplay: inline-block;\n\t\t\t}\n\n\t\t\t.scale-table {\n\t\t\t\tdisplay: table-row;\n\t\t\t\tborder-collapse: collapse;\n\n\t\t\t\t.box {\n\t\t\t\t\tdisplay: table-cell;\n\t\t\t\t\tborder: 2px solid black;\n\t\t\t\t\twidth: 17px;\n\t\t\t\t\theight: 24px;\n\t\t\t\t\tpadding: 0\n\t\t\t\t}\n\n\t\t\t\t.box-1 {\n\t\t\t\t\tbackground-color: rgb(49, 210, 22);\n\t\t\t\t}\n\n\t\t\t\t.box-2 {\n\t\t\t\t\tbackground-color: rgb(28, 138, 18);\n\t\t\t\t}\n\n\t\t\t\t.box-3 {\n\t\t\t\t\tbackground-color: rgb(20, 90, 15);\n\t\t\t\t}\n\n\t\t\t\t.box-4 {\n\t\t\t\t\tbackground-color: rgb(10, 40, 10);\n\t\t\t\t}\n\n\t\t\t\t.box-5 {\n\t\t\t\t\tbackground-color: rgb(196, 179, 70);\n\t\t\t\t}\n\n\t\t\t\t.box-6 {\n\t\t\t\t\tbackground-color: rgb(190, 72, 19);\n\t\t\t\t}\n\n\t\t\t\t.box-7 {\n\t\t\t\t\tbackground-color: rgb(171, 14, 14);\n\t\t\t\t}\n\n\t\t\t\t.box-8 {\n\t\t\t\t\tbackground-color: rgb(115, 31, 4);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.scale {\n\t\t\t\t.text {\n\t\t\t\t\tposition: relative;\n\t\t\t\t\ttop: -5px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.time {\n\t\t\t\tposition: relative;\n\t\t\t\tfont-weight: normal;\n\t\t\t\ttop: -14px;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.radar {\n\toverflow: hidden;\n\theight: 367px;\n\n\t.container {\n\n\t\t.tiles {\n\t\t\tposition: absolute;\n\t\t\twidth: 1400px;\n\n\t\t\timg {\n\t\t\t\tvertical-align: middle;\n\t\t\t}\n\t\t}\n\n\t\t.scroll-area {\n\t\t\tposition: relative;\n\t\t}\n\t}\n}\n\n.wide.radar #container {\n\tbackground: url(../images/backgrounds/4-wide.png);\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#regional-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/5.png');\n}\n\n.weather-display .main.regional-forecast {\n\n\n\tposition: relative;\n\n\t.map {\n\t\tposition: absolute;\n\t\ttransform-origin: 0 0;\n\t}\n\n\t.location {\n\t\tposition: absolute;\n\t\twidth: 140px;\n\t\tmargin-left: -40px;\n\t\tmargin-top: -35px;\n\n\t\t>div {\n\t\t\tposition: absolute;\n\t\t\t@include u.text-shadow();\n\t\t}\n\n\t\t.icon {\n\t\t\ttop: 26px;\n\t\t\tleft: 44px;\n\n\t\t\timg {\n\t\t\t\tmax-height: 32px;\n\t\t\t}\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000 Large';\n\t\t\tfont-size: 28px;\n\t\t\tpadding-top: 2px;\n\t\t\tcolor: c.$title-color;\n\t\t\ttop: 28px;\n\t\t\ttext-align: right;\n\t\t\twidth: 40px;\n\t\t}\n\n\t\t.city {\n\t\t\tfont-family: Star4000;\n\t\t\tfont-size: 20px;\n\t\t}\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n#almanac-html.weather-display {\n\tbackground-image: url('../images/backgrounds/3.png');\n}\n\n.weather-display .main.almanac {\n\tfont-family: 'Star4000';\n\tfont-size: 24pt;\n\t@include u.text-shadow();\n\n\t.sun {\n\t\t// Use CSS Grid for cross-browser consistency\n\t\t// Grid is populated in reading order (left-to-right, top-to-bottom):\n\t\tdisplay: grid;\n\t\tgrid-template-columns: auto auto auto;\n\t\tgrid-template-rows: auto auto auto;\n\t\tgap: 0px 90px;\n\t\tmargin: 3px auto 5px auto; // align the bottom of the div with the background\n\t\twidth: fit-content;\n\t\tline-height: 30px;\n\n\t\t.grid-item {\n\t\t\t// Reset inherited styles that interfere with grid layout\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tpadding: 0;\n\t\t\tmargin: 0;\n\t\t\tposition: relative;\n\n\t\t\t// Column headers (day names)\n\t\t\t&.header {\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t// Row labels (Sunrise:, Sunset:)\n\t\t\t&.row-label {\n\t\t\t\t// color: c.$column-header-text; // screenshots show labels were white\n\t\t\t\ttext-align: right;\n\t\t\t}\n\n\t\t\t// Time values (sunrise/sunset)\n\t\t\t&.time {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t}\n\t}\n\n\t.moon {\n\t\tposition: relative;\n\t\tpadding: 7px 50px;\n\t\tline-height: 36px;\n\n\t\t.title {\n\t\t\tcolor: c.$column-header-text;\n\t\t\tpadding-left: 13px;\n\t\t}\n\n\t\t.day {\n\t\t\tdisplay: inline-block;\n\t\t\ttext-align: center;\n\t\t\twidth: 132px;\n\n\t\t\t.icon {\n\t\t\t\t// shadow in image make it look off center\n\t\t\t\tpadding-left: 10px;\n\t\t\t}\n\n\t\t\t.date {\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -10px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hazards-html.weather-display {\n\tbackground-image: url('../images/backgrounds/7.png');\n}\n\n.weather-display .main.hazards {\n\t&.main {\n\t\toverflow-y: hidden;\n\t\theight: 480px;\n\t\tbackground-color: rgb(112, 35, 35);\n\n\n\t\t.hazard-lines {\n\t\t\tmin-height: 400px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.hazard {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: white;\n\t\t\t\t@include u.text-shadow(0px);\n\t\t\t\tposition: relative;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\tmargin-left: 80px;\n\t\t\t\tmargin-right: 80px;\n\t\t\t\tpadding-bottom: 10px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.wide.hazards #container {\n\tbackground: url(../images/backgrounds/7-wide.png);\n}",".media {\n\tdisplay: none;\n}\n\n#ToggleMediaContainer {\n\tdisplay: none;\n\tposition: relative;\n\n\t&.available {\n\t\tdisplay: inline-block;\n\n\t\timg.on {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\timg.off {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t// icon switch is handled by adding/removing the .playing class\n\t\t&.playing {\n\t\t\timg.on {\n\t\t\t\tdisplay: block;\n\t\t\t}\n\n\t\t\timg.off {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\n\t\t}\n\n\n\t}\n\n\t.volume-slider {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\ttop: 0px;\n\t\ttransform: translateY(-100%);\n\t\twidth: 100%;\n\t\tbackground-color: #000;\n\t\ttext-align: center;\n\t\tz-index: 100;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #303030;\n\t\t}\n\n\t\tinput[type=\"range\"] {\n\t\t\twriting-mode: vertical-lr;\n\t\t\tdirection: rtl;\n\t\t\tmargin-top: 20px;\n\t\t\tmargin-bottom: 20px;\n\t\t}\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\t}\n\n\n\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#spc-outlook-html.weather-display {\n\tbackground-image: url('../images/backgrounds/6.png');\n}\n\n.weather-display .spc-outlook {\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 0px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 300px;\n\t\toverflow: hidden;\n\t}\n\n\t.risk-levels {\n\t\tposition: absolute;\n\t\tleft: 206px;\n\t\tfont-family: 'Star4000 Small';\n\t\tfont-size: 32px;\n\t\t@include u.text-shadow();\n\n\n\t\t.risk-level {\n\t\t\tposition: relative;\n\t\t\ttop: -14px;\n\t\t\theight: 20px;\n\n\t\t\t&:nth-child(1) {\n\t\t\t\tleft: calc(20px * 5);\n\t\t\t}\n\n\t\t\t&:nth-child(2) {\n\t\t\t\tleft: calc(20px * 4);\n\t\t\t}\n\n\t\t\t&:nth-child(3) {\n\t\t\t\tleft: calc(20px * 3);\n\t\t\t}\n\n\t\t\t&:nth-child(4) {\n\t\t\t\tleft: calc(20px * 2);\n\t\t\t}\n\n\t\t\t&:nth-child(5) {\n\t\t\t\tleft: calc(20px * 1);\n\t\t\t}\n\n\t\t\t&:nth-child(6) {\n\t\t\t\tleft: calc(20px * 0);\n\t\t\t}\n\t\t}\n\t}\n\n\t.days {\n\t\tposition: absolute;\n\t\ttop: 120px;\n\n\t\t.day {\n\t\t\theight: 60px;\n\n\t\t\t.day-name {\n\t\t\t\tposition: absolute;\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\twidth: 200px;\n\t\t\t\ttext-align: right;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tpadding-top: 20px;\n\t\t\t}\n\n\t\t\t.risk-bar {\n\t\t\t\tposition: absolute;\n\t\t\t\twidth: 150px;\n\t\t\t\theight: 40px;\n\t\t\t\tleft: 210px;\n\t\t\t\tmargin-top: 20px;\n\t\t\t\tborder: 3px outset hsl(0, 0%, 70%);\n\t\t\t\tbackground: linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%);\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#server-observations-html.weather-display {\n\t.header .title.single {\n\t\tfont-size: 20pt;\n\t}\n}\n\n.weather-display .server-observations {\n\t// Override the default has-scroll height to fit content properly\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.server-output {\n\t\tposition: relative;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 20pt;\n\t\tline-height: 32px;\n\t\tcolor: #fff;\n\t\ttext-transform: uppercase;\n\t\ttext-align: center;\n\t\t@include u.text-shadow();\n\n\t\t.server-page {\n\t\t\theight: 250px;\n\t\t\tpadding: 0 8px;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\n\t\t.server-line {\n\t\t\twhite-space: normal;\n\t\t\toverflow-wrap: anywhere;\n\t\t\tword-break: break-word;\n\t\t\tmargin-bottom: 6px;\n\t\t}\n\t}\n}\n","@use 'shared/_utils' as u;\n\n.weather-display .linux-news {\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.news-output {\n\t\tposition: relative;\n\n\t\t.news-page {\n\t\t\theight: 250px;\n\t\t\tbox-sizing: border-box;\n\t\t\tpadding: 0 8px;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tjustify-content: space-between;\n\t\t}\n\n\t\t.story {\n\t\t\theight: 116px;\n\t\t\toverflow: hidden;\n\t\t}\n\n\t\t.headline {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 17pt;\n\t\t\tline-height: 22px;\n\t\t\tcolor: #ff0;\n\t\t\ttext-transform: uppercase;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-bottom: 4px;\n\t\t}\n\n\t\t.blurb {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 14pt;\n\t\t\tline-height: 16px;\n\t\t\tcolor: #fff;\n\t\t\t@include u.text-shadow();\n\t\t\toverflow: hidden;\n\t\t}\n\t}\n}\n","/* =========================================================\n REGULAR SCANLINES SETTINGS\n ========================================================= */\n\n$scan-width: 1px;\n$scan-crt: false;\n$scan-fps: 20;\n$scan-color: rgba(#000, 0.30);\n$scan-z-index: 2147483648;\n\n$scan-moving-line: true;\n$scan-opacity: 0.75;\n\n/* =========================================================\n CRT / S-VIDEO EFFECT SETTINGS\n ========================================================= */\n\n// whole-screen softness\n$crt-soft-blur: 0.45px;\n\n// mild brightening / contrast to keep blur from looking muddy\n$crt-contrast: 1.04;\n$crt-saturation: 1.08;\n$crt-brightness: 0.98;\n\n// fake horizontal chroma bleed\n$crt-r-shift: -0.7px;\n$crt-b-shift: 0.7px;\n$crt-bleed-blur: 1.2px;\n$crt-rgb-opacity: 0.04;\n\n// subtle tube edge darkening\n$crt-vignette-opacity: 0.16;\n\n// optional tiny bloom\n$crt-glow-opacity: 0.05;\n\n/* =========================================================\n MIXINS\n ========================================================= */\n\n@mixin scan-crt($enabled) {\n @if $enabled == true {\n animation: scanlines 1s steps($scan-fps) infinite;\n } @else {\n animation: none;\n }\n}\n\n@mixin scan-moving($enabled) {\n @if $enabled == true {\n animation: scanline 6s linear infinite;\n } @else {\n animation: none;\n }\n}\n\n/* =========================================================\n APPLY TO THE REAL APP CONTAINER\n ========================================================= */\n\n/*\n You can add class=\"scanlines\" to #divTwcMain or #container.\n Example:\n
\n*/\n\n.scanlines {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n\n /*\n This is the actual rendered weather area in your HTML.\n Applying the softness here affects the maps/text/icons themselves.\n */\n #container {\n position: relative;\n z-index: 1;\n transform: translateZ(0);\n will-change: filter;\n\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n }\n\n /*\n Red fringe overlay\n */\n #container::before,\n #container::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n }\n\n #container::before {\n background:\n linear-gradient(\n to right,\n rgba(255, 0, 0, $crt-rgb-opacity) 0%,\n rgba(255, 0, 0, 0.01) 15%,\n rgba(255, 0, 0, 0.00) 50%,\n rgba(255, 0, 0, 0.01) 85%,\n rgba(255, 0, 0, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-r-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Blue fringe overlay\n */\n #container::after {\n background:\n linear-gradient(\n to right,\n rgba(0, 140, 255, $crt-rgb-opacity) 0%,\n rgba(0, 140, 255, 0.01) 15%,\n rgba(0, 140, 255, 0.00) 50%,\n rgba(0, 140, 255, 0.01) 85%,\n rgba(0, 140, 255, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-b-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Moving scanline\n */\n &:before,\n &:after {\n display: block;\n pointer-events: none;\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n }\n\n &:before {\n height: var(--scanline-thickness, $scan-width);\n z-index: $scan-z-index + 2;\n background: $scan-color;\n opacity: $scan-opacity;\n @include scan-moving($scan-moving-line);\n }\n\n /*\n Regular scanline mask\n */\n &:after {\n top: 0;\n bottom: 0;\n z-index: $scan-z-index;\n background: repeating-linear-gradient(\n to bottom,\n transparent 0,\n transparent var(--scanline-thickness, $scan-width),\n $scan-color var(--scanline-thickness, $scan-width),\n $scan-color calc(var(--scanline-thickness, $scan-width) * 2)\n );\n @include scan-crt($scan-crt);\n }\n\n /*\n Vignette layer\n Added as an inset shadow so you don't need extra HTML\n */\n box-shadow:\n inset 0 0 80px rgba(0, 0, 0, $crt-vignette-opacity),\n inset 0 0 18px rgba(255, 255, 255, $crt-glow-opacity);\n}\n\n/* =========================================================\n OPTIONAL: only affect active weather panels, not menus\n ========================================================= */\n\n/*\n If the controls / bottom nav get too blurry, move the blur\n from #container to the weather slides only:\n*/\n.scanlines.crt-panels-only {\n #container {\n filter: none;\n }\n\n .weather-display {\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n\n transform: translateZ(0);\n }\n}\n\n/* =========================================================\n OPTIONAL: make text slightly glow like old TV phosphors\n ========================================================= */\n\n.scanlines {\n .header,\n .main,\n .scroll,\n .date-time,\n .city,\n .temp,\n .condition,\n .location,\n .label,\n .value,\n .title {\n text-shadow:\n 0 0 1px rgba(255, 255, 255, 0.18),\n 0 0 2px rgba(255, 255, 255, 0.06);\n }\n}\n\n/* =========================================================\n ANIMATIONS\n ========================================================= */\n\n@keyframes scanline {\n 0% {\n transform: translate3d(0, 200000%, 0);\n }\n}\n\n@keyframes scanlines {\n 0% {\n background-position: 0 50%;\n }\n}\n\n"],"file":"ws.min.css"} \ No newline at end of file diff --git a/session-ses_2a6f.md b/session-ses_2a6f.md new file mode 100644 index 0000000..a57c204 --- /dev/null +++ b/session-ses_2a6f.md @@ -0,0 +1,1863 @@ +# Add fastfetch Server Observations to forecast + +**Session ID:** ses_2a6ff7d92ffeCeb6Vd6u0fTEpn +**Created:** 4/4/2026, 10:58:18 AM +**Updated:** 4/4/2026, 5:01:21 PM + +--- + +## User + +Can you help fix this error with the Server Observations display? It is not showing text now: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'initialCounts') + at ServerObservations.baseCountChange (serverobservations.mjs:132:81) + at ServerObservations.screenIndexChange (serverobservations.mjs:109:8) + at ServerObservations.updateScreenFromBaseCount (weatherdisplay.mjs:322:9) + at ServerObservations.navNext (weatherdisplay.mjs:378:8) + at ServerObservations.showCanvas (weatherdisplay.mjs:217:47) + at loadDisplay (navigation.mjs:283:32) + at displayNavMessage (navigation.mjs:204:44) + at Radar.sendNavDisplayMessage (weatherdisplay.mjs:449:3) + at Radar.updateScreenFromBaseCount (weatherdisplay.mjs:286:9) + at Radar.navNext (weatherdisplay.mjs:378:8)Understand this error +serverobservations.mjs:132 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'initialCounts') + at ServerObservations.baseCountChange (serverobservations.mjs:132:81) + at ServerObservations.screenIndexChange (serverobservations.mjs:109:8) + at ServerObservations.updateScreenFromBaseCount (weatherdisplay.mjs:322:9) + at ServerObservations.navPrev (weatherdisplay.mjs:399:8) + at ServerObservations.showCanvas (weatherdisplay.mjs:218:46) + at loadDisplay (navigation.mjs:282:32) + at displayNavMessage (navigation.mjs:203:48) + at CurrentWeather.sendNavDisplayMessage (weatherdisplay.mjs:449:3) + at CurrentWeather.navPrev (weatherdisplay.mjs:394:10) + at navTo (navigation.mjs:240:64) + +--- + +## Assistant + +I’m tracing the Server Observations lifecycle to see why `scrollTiming` is undefined when navigation enters the display. + +**Tool: read** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +Yes. I understand the failure now. + +**Root cause** + +`ServerObservations` added `screenIndexChange()`, but in `WeatherDisplay.updateScreenFromBaseCount()` that changes the render path: + +```js +if (this.screenIndexChange) { + this.screenIndexChange(this.screenIndex); +} else { + await this.drawCanvas(); +} +``` + +So for Server Observations: + +1. `drawCanvas()` is skipped during navigation +2. `.server-output` never gets populated +3. `setTiming()` never runs +4. `this.scrollTiming` stays `undefined` +5. `baseCountChange()` crashes on `this.scrollTiming.initialCounts` + +That exactly matches your stack trace. + +**Why Hazards works** +Hazards also defines `screenIndexChange()`, but it compensates by overriding `showCanvas()`: + +```js +showCanvas() { + this.drawCanvas(); + super.showCanvas(); +} +``` + +So its content and `scrollTiming` exist before scrolling starts. + +**What needs to change** + +1. Make Server Observations follow the Hazards pattern: + - override `showCanvas()` + - call `this.drawCanvas()` before `super.showCanvas()` + +2. Guard `baseCountChange()` so it no-ops if `this.scrollTiming` is not ready yet + +3. Optionally initialize a safe default in the constructor: + - `this.scrollTiming = { initialCounts: 0, pixelsPerCount: 0 }` + +**Expected fix shape** + +```js +showCanvas() { + this.drawCanvas(); + super.showCanvas(); +} +``` + +and: + +```js +baseCountChange(count) { + if (!this.scrollTiming) return; + ... +} +``` + +**Why the body is blank** +Because `drawCanvas()` is not being called at the point the display becomes active. + +**Plan** +1. Update `serverobservations.mjs` to override `showCanvas()` like Hazards +2. Add a defensive guard in `baseCountChange()` +3. Rebuild and verify the text renders and scrolls + +If you want, I can implement that fix next. + +--- + +## User + +Sure. You may proceed with this fix + +--- + +## Assistant + +I’m patching the Server Observations lifecycle to render before navigation starts and to safely skip scrolling until timing is ready. + +**Tool: apply_patch** + +--- + +## Assistant + +I’ve applied the lifecycle fix. Next I’m rebuilding to verify there are no runtime or lint issues. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Fixed. + +## What changed + +In `server/scripts/modules/serverobservations.mjs` I: + +1. Added a safe default for `this.scrollTiming` +2. Overrode `showCanvas()` so `drawCanvas()` runs before navigation starts +3. Added a guard in `baseCountChange()` so it exits if timing is not ready + +## Why it failed + +`screenIndexChange()` caused `WeatherDisplay` to skip `drawCanvas()` during navigation. That meant: +- `.server-output` was never rendered +- `setTiming()` never ran +- `this.scrollTiming` stayed undefined +- scrolling crashed on `initialCounts` + +## Result + +The Server Observations display should now: +- render its text again +- initialize scroll timing before use +- scroll without throwing the `initialCounts` error + +`npm run lint` and `npm run build` both pass. + +--- + +## User + +The text is visible again, but it does not scroll or show the full output, if we can't scroll could we split it up into multiple screens? + +--- + +## Assistant + +I’m checking how existing multi-screen displays paginate so I can recommend the cleanest approach for Server Observations. + +**Tool: read** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +Yes. Splitting into multiple screens is the cleaner fallback here. + +## What I found + +The current scroll approach is fighting the display lifecycle a bit: +- `ServerObservations` redraws in `showCanvas()` +- scrolling depends on `baseCountChange()` timing state +- this module is really closer to `Local Forecast` than `Hazards` + +`Local Forecast` is a better model here because it: +- renders text blocks +- paginates by container height +- uses normal display navigation instead of continuous scroll animation +- is easier to keep readable on a TV + +## Recommended plan + +Use **multi-screen pagination** instead of scrolling. + +### Behavior +- Page 1: `OS`, `KERNEL`, `UPTIME`, `CPU` +- Page 2: `GPU`, `MEMORY`, `DISK` +- Or use 3-4 lines per page depending on fit + +### Implementation shape +1. Remove the scroll-specific logic from `serverobservations.mjs` + - `calculateScrollTiming` + - `scrollCache` + - `scrollTiming` + - `baseCountChange()` + - `screenIndexChange()` + - custom `showCanvas()` + +2. Convert the parsed server lines into pages + - chunk the `infoLines` array into groups + - recommended: **4 lines per page** + +3. Render pages into a vertically stacked container + - same pattern as `localforecast.mjs` + - set `this.pageHeight = container.offsetHeight` + - set `this.timing.totalScreens = pageCount` + - set `this.timing.delay = new Array(pageCount).fill(1)` + - keep a readable `baseDelay` like `7000` or `9000` + +4. Update `drawCanvas()` + - move the stacked content with `style.top = -this.screenIndex * this.pageHeight` + +### Why this is better +- simpler than animated scrolling +- matches existing project patterns +- better readability for TV viewing +- easier to reason about and maintain + +## Recommendation + +I’d implement: +- **4 lines per page** +- **7 seconds per page** +- centered text layout preserved + +That would likely produce: +- Page 1: `OS`, `KERNEL`, `UPTIME`, `CPU` +- Page 2: `GPU`, `MEMORY`, `DISK` + +If you want, when edit mode is available, I’ll switch Server Observations from scrolling to Local Forecast-style pagination. + +--- + +## User + +Sounds good! You may proceed with this implementation + +--- + +## Assistant + +I’m replacing the scroll-based behavior with Local Forecast-style pagination so the server info shows across multiple readable screens. + +**Tool: apply_patch** + +--- + +## Assistant + +I’ve switched the module logic to pagination. I’m adding the small layout rules needed so each page occupies the content area cleanly. + +**Tool: apply_patch** + +I’ve switched the logic to paging; now I’m updating the layout so each page actually moves and fills the box like Local Forecast. + +**Tool: apply_patch** + +--- + +## Assistant + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Implemented. + +## What changed + +`server/scripts/modules/serverobservations.mjs` +- Removed the scroll-timing approach +- Switched to Local Forecast-style pagination +- Splits server info into pages of 4 lines each +- Sets: + - `this.pageHeight = container.offsetHeight` + - `this.timing.totalScreens = pages.length` + - `this.timing.delay = [1, 1, ...]` +- Moves pages with `outputElem.style.top = -this.screenIndex * this.pageHeight` + +`server/styles/scss/_server-observations.scss` +- Added `position: relative` to `.server-output` +- Added `.server-page { height: 250px; }` so each page fills the display area correctly + +## Result + +Server Observations should now: +- show all system info across multiple screens +- advance like other paginated displays +- avoid the broken scroll behavior entirely + +`npm run lint` and `npm run build` both pass. + +--- + +## User + +Still seems that some of the text gets cut off on the right borders, could we shrink the font a bit to handle this? better? + +--- + +## Assistant + +Yes. Shrinking the font is the right next step. + +## What I’d change + +In `server/styles/scss/_server-observations.scss`: + +1. Reduce `.server-output` font size +- from `22pt` +- to `20pt` first + +2. Tighten line height slightly +- from `36px` +- to `32px` or `34px` + +3. Optionally add a little inner horizontal padding +- so long lines don’t visually kiss the box edge +- something like `padding: 0 8px;` on `.server-output` or `.server-page` + +## Recommended first pass + +I’d try this minimal adjustment: + +```scss +.server-output { + font-size: 20pt; + line-height: 32px; +} +``` + +If that still clips, second pass: + +```scss +.server-output { + font-size: 19pt; + line-height: 30px; +} + +.server-page { + padding: 0 8px; + box-sizing: border-box; +} +``` + +## Why this is the best approach + +- minimal visual change +- keeps TV readability +- avoids reworking pagination logic +- likely fixes CPU and disk lines getting clipped on the right edge + +If you want, once edit mode is available, I’d implement the `20pt / 32px` version first. + +--- + +## User + +Sure, you can proceed with these changes + +--- + +## Assistant + +I’m making a small typography adjustment to the Server Observations slide and rebuilding so we can verify the fit improvement. + +**Tool: apply_patch** + +--- + +## Assistant + +The SCSS is updated. I’m rebuilding the CSS output used by the dev server now. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Adjusted. + +## Changes +In `server/styles/scss/_server-observations.scss`: +- `font-size`: `22pt` → `20pt` +- `line-height`: `36px` → `32px` +- added page padding: + - `padding: 0 8px` + - `box-sizing: border-box` + +## Result +This gives each page a bit more horizontal breathing room and should reduce right-edge clipping without changing the overall layout much. + +`npm run lint` and `npm run build` both pass. + +--- + +## User + +This is better, still seems that the long CPU and kernel names are being cut off though + +--- + +## Assistant + +Yes. The remaining clipping is likely from a combination of: + +1. `white-space: nowrap` on `.server-line` +2. centered text +3. very long single-line values like `KERNEL` and `CPU` + +That means even with a smaller font, those lines still have no way to wrap. + +## Best fix + +Keep the page-based layout, but let long lines wrap cleanly. + +### Recommended changes +1. Allow wrapping on `.server-line` +- remove `white-space: nowrap` +- remove `text-overflow: ellipsis` +- use normal wrapping + +2. Keep the label/value readable +- likely reduce font one more step if needed: `19pt` +- slightly tighter line height if needed: `30px` + +3. Give pages a little more inner width control +- keep the horizontal padding +- possibly increase to `10px` or `12px` + +## Why this is better than shrinking again +Just shrinking the font keeps the root problem: +- long strings still must fit on one line + +Wrapping fixes the actual issue and should make: +- `Kernel: Linux 7.0.0-rc5-...` +- `CPU: 12th Gen Intel...` + +fit naturally over two lines when necessary. + +## Suggested plan +1. Update `.server-line` to wrap instead of truncate +2. If needed, reduce font from `20pt` to `19pt` +3. Recheck how many lines fit per page +4. If wrapping increases page height too much, reduce `LINES_PER_PAGE` from `4` to `3` + +## Recommendation +I’d try this order: +1. enable wrapping first +2. only then reduce font to `19pt` if needed +3. if pages become too tall, reduce to 3 lines per page + +If you want, once edit mode is available, I’d implement that exact sequence. + +--- + +## User + +That sounds good, lets try enabling wrapping + +--- + +## Assistant + +I’m updating the Server Observations text to wrap instead of truncating, then I’ll rebuild to verify the layout still works. + +**Tool: apply_patch** + +--- + +## Assistant + +The wrapping change is in. I’m rebuilding assets so the dev-served CSS picks it up. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Updated. + +## Change made +In `server/styles/scss/_server-observations.scss`, `.server-line` now wraps instead of truncating: + +- removed `white-space: nowrap` +- removed `text-overflow: ellipsis` +- added: + - `white-space: normal` + - `overflow-wrap: anywhere` + - `word-break: break-word` + +## Result +Long CPU and kernel lines should now wrap within the blue box instead of getting clipped on the right. + +`npm run lint` and `npm run build` both pass. + +--- + +## User + +Nice! Now the only issue is Server Observations is now overflowing out of the header, lets resize that to 20pt font for those screens + +--- + +## Assistant + +Yes. The remaining issue sounds like the **header title**, not the body text. + +## What I’d change + +Add a Server Observations-specific header override in `_server-observations.scss`: + +```scss +.weather-display.server-observations, +.weather-display .server-observations { + .header .title.single { + font-size: 20pt; + } +} +``` + +More likely, since the header is on the root `.weather-display` element and not inside `.main`, the correct targeting should be against the display container id/class, for example: + +```scss +#server-observations-html.weather-display .header .title.single { + font-size: 20pt; +} +``` + +## Why + +The shared header styles in `_weather-display.scss` set: + +- `.weather-display .header .title { font-size: 24pt; }` +- `.weather-display .header .title.single { ... }` + +So if only Server Observations is overflowing in the header, the clean fix is a **display-specific override** for that title size, leaving other modules unchanged. + +## Likely implementation plan + +1. Add a display-specific header title override for Server Observations +2. Set the title to `20pt` +3. Rebuild CSS +4. Verify the title stays inside the header while body text remains unchanged + +## One thing to confirm + +Do you want only: +1. the **header title** `Server Observations` reduced to `20pt` + +Or also: +2. the **body text** reduced further as well + +From your note, I believe you mean **option 1 only**. + +--- + +## User + +Yes, lets do option 1 only + +--- + +## Assistant + +I’m adding a Server Observations-specific header override so only that slide’s title drops to 20pt, then I’ll rebuild. + +**Tool: apply_patch** + +--- + +## Assistant + +The header override is in. I’m rebuilding the CSS used by the dev server now. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Done. + +## Change made +Added a Server Observations-specific header override in `server/styles/scss/_server-observations.scss`: + +```scss +#server-observations-html.weather-display { + .header .title.single { + font-size: 20pt; + } +} +``` + +## Result +Only the `Server Observations` header title is reduced to `20pt`. The body text styling is unchanged. + +`npm run lint` and `npm run build` both pass. + +--- + +## User + +Great! Can you come up with a git commit message for adding this Server Observations screen? You can write what was done between this commit in DEVLOG.md + +--- + +## Assistant + +I’m checking recent commit style and current changes so I can draft a commit message and matching `DEVLOG.md` entry. + +**Tool: bash** + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Proposed commit message: + +`add server observations display with fastfetch summary` + +Suggested `DEVLOG.md` entry: + +```md +## Server Observations + +Added a new `Server Observations` forecast screen that blends Linux server telemetry into the WeatherStar rotation using `fastfetch`. + +- added `/api/server-info` to run `fastfetch` and return a cleaned plain-text summary +- created a new `serverobservations` display module and EJS partial +- registered the new screen in the main display deck and script loading flow +- paginated the server info across multiple readable screens instead of trying to force a single page +- adjusted styling to better fit the blue content box and reduced the header title size for this screen +- updated navigation handling to safely work with sparse display arrays introduced by the new nav slot +- updated the frontend build so generated CSS is copied to the development-served stylesheet path as well +``` + +If you want, I can also draft a shorter conventional-style message, like: + +`add fastfetch-based server observations slide` + +--- + +## User + +Sounds good, you can write the DEVLOG.md entry now + +--- + +## Assistant + +I’m adding the Server Observations summary to `DEVLOG.md` now. + +**Tool: glob** + +**Tool: read** + +--- + +## Assistant + +`DEVLOG.md` doesn’t exist yet, so I’m creating it with the new entry. + +**Tool: apply_patch** + +--- + +## Assistant + +Added `DEVLOG.md` with the Server Observations entry. + +--- + +## User + +How often does the fastfetch command get updated in the display? + +--- + +## Assistant + +I’m checking the display refresh lifecycle so I can tell you exactly how often Server Observations reruns `fastfetch`. + +**Tool: grep** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +**Tool: read** + +--- + +## Assistant + +I’ve confirmed it uses the shared display auto-refresh interval unless overridden. I’m checking the default setting value so I can give you the exact cadence. + +**Tool: read** + +--- + +## Assistant + +`fastfetch` is currently refreshed on the same cadence as the app’s general data refresh setting: **every 10 minutes by default**. + +## Why +`ServerObservations` does not set its own `refreshTime`, so it inherits the base display auto-refresh behavior from `WeatherDisplay`: + +- `WeatherDisplay.setAutoReload()` uses: + - `this.refreshTime ?? settings.refreshTime.value` +- `settings.refreshTime.defaultValue` is `600_000` +- `600_000 ms = 10 minutes` + +## Practical behavior +- The screen does **not** rerun `fastfetch` every time the slide appears +- It reruns when the display data refresh cycle fires +- By default that is **once every 10 minutes** +- If the hidden refresh setting is changed, Server Observations will follow that value + +Available refresh values in code: +- `30 seconds` (testing) +- `5 minutes` +- `10 minutes` default +- `15 minutes` +- `30 minutes` + +If you want, I can also outline how to make Server Observations refresh on its own cadence, like every 1 minute, without affecting the weather displays. + +--- + +## User + +It's fine how it is thank you for exmplaining, was just curious. Could we also modify the WeatherStar4000+ v6.5.4 page that shows initially to include a link to the Server Observations display as well? + +--- + +## Assistant + +I’m inspecting the initial landing page UI to see where the existing display links live and how to add Server Observations consistently. + +**Tool: grep** + +**Tool: grep** + +**Tool: read** + +--- + +## Assistant + +Yes. This is straightforward. + +## What I found + +The initial page is the `#loading` block in `views/index.ejs`: + +```html +
+
+
WeatherStar 4000+
+
v<%- version %>
+
Enter your location above to continue
+
+
+``` + +So there is **not currently a list of display links there**. The only display-selection UI is farther down the page in: + +- `Selected displays` +- generated dynamically into `#enabledDisplays` + +## Best way to add it + +The cleanest options are: + +### Option A +Add a short line under the existing instruction mentioning Server Observations, for example: + +`Enter your location above to continue. Server Observations is available in Selected displays.` + +This is minimal and consistent. + +### Option B +Add a second small helper line under the instruction: + +- `Enter your location above to continue` +- `Enable Server Observations below to include Linux server info` + +This is probably the clearest. + +### Option C +Add an actual anchor link from the loading panel to the `Selected displays` section, like: + +`Enable Server Observations in Selected displays below` + +with a link to `#enabledDisplays` + +That gives the user a direct jump target. + +## Recommendation + +I’d use **Option C**: +- keeps the current intro screen intact +- clearly advertises the new feature +- gives a direct link to where it is enabled + +Example copy: + +```html +
Enter your location above to continue
+ +``` + +## Small note + +If we do this, we may also want to check whether the existing `.instructions` styling handles links well, or add a tiny style tweak so the link remains readable on the loading screen. + +If you want, next I’d implement: +1. a second line in the loading panel +2. a link to `#enabledDisplays` +3. minimal styling only if needed + +--- + +## User + +I meant more so to put it on the screen that's shown first, not the location, the weather-display screen with all the links, we might have to shrink the font a bit + +--- + +## Assistant + +I’m tracing the “weather-display screen with all the links” UI so I can identify the right place to add Server Observations without guessing. + +**Tool: read** + +**Tool: read** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +Yes, now I understand what you meant. + +You’re referring to the **progress screen** shown first after location is entered, the one headed: + +- `WeatherStar` +- `4000+ v...` + +and listing each display as clickable rows with status on the right. + +## What I found + +That screen is built by: + +- `views/partials/progress.ejs` +- `server/scripts/modules/progress.mjs` +- `server/styles/scss/_progress.scss` + +Each line on that screen is generated from every registered display in `progress.mjs`: + +```js +const lines = displays.map((display, index) => { + if (display.showOnProgress === false) return false; + ... + fill = { name: display.name }; +``` + +So whether a display appears there is controlled by: + +```js +display.showOnProgress +``` + +## Why Server Observations is missing there + +In `server/scripts/modules/serverobservations.mjs`, it currently sets: + +```js +this.showOnProgress = false; +``` + +That explicitly hides it from the progress screen list. + +## Clean plan + +### 1. Make Server Observations appear on the progress screen +Change Server Observations so it no longer opts out of progress display. + +That means either: +- remove `this.showOnProgress = false` +- or set it to `true` + +### 2. Keep the progress screen readable +The progress screen already uses: +- `font-size: 19pt` +- `line-height: 28px` + +That screen is tight vertically, so adding one more line may make it feel cramped depending on how many displays are enabled/shown. + +### 3. If needed, slightly tighten the progress list +If adding Server Observations makes the list too crowded, the likely safe adjustment is in `_progress.scss`: + +- reduce `font-size` from `19pt` to `18pt` +- or reduce `line-height` slightly +- or both, minimally + +I would not change this unless the extra row visibly crowds the list. + +## Recommendation + +Best implementation path: + +1. Let `Server Observations` appear on the progress screen +2. Check whether the existing progress layout still fits cleanly +3. Only if needed, make a very small progress-screen typography reduction + +## Expected result + +On the initial progress screen, you would get a clickable row like: + +`Server Observations ................................ Press Here` + +or its current status if not loaded. + +If you want, once edit mode is available, I’d implement it in that order: +1. enable it on progress +2. test fit +3. only then shrink the progress font if necessary + +--- + +## User + +It's already pretty tightly packed with the current font and the 10 options shown, we will probably have to shrink the font + +--- + +## Assistant + +Agreed. With 10 items already on the progress screen, adding `Server Observations` will almost certainly require a small typography reduction there. + +## What should change + +### 1. Show Server Observations on the progress screen +In `serverobservations.mjs`: +- stop opting out with `this.showOnProgress = false` + +### 2. Slightly shrink the progress screen typography +In `server/styles/scss/_progress.scss`, likely: + +- `font-size: 19pt` → `18pt` +- `line-height: 28px` → `26px` + +That should make room for one additional row without materially changing the look. + +## Why this is the right place + +The progress screen rows are generated automatically from all registered displays, so once Server Observations is allowed in, the only likely layout issue is vertical density in: + +- `.weather-display .progress` +- `.weather-display .progress .container` + +That’s exactly what `_progress.scss` controls. + +## Recommended implementation order + +1. Enable Server Observations on the progress screen +2. Reduce progress screen font size to `18pt` +3. Reduce progress line height to `26px` +4. Rebuild and visually verify the list still fits cleanly + +## If 18pt is still too tight + +Fallback: +- `font-size: 17pt` +- keep or slightly reduce line-height further + +But I would start with `18pt / 26px`. + +If you want, once plan mode ends, I’d implement exactly that. + +--- + +## User + +Sounds good, you can proceed with these changes + +--- + +## Assistant + +I’m updating Server Observations to appear on the progress screen and tightening the progress-screen typography so the extra row fits cleanly. + +**Tool: apply_patch** + +--- + +## Assistant + +Server Observations is now included in the progress list. I’m shrinking the progress screen text slightly to make room for the extra item. + +**Tool: apply_patch** + +--- + +## Assistant + +The code changes are in. I’m rebuilding assets now so both the JS and dev-served CSS reflect the progress-screen update. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Implemented. + +## Changes +`server/scripts/modules/serverobservations.mjs` +- removed the progress-screen opt-out so `Server Observations` now appears in the initial progress display list + +`server/styles/scss/_progress.scss` +- reduced progress screen font size from `19pt` to `18pt` +- reduced progress screen line height from `28px` to `26px` + +## Result +The initial WeatherStar progress screen should now include `Server Observations`, and the slightly smaller progress typography should help the extra row fit. + +`npm run lint` and `npm run build` both pass. + +--- + +## User + +Perfect! This works nicely, you may write about your progress during this commit in the DEVLOG.md file + +--- + +## Assistant + +I’m updating `DEVLOG.md` to include the later refinements made during this Server Observations work. + +**Tool: read** + +--- + +## Assistant + +I’ve got the current entry. I’m expanding it to capture the pagination, fitting, and progress-screen work that landed afterward. + +**Tool: apply_patch** + +--- + +## Assistant + +Updated `DEVLOG.md` with the later progress: +- wrapping and sizing fixes for long server info lines +- adding Server Observations to the initial progress screen +- tightening progress-screen typography so the extra row fits + +--- + +## User + +Great, can you also suggest a concise commit message like: Adds Server Observations to the startup screen + +--- + +## Assistant + +Yes. A concise commit message in that style could be: + +`Adds Server Observations to the startup screen` + +A few slightly stronger alternatives: + +- `Adds Server Observations display to startup screen` +- `Adds Server Observations screen and fastfetch summary` +- `Adds Server Observations forecast display` +- `Adds Server Observations to forecast rotation and startup screen` + +My recommendation: +`Adds Server Observations to the startup screen` + +If you want, I can also suggest one that better covers the full scope of the change, not just the startup screen. + +--- + +## User + +Great! That's good for this commit, now I have a new screen/ feature idea: Linux News: LWN. We can have a utility that fetches Headline and story BlurbListing from the HTML and shows it across a few screens. I think we may need 4 screens for all the news. FOr example we could just fetch this URL to check: https://lwn.net/ + +--- + +## Assistant + +I’m going to inspect the existing display patterns and the LWN page structure so I can propose a clean implementation plan for a `Linux News: LWN` screen. + +**Tool: read** + +**Tool: read** + +**Tool: webfetch** + +--- + +## Assistant + +Yes, this is feasible. + +## What I found + +LWN’s homepage already exposes the content you want in a simple repeated pattern: + +- headline +- category/byline/date line +- short blurb paragraph +- story link + +So we would not need a browser or heavy parser. A server-side fetch plus HTML extraction should be enough. + +## Best fit with this codebase + +The cleanest implementation is to follow the same pattern as `Server Observations`: + +1. Add a new server endpoint +- example: `/api/linux-news` +- fetch `https://lwn.net/` +- parse the top N stories into structured JSON + +2. Add a new display module +- example: `linuxnews.mjs` +- fetch `/api/linux-news` +- render paginated pages +- use fixed pages instead of scrolling + +3. Add a new partial and SCSS +- `views/partials/linux-news.ejs` +- `server/styles/scss/_linux-news.scss` + +4. Register it in the deck +- add script include +- add display container in `views/index.ejs` +- give it a new nav slot after `Server Observations` + +## Recommended content model + +I’d keep it compact and TV-readable: + +For each story: +- headline +- 1 shortened blurb +- optional category + +### Suggested page layout +Use **4 screens total**, as you suggested: +- Screen 1: stories 1 and 2 +- Screen 2: stories 3 and 4 +- Screen 3: stories 5 and 6 +- Screen 4: stories 7 and 8 + +That means: +- 2 stories per page +- each story gets a headline plus a trimmed blurb + +This is much safer than trying to fit one story per screen with full blurbs. + +## Parsing strategy + +Server-side parse from `https://lwn.net/`: + +Extract per article: +- headline text from article heading +- href for link +- first paragraph blurb +- optional section like `[Kernel]`, `[Security]` + +Normalize: +- strip extra whitespace +- remove subscription markers like `[$]` +- optionally trim blurbs to a max length + +## Expected implementation details + +### Backend +In `index.mjs`: +- add `/api/linux-news` +- fetch homepage HTML +- parse the first 8 items +- return: +```json +{ + "success": true, + "stories": [ + { + "headline": "Ubuntu's GRUBby plans", + "section": "Distributions", + "blurb": "GNU GRUB 2 ...", + "url": "https://lwn.net/Articles/1065420/" + } + ] +} +``` + +### Frontend display +In `linuxnews.mjs`: +- chunk stories into 4 pages +- likely `baseDelay` around 8-10 seconds +- use Local Forecast / Server Observations pagination style + +### Styling +Use a layout closer to `Local Forecast` than `Server Observations`: +- large readable headline +- smaller blurb text +- two stacked story blocks per page +- no scrolling if possible + +## Main tradeoffs + +### 1. Homepage only vs article pages +Recommendation: **homepage only** +- enough content for headlines + blurbs +- much simpler +- less traffic +- more robust + +### 2. Fixed 4 screens vs dynamic page count +Recommendation: **fixed 4 screens** +- matches your idea +- predictable timing +- easier to design + +### 3. Full blurbs vs trimmed blurbs +Recommendation: **trimmed blurbs** +- TV readability +- keeps layout stable + +## Main risk + +LWN markup could change over time, since this is HTML scraping rather than a formal API. +To reduce fragility, I’d keep the parser simple and tolerant: +- target article headings and following paragraphs +- skip entries that don’t match expected structure +- fall back to fewer stories if needed + +## Recommended plan + +1. Add `/api/linux-news` that fetches and parses `https://lwn.net/` +2. Return first 8 story summaries +3. Build `Linux News: LWN` display module +4. Render 2 stories per page across 4 pages +5. Style for TV readability with trimmed blurbs +6. Add it to startup/progress list and rotation + +## Questions before implementation + +1. Should the screen title be `Linux News` or `Linux News: LWN`? +2. Do you want to include the story section labels like `Kernel`, `Security`, `Development`? +3. Should we exclude weekly-edition/meta posts and keep only regular news stories? +4. Do you want this enabled by default like Server Observations, or opt-in? + +--- + +## User + +1. Lets do Linux News: LWN. 2. We don't need the story section labels. 3. No need to exclude any stories out of principle. 4. Lets enable it by default. You may proceed with this implementation + +--- + +## Assistant + +I’m implementing the LWN screen end-to-end: backend fetch/parsing, a new paginated display, and deck/progress registration. + +**Tool: todowrite** + +--- + +## Assistant + +**Tool: read** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +I’ve got the integration points. Next I’m wiring the backend parser and the new paginated display files. + +**Tool: read** + +--- + +## Assistant + +**Tool: apply_patch** + +--- + +## Assistant + +The LWN backend is in. I’m adding the new display module, partial, styles, and registration/build hooks next. + +**Tool: apply_patch** + +--- + +## Assistant + +The new display files are added. I’m wiring them into the deck, the production build bundle, and the stylesheet manifest now. + +**Tool: apply_patch** + +--- + +## Assistant + +The feature is wired in. I’m running lint/build and then I’ll spot-check the new endpoint output shape. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +Lint and build pass. I’m doing one quick API smoke test against `/api/linux-news` to confirm the parser is returning story data. + +**Tool: bash** + +--- + +## Assistant + +The smoke test hit the weather proxy, which usually means I hit an older running server instance rather than the updated one. I’m checking the startup log instead of guessing. + +**Tool: bash** + +--- + +## Assistant + +**Tool: grep** + +--- + +## Assistant + +**Tool: read** + +--- + +## Assistant + +**Tool: read** + +--- + +## Assistant + +I verified the route ordering is correct. I’m rerunning the smoke test on an alternate port to avoid any stale dev server on `8080`. + +**Tool: bash** + +--- + +## Assistant + +The parser works, but I found two polish issues in the returned data: LWN’s subscription marker is still in some headlines, and link extraction is too loose. I’m tightening that now. + +**Tool: apply_patch** + +--- + +## Assistant + +I tightened the parser. I’m re-running lint/build and a quick endpoint check on the alternate port. + +**Tool: bash** + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +The endpoint output is good. I’m making one final small parser tweak so article URLs prefer the story page instead of `#Comments` links. + +**Tool: apply_patch** + +--- + +## Assistant + +I’m re-running lint/build after that parser polish so the tree stays clean. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +**Tool: todowrite** + +--- + +## Assistant + +Implemented `Linux News: LWN`. + +## What changed + +### Backend +Added `/api/linux-news` in `index.mjs`: +- fetches `https://lwn.net/` +- parses the first 8 homepage stories +- extracts: + - headline + - trimmed blurb + - story URL +- returns JSON for the frontend display + +### Frontend display +Added `server/scripts/modules/linuxnews.mjs`: +- enabled by default +- title: `Linux News: LWN` +- paginates 8 stories into 4 screens +- shows 2 stories per page +- uses normal page-based navigation like the other multi-screen displays + +### Template and styles +Added: +- `views/partials/linux-news.ejs` +- `server/styles/scss/_linux-news.scss` + +The layout is tuned for TV readability: +- yellow headlines +- smaller white blurbs +- two stacked stories per page +- boxed content area matching the rest of the app + +### Wiring +Updated: +- `views/index.ejs` +- `gulp/publish-frontend.mjs` +- `server/styles/scss/ws.scss` + +So the new screen is: +- included in dev mode +- included in the production bundle +- included in the compiled stylesheet +- part of the display deck/progress screen automatically + +## Validation +- `npm run lint` passes +- `npm run build` passes +- `/api/linux-news` returns parsed LWN stories successfully + +If you want, next I can also add a `DEVLOG.md` entry for the LWN screen. + +--- + +## User + +Hold on, we are having some issues, looks like we need to trim the story text a bit more, they're running too long in the 512x250 secreen section and on each subsequent LWN page more text gets layered over. This needs to be fixed + +--- + +## Assistant + +I’m going to inspect the LWN display implementation and its CSS so I can pinpoint why text is overlapping and propose a precise fix plan. + +**Tool: read** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +Yes. I understand the two actual problems now. + +## Root causes + +### 1. Blurbs are too long for the available area +Right now `trimBlurb()` in `index.mjs` uses `maxLength = 240`, which is too generous for: +- a `512x250` content box +- `2 stories per page` +- wrapped headlines + wrapped blurbs + +So even if the text wraps correctly, each story block can become taller than half the page. + +### 2. Each page has a fixed height, but each story block is unconstrained +In `_linux-news.scss`: +- `.news-page` is fixed at `250px` +- but `.story`, `.headline`, and `.blurb` have no max-height constraints + +That means when story 1 or story 2 grows too tall, it pushes beyond the page’s vertical budget. Since pages are stacked vertically in `.news-output`, the overflow from one page visually bleeds into the next page and looks like text layering. + +## Recommended fix + +### Backend +Trim blurbs more aggressively. +Current: +- `maxLength = 240` + +Recommended: +- first pass: `140` or `150` + +That should materially reduce vertical growth. + +### Frontend layout +Constrain each story block so a page cannot visually overflow. + +Recommended CSS changes: +1. Make each page a two-row layout +- each page should reserve half the height for each story + +2. Give each story a fixed max height +- something like about half the page minus spacing + +3. Hide excess blurb text inside each story block +- `overflow: hidden` + +4. Keep headlines and blurbs wrapped, but bounded + +## Best implementation plan + +### Option A: Keep 2 stories per page, trim more, and constrain block heights +This is the best first fix. + +Changes: +1. reduce `trimBlurb()` from `240` to `140-150` +2. make `.news-page` a vertical layout with two fixed-height story slots +3. add `overflow: hidden` to `.story` and likely `.blurb` + +This should preserve your intended 4-screen design. + +### Option B: Fall back to 1 story per page +Only if Option A still feels cramped. + +That would: +- improve readability +- but increase total screens from 4 to 8 + +Since you explicitly wanted 4 screens, I would not jump to this first. + +## Concrete change set I would make + +### In `index.mjs` +Change: +```js +const trimBlurb = (text, maxLength = 240) => { +``` + +To something like: +```js +const trimBlurb = (text, maxLength = 150) => { +``` + +### In `_linux-news.scss` +Change page/story layout so each page is height-bounded: + +- `.news-page` + - use flex column + - fixed height `250px` + +- `.story` + - fixed or calculated height for half-page + - `overflow: hidden` + +- `.blurb` + - `overflow: hidden` + +Example direction: +```scss +.news-page { + height: 250px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.story { + height: 116px; + overflow: hidden; +} +``` + +That is the key layering fix. + +## Recommendation + +I recommend this exact sequence: + +1. reduce blurbs to `150` chars +2. constrain each `.story` block height +3. keep 2 stories per page +4. rebuild and visually check +5. only if still cramped, reduce blurbs further to `130` + +If you want, once edit mode is available again, I’d implement that exact fix. + +--- + +## User + +Sounds good, you can proceed with this fix + +--- + +## Assistant + +I’m tightening the LWN story content and constraining each page’s story slots so pages stop bleeding into each other. + +**Tool: todowrite** + +--- + +## Assistant + +**Tool: apply_patch** + +--- + +## Assistant + +The backend blurbs are shortened. I’m now constraining the Linux News page layout so each page has two bounded story blocks. + +**Tool: apply_patch** + +--- + +## Assistant + +The page layout is bounded now. I’m rebuilding and linting to make sure the LWN fixes are clean. + +**Tool: bash** + +**Tool: bash** + +--- + +## Assistant + +**Tool: todowrite** + +--- + +## Assistant + +Fixed. + +## Changes made + +### `index.mjs` +- reduced LWN blurb trimming from `240` chars to `150` + +### `server/styles/scss/_linux-news.scss` +- made each `.news-page` a fixed two-slot vertical layout +- constrained each `.story` to `116px` height +- added `overflow: hidden` to both `.story` and `.blurb` + +## Why this fixes it +- blurbs are shorter, so each story block is less likely to exceed half the page +- each page now has two bounded story regions instead of unconstrained content +- overflow from one page can no longer visually spill into the next page stack + +## Validation +- `npm run lint` passes +- `npm run build` passes + +If it still feels a little dense after you look at it, the next small tweak would be reducing blurbs again from `150` to about `130`. + +--- + +## User + +This is better, however top stories with these texts: "Brian "bex" Exelbierd has published a blog post exploring follow-up questions raised by the recent debate about the use of the LLM-based review tool." and "In early March, Dylan M. Taylor submitted a pull request to add a field to store a user's birth date in systemd's JSON user records. This was done to" were cut off when shown as the top-most stories on their respective screens. I think we need to double check to make sure those stories aren't getting cut off prematurely + +--- + +## Assistant + +I’m checking the Linux News layout math against the shared display box sizing so I can explain exactly why the top story is being clipped and what to change. + +**Tool: read** + +**Tool: read** + +**Tool: read** + +**Tool: read** + +--- + +## Assistant + +Yes. I see what’s happening. + +## What’s actually wrong + +This is no longer the page-overlap bug. +Now it’s a **content-budget mismatch inside each fixed story slot**. + +Current Linux News layout: +- each page is `250px` tall +- each story gets `116px` +- headline is `18pt / 24px` +- blurb is `15pt / 18px` + +So a story with: +- a 2-line headline +- plus a 4-line blurb + +will exceed `116px` and get clipped by: + +```scss +.story { + height: 116px; + overflow: hidden; +} +``` + +That means those top stories are being cut off exactly because the slot is too short for their wrapped headline + blurb combination. + +## Why those specific stories get cut off + +The examples you gave have: +- long enough headlines to wrap +- long enough blurbs to take several lines + +That combination is taller than the fixed per-story slot. + +So the current trim length may still be too generous for the worst-case headline length. + +## Best fix plan + +I would treat this like a fixed TV card layout and enforce a tighter story budget. + +### 1. Shorten blurbs again +Current trim is `150`. + +Recommended next step: +- reduce to `120` first + +That gives much better odds of fitting after a 2-line headline. + +### 2. Slightly tighten typography +Not dramatically, but enough to help: +- headline `18pt` → `17pt` +- headline line-height `24px` → `22px` +- blurb `15pt` → `14pt` +- blurb line-height `18px` → `16px` + +That gives back vertical room without making it hard to read. + +### 3. Keep the fixed two-story page layout +I would **not** change page count yet. +The 4-screen structure still makes sense. + +## Why I would not jump to 1 story per page yet + +That would solve readability, but it changes the feature from: +- 4 pages / 8 stories + +to: +- 8 pages / 8 stories + +You originally wanted about 4 screens, so I’d preserve that first. + +## Recommended implementation order + +1. reduce LWN blurb trim from `150` to `120` +2. slightly reduce Linux News headline/blurb font sizes and line heights +3. keep `2 stories per page` +4. retest the previously clipped examples + +## Expected outcome + +Those top-slot stories should stop truncating early because: +- blurbs will be shorter +- wrapped headline + blurb will fit within the existing `116px` story slot more reliably + +If you want, once edit mode is available again, I’d implement exactly that first-pass fix. + +--- + diff --git a/views/index.ejs b/views/index.ejs index dd8d184..7d1c030 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -64,6 +64,7 @@ + <% } %> @@ -137,6 +138,9 @@
<%- include('partials/server-observations.ejs') %>
+
+ <%- include('partials/linux-news.ejs') %> +
<%- include('partials/scroll.ejs') %>
@@ -219,4 +223,4 @@ - \ No newline at end of file + diff --git a/views/partials/linux-news.ejs b/views/partials/linux-news.ejs new file mode 100644 index 0000000..fc84938 --- /dev/null +++ b/views/partials/linux-news.ejs @@ -0,0 +1,6 @@ +<%- include('header.ejs', {titleDual:{ top: 'Linux News' , bottom: 'LWN' }, hasTime: true}) %> +
+
+
+
+