From 65bd110a9fdb732f75b510ef8344159a104c7299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20H=C3=A4gele?= Date: Thu, 10 Sep 2026 13:45:31 +0200 Subject: [PATCH 1/6] feat(web-standalone): adopt the DMC tokens, type and background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First of three parts on #139. The app was its own island: teal accent on a teal-dark ground, Avenir Next throughout, 125 hex literals against 90 token uses, and a tricolour stripe in colours that were not the brand's. Tokens now come from DutchMeshCore-Branding/STYLE-GUIDE.md under their canonical names — --text-muted, --text-faint, --surface, --border — with the brand constants (--red/--white/--blue/--green/--yellow) and semantic state (--success/--warning/--danger) on top. No bridge aliases: an alias would keep the divergence alive, which is the thing this issue is about. Every chrome literal moved into :root; the only hex left outside it is one in a comment. Type: Aldrich for headings and the brand, IBM Plex Sans for body, IBM Plex Mono for data, served as woff2 from assets/fonts/ (75KB total) and packaged into the image. Headings are uppercase with the house drop shadow. Ground: the red/blue glow over a dark fade, plus the grid and scanline overlays the guide layers on it, all behind a z-index:1 content layer. Panels take the glass fill instead of a flat white wash. Geometry: one --radius (8px) for controls and --radius-lg (16px) for large surfaces, replacing eight ad-hoc values between 8 and 24px. The brand stripe becomes what the guide calls for: a full-width band in normal flow above the navbar, rather than a 4px vertical bar beside it — the same idea in the wrong orientation, in near-flag hexes instead of the brand ones. Refs #139 Co-Authored-By: Claude Opus 5 --- web-standalone/.dockerignore | 2 + web-standalone/Dockerfile | 2 + .../assets/fonts/aldrich-v22-latin-400.woff2 | Bin 0 -> 16460 bytes .../fonts/ibm-plex-mono-latin-400.woff2 | Bin 0 -> 10052 bytes .../fonts/ibm-plex-mono-latin-600.woff2 | Bin 0 -> 10120 bytes .../fonts/ibm-plex-sans-latin-var.woff2 | Bin 0 -> 40240 bytes web-standalone/index.html | 381 ++++++++++++------ 7 files changed, 261 insertions(+), 124 deletions(-) create mode 100644 web-standalone/assets/fonts/aldrich-v22-latin-400.woff2 create mode 100644 web-standalone/assets/fonts/ibm-plex-mono-latin-400.woff2 create mode 100644 web-standalone/assets/fonts/ibm-plex-mono-latin-600.woff2 create mode 100644 web-standalone/assets/fonts/ibm-plex-sans-latin-var.woff2 diff --git a/web-standalone/.dockerignore b/web-standalone/.dockerignore index 9913164..dfa8ac1 100644 --- a/web-standalone/.dockerignore +++ b/web-standalone/.dockerignore @@ -4,3 +4,5 @@ !bag3d.py !index.html !changelog.json +!assets/ +!assets/** diff --git a/web-standalone/Dockerfile b/web-standalone/Dockerfile index 2c88333..6065301 100644 --- a/web-standalone/Dockerfile +++ b/web-standalone/Dockerfile @@ -8,6 +8,8 @@ LABEL org.opencontainers.image.source="https://github.com/khagele/meshcore-trian WORKDIR /app COPY server.py spamdetector.py bag3d.py index.html changelog.json ./ +# Shared DMC web fonts (DutchMeshCore-Branding); the page @font-face's these. +COPY assets/ ./assets/ # Inside the container we must bind all interfaces; restrict exposure when # publishing the port instead (e.g. -p 127.0.0.1:8000:8000). diff --git a/web-standalone/assets/fonts/aldrich-v22-latin-400.woff2 b/web-standalone/assets/fonts/aldrich-v22-latin-400.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..c92a531ba0db0a6b6de757349c56f0d309b10134 GIT binary patch literal 16460 zcmZ9zW2`Vd6Rx{#+qP}nwr$(C*RyQfwr$(C?el(n|2R44%H*E5nP&Q{=`_EfdD|N698lb zA_0zoK~A6mApi~L0S{q?0l@|@;|$qx3-+fV+JP)CseI*hVjB#L6=q1c#6UfVI@vVn9CS4UU9nY9&h+OB&(ELY;0fquIbYFF*Z{rLmDrv)*6Y-q=eR|Vfdd_5J2@q_lUIzpQ+FY{goJ^oK{W0a)M9} zNbZAAhjj~kx?1!X!WDJc{yM#sa6J@QN}89dU*O)-xTaiVfy3F$T$ie(7Fb7#Ymu({ z%so+uDL^&$C4nJU1EmKg|Cc{-(^b!Yw>#+dOKnEn?_(Sx5BmJS5dg(s7#r-5r0nkd z@2sz9KHdp^!&eya$gosEr-UA8QzJao#uF>Idir|ucaWMFA0Q@l*1{uzG!K&6A;P$n7+kyFL z+7Ex{m%W;0+I$1h`XsqbutnkbKYcOt)pS(5wQ=)fZohJiwtmDC!+f_Vkd7|>ubT;B zD9WW&Nl@LIi`%{~S)a+)C=HBcz>SL9C~K+}e(?0$S`aP~l|C>+!1amFpZXdqdJ$>m zNZ_UF^__kmVYnpJrcQEy(N65wNVRaOHNC0NZQ#oQ^Ah7~Pncxs^~8#gCw3 zU6gnEHy(%E!b&=+e%^y{K`(*3d#x~JXX;E21t9a1wYLfD9U2ohgGdoC?@X z)Y$XwEHx8lAWnPH_x7s%YR|ExTA+#bx3LD zG5ZPLvzV}n(lB;GmL)iu@^JQr5~xF| z7FNu$7}bc7+tNz|b_gygW~8f_wTM2|ZmyfHz08Zt1vCwetXEOGFn4Kx*0b^0em%an z6w<*Ekj zW#{hz$+)sKt<$c_Bcy#J`)${UqC-_bQ5eTmpa2ozs z1h4;l9}1uMci#b@_sg(^ugcTm@uwW3^p2{^NaQk}zcg%bC6mSO;T#u#d(}H#e&%PD zuWVIPhX^>-5DFAb^TcX|kvQ%L2nr3WMUrf;z;rN^w)!w`$xEn{5RGB8P%&Sdzsa)) z&&JS1(T(S&CddXeMdDIjG&v3P-_|5Xv{(Ym;OIpL(Ls^ly{(I3NlaR~$pljjHzFKZ{AJDa))_Gdzbmk(moid_{Xa-kPJHF}`rEvihRzqjO zQm;y}gL!5eBNOhT7K&90?jyiUISY_*w)6Q+NsXU)ntN6yVI3#2>Hq;U^G`Au0hE3b z0`K|rJ5{Yc001b%cW?jzuo1%q;IfDO161T?jH3mhW5zGl;{5GlD6$kFB`GE&l+BNn~2_Y|UQQjI7%iP%XE`OI0$V zO;XayK#u)jV@T4|V9ya?4IAq4Eg43}r%$oPzr%Bkj@`Q7$7ArrQGPfGq5HesGo=w_ z%w&XS-IrbD$6-Wy^YdGXq&Ghs{m(5$%P6EUUVzxov3|y#uY*oyjcEVziBx8o5pz+B?|EXtXS^kJ{0uL zDbltf(8?0eBa~Sf04j3OEQ*0qC9h#5iG<6Ke8=Y>>0fYOGLzX(&1aLRPA*O@QT^EF zx}#-KN6mneHYPRyT9q1*%CRj>#|5Uml&CFLotKs7lr&|TrU5cqBp#sPGVogp%Et<< zg(JHZBj*)3%#q+&T)AP*MC)$Wea=RS2gunBEFCVPk~8a$y=x0|BGNj(B)yx;<9ohZ zNTeuOpUO$3PzRusEDnnbJuJ~p4@2`e?@p5mBVYGjpn%5>L1pL-s~-oP8wVIJsh97HK&LjR1 z$D|Flr+y{6#68vzl7LB6!7)Bp{<%&HNdEJvhYju$ZBJJ1b&N8N&qBqEuGbEQrjy=w zlk=R#*|Ve|8AO%HkleoCObF95mr8oeak$?tYz$&D%q`>lB^KnBOdx$WUJAniBs zUT=#sE&%c9-Hkv~Qhba4oCg)Y?!t@8Z;}XkNCprO%7~SMVAwhT{oPH)=Yt}XB_ckV!DcBX((gBqTJj<4i~IL+lh_klQt|z?vyKwi8<|(J?(9+=PXT zp~)&##o%yu2Zw2G7o}c)@{MxwPsb7aq@!5nocH3c(84-RNZu4K99Bj7u1A_H)Zv%W zte8l0%2^a47#dafQ~Tw z$-Vy9LbKP};54!cb~u8lP@oIZf@*uZhv`tm%o7?JiU?hi(Rax7>%8)tWs~hs9PD*o zy}-YvRA*?aZ|^p;d;V*g^v|a}f|cEM4qR#uB{;P2Qc-gRb_?(I!~@@-0vhq#kHXBI z&=M=0Q8T^I-qkPdZ~5m@ouh}wfBi(hJG6}$({=K!$r>%9E8A|Uthl9wmUilz)SiRl zOvF@x<`TZ}D#ZvP--}r5nyLGF%5fP_XJRr{n}V!f^VgX;u|PD*=7^Fv_ZvC8aFoxT z;ixv~QpZeN8jwg`?vWGj;C4ioIjDpO_%hMmxp!$+>b#hTH0tx|q(|Kpg4H?+r{XvaS zJY6j>r7doGeWKfl4uu*MxWrvYFb&|W$LFF*X>u27c}Qru!8Ts-pxL<%-EgV$zaX6p zWjOnap+avATPm3biA}-r!VHN)bY2|Pnt+1f2{Y}QrWvd5o#QLpmg#ARziOR$<6lc3 zxs9?CEtvXON7+L!BAX^5XN^%Hfq&KW1koid3eSOY$CtkKuX8D?^ysT88gkjn?GW+; zQdp7TG7P#Qaa zT@PonPG0B<^Y-G!V&i+kzh<(k1bu z_LH3Z#)|ngx#y@#(O9Wa!rGq{VR~kcR$qIQ5SIM!R@mXyK=?@Y<)PkHK@;jWVq<1_ z>X6Msptyx%y?qIH#^cJ`@`y1LgF5Smsz3*KA~84mPVN^z^LV(}8C-r>&2u;oW-mEl z+g1EBp-d|ni(b-znT0O_fMJ3}JLpAMedy&{walxlZRvBEECQMiAYo2qL->TSwP5~# zG(*s|0MI(DG2v|cu)Tqk9je;UOmh_k_TEdf#0A(!k_TA-l0zFM7O^O&gQ_!JOYgpC zo-m#dNLL2!YSpBqf?zm;XTsCc6$}-xQC-!=e+;Vv9%H7t@tGrzhwk z;qQ?RCNpR>C2qV6gi-93w4Uyah}1!?V=Dzpb3{ois0gm8QI~T520_PXDFFtUiq6y> z4FYrEa&vHRkZ!&72TD$n+yX>zL+h0i`77<+Zx)SC>;m3k^nZhy6d=^E7XgRHsE-^6Ya)=n5A0XyLHR4^u#qc zhCA_ZZ_?*r)5@w$j_52A#6Qwv0SnsKQmE+UdT1y2k(rfIXh@VT}|fD^ zFqSd>yO5DLtR7Fg5I{#VHUKYGoJkynhGPm(N#hQLV|FY$UP`~a~BFCACjr!;aq<KZcm>*WJ;&R}}i=Bj@M(-$*gD7S4`$Bjp0RX5su>372r0^iAbdEeU z7B!hIt@=&r`*+7;DJkKQ45Dn1&otPQrXx$x&HA+zjdh5Mz;w}qWPvw2Kya@pHrmHK zfhpOm8Kn)uqXQSzKHN^zqLFAiqXdy%Ds)1Wxcz>%AS@~)mxfz!%mS0!_Q-(lwR?0R z=*e{X)bev*hAyHL53+ny&$*2*=5DniTRHB40qbQYwwyi+XDyS`f?*)nP?O&s!$JP3b0CgYF@*a*w5JVopA4ur~fKI;;c4$8D zYKOi3`+Em=TGrR*(dPAcgPGX(%>zR7H|FbxFnPv70=EahAuLUmFox`?a1(5Ic#Da|_)$ z6Iv1h`D$RifZ;3JPs=}7ns|}ld($a%n7Qf&KD|hW;8;y{;~}v_ctHXBSmtW&_;+*u z)3P!hZs;X#jdtyVH{r_OeDBoL_nWD*nF0}-X^+WYrDsq@#a*N(X|iO@D>*Yz8f~0* zWB*b~`T{BCcYMy;f)&*XT1a?0fmyOW=Asr*rZlu8-y0|9E5`$@gLL{+VG3ya!Ho;! z<8D-z3N`J|rJvIW?hyB)kX4a~nVZiFFGvFc*~l!DzJ_rK-K#nr2hBi-$DS%Rg2)M*6HU6^ z5)tflY#8aHgA2(mn|QAT5%KDaSf;={ikDgGXNootpMkNo13p=EvJ{^HEAQ!vNH^66 zW-yz+H6jJgv@eoDM56Ec_e0SQs1&n+5UrG6CC+=_F99;UJyGskLZPDDrN|li>68e0 z}n` zG!A+8pMrZ#`3_|fmA4}Q=955EB$<(623MX5@t~9~$#G%1u2E^aX;P>OHl)6Y$Rzy~ z{r3VbED$$<40-R<3Bq{YSOkO8^!(ttE>UVk#RL(PSmFCWC3Ga&!*(ewWm}VV670l1 z$w#4Wn?O%M_3QV+iDtw$Sxiuw31|FF%_k77Tjg8|`iE%5F#pQ9{mgzZllUm7}NSd_f zlIC)Gd>##c%3Yh&{7k_#jO0PkIyU}^t{BOmQeg0M_<4NWkk|c`;=L?+h(1)7llb0s zx_<7yHCySSl$`3u=YG5tQ*F+&vi$3P!fhd&Q>@xc`F0NvxLT=9yVMfnQbDmSiz^m3H&>tr@G%cC#Dxh@C`S*^)NEYA}!7?d7XBZdht~w*Olge1Ji}p zJ2K*MviaA#@iF^Q@G<++^2Oy1hRewlG?YuX?`*xeWZmx58M_S+aX+_hq3FHmZhW!Ph(J0FnN|oqCh{GyXe4%FSVyGsdC2?ZEe6a%;&1x zG?Jy&DvsbCK}^ORvMk$O+hrr=g!!I>-^mBUOHkr$VUf&Ve8GzI-@D1Q1g7hj!@`jB zF`LO0JQUKl@ys;n!GOODCoY8S=aYlgMe>zAt2^Y0vwxR9&5!mmTRk zP%UEZ7i1~*fXpDvl>DlJ6Q7Q6(*E*(UxDAt!>8DZ2Lf+8Ami*8l~TU*uWI;QxEv@# zfx6x;Iw0xl*0bx~P#%s~k!2u>(`)(^u_a1EI`-k5^l`9GMq1q^A zSsTd3A(N$%bbPk`FB`3o7b&Wu72GtVS4Zc2R?@dlZ*O(e+Wp4XcI9ei_po0%`^qxb z)qiNXVS$t8{UvYSk($^sJaeyoB}gKuYYfDRbre z$E||hNX)wPF!lBGTCpBnE(<6idCHsX(}!{qqN;( z{V`)6>Z0Y1lL?m{7tOE1rz5-oDlaFuAve{k4wz|7RyTxh;(c4T;9`7|%XX&%LT7BM zk&WsN+4{1vOFfdRb<9f6i@T{mS9FiQZD7fJ! z^Lty%d~*05#4VopMY`7(C3ozfRC#eAzhooP1MW@9Sgc36`)#%)@clvUlj42%tah#6<-+HETRfwECAc~Kv__Qz_2S}z`6XK>%vAL!;up$KTq zc;Wb>?$!U0-mxS@(yev-iidY{0+)8^AisP_z+ z!L)V+JAxVu_x@1kTs{S#&Hbm7^lI(-bewD>vZ{vlNY`re3c4fXMeb8E=BRn+Y}$`u z!q`8G%|Q(2*IrDXU(2XQ-*eb!-jy-;hCi7(%;+O)J6@Qqz+@<1RY(d>spN~3EB{GR zbolK2%N=FIdv;E1=n!;uuEnjI&kXnRtuM9`9{TFJKBtkt+-p(`m(3;=2*I#h$F zkJ8$Bs5uPY-?}V~*ZthP%q0F7y)3xG%YU%yrX-f%HdVnLNaxg3l8qINK0d02PG;YzB{{$DMMOx4W9jqbEx4*n;(U!6!DK9*r|E{1K? z9I%LJ$!|oab2nOFYMn8@^P<;5-*wx2N7*4^zO~)2=qV^nj)?9q>$shd?U50Cg=gu1 zYu@*&vum0bt5_R}lJC->C7{w$RABVp`9dR5MCF4v?%0H~GSs z&b74zft1V~+OgUvp2yMZiR^3ef!g|=b!7WsKY5zKH=g4*6F>Of!{V^@_W4t}^G$_L z#KC`ghui!X52`ON-a^Hmlw3(33E9UPdXWTVr~K|fkC|ar158FaV2N%OBU2Wu=-!ev zW24Ke$0WJ@Ls9Jm*_}0-62|sGIpdeY`oL2{RjN$gMkU)VA(+0>P53%7#Ax;w+vf4w z+ig1Kv#It_m1AqSm1DR4nY|_tyHBTq69NDoo)%MC9XLX_fsWT8dB^M6Lri*A_9*c0 znv%UKlLT-5bf8&j$W31<#R9%}Y**;^&mM9X8KxY=+tEv-#CD&wMko@TzCe2+Dbt~Z z3cVLi#VZ`px}k9Ih+uy?zJoOm87nwU0HDOJGDH$wl>#}?G~x+@K!Nr5$`Z2|!T(EV zuZv_Nud!Q&D&G)(Fa|@(3R$>588N~y?OIxf=*Ee3+AtB$`D4ZBEvm=ggQ_K2 zM4sHyr5sz0U;}7HPA24dR92X{-@!d|J^5!6m)a{?2&lVDxP!YL;b~B1R#s}Ks59nO zSPq2H!hB0w+_x&eO&(ttZEe7}i6RooqgDd#Ol`|%B1vkx%vuB&IlR-r$FK^Hv++ec-yZ+!7!s7;f>9@SH|dtkJ%NdpqVMy zZcu~U?}re5J@vIVtB(!rzF7Nf;-z*HYt`c?;+{p{HZqcs>jV-uIjFot2|;17Ian>& ziXPm>pr`-^rgu{<2MX7AG@~}P9~{Feb?Q+UVT}e|LKJ!lq-HX(d)@+QEL`YfG$l5I zGMmG-&}4)gg_4xI6y{|=4o_j%bPb9_Nx_pOXOs7^-o&abH_^(nOb1GH#-=d!_2l^c zO0;VLs@Kfx9G$rjM0&XT`Kbpt&Mg>=C{2kA7M80~ma~1e7+7A#ScGL&`@Up>bwu~+ zeoyL%D@jtJVOP^9+aRr#=~V?_JP_cp)ubn9DFw%HdB)@Y96k$N8ZdZEphNC`N3=p2 zPACdsdD(Ql#-C-%abL*;$2rel^0#vyxW*01Rx(<|4Mvq@T{q53Qboy#M6gAUS`x(l zXMn(F49pqg*cS+ZSccuw#IlqV0Upu9LGQp}fhw*8s^OW$+JYcRAeJ3AccH1s6f^)a zkbsbYG6&d3st;w92B3$-F=z3|SEN%Fa3~r>7AAmDl1BnlXfWegHRnjV=b69V*i z^F9a^XdMI;nKq*5blRAYh)W`?550w-yPLE!Sr&HW*$~E=!Wj6Aa{#u|^SkSk2G4HD zdhL<d5jrv&W9((gYAejv}V^#)^gP8@nMi=Zt9aM?cUS`Dngjpg30{e z+)y>2-ARAK?f~~}bcj3IZvPIx&Wc{s48+oi=+&>CGZe&ZfvJ#XDDTkqf^&AVti(<+ zhfOk;VUk5T>IM$)q(WPJv~&)$lbGJ!uJ%2csHucHdrD6$d?W{;oZVJ3pxrq5w}FK06( z{GK;Q8-Jo4-fmLyMOmP!Y{UT`6%8=D*Q_2>GwJb@@(z#==sdOPlIm~6zL|t z$Fg~1_`dUHB~Xe%meTn4u^VCnvD>Ew@OUnnGyKX|&=ABFl$Di%0sf~$KA=p@%*@JC zl>g~d`7(>A&!^Sd3-3t#uWof`q*dxUGrzUEJVq36`0wsdvIF<9&G)za(VN;7jc0~7(4@^x#q#sn=2P{XNIMZJgBA^E*N4B$vzL=(0*Ziq zPe=AoRQJg=@#k_Ln%u2VseJ90&em)b`WVQ2wzyO0ucKHJa>_JKQi#vy%@(nw^y9(0s@t7-Pj@neSM8^&NGFb=@y2x7leVKcC-pa zyy5GFgj=}?NVd|4t)yY%nv!4$LIxzHl>(7E9;&r8bRCCBY)LZj>&yf>+yNmXX~_^N zEP*GGvOyDI_@G)uNx)B7m>f1G;S*;8p+m|-e99O%Xx?ktJ;)~+XOwY88EjdjND2?W zgowTPc#I-Rq%ImT86HZ?LsQ<8pY$2!Gk42!fg2N9fC%)WUEgJyF<&DxF>9)4Iq#08 zI)~3BH6(j{6r~}lg>9-!%XNDI&73QEY&#i96@D@?nAqDUqpZ(v8apA@7T+Y1O?_Wd zKD90$J=;63E)Bk3KwsYi|Cz_MCCy8?9`!0z6DMVMt4#ckaDoP5MOmlLhS=`?G;w4| zDo)rV&^V~xx*e6A=}{ihw=CZyrbM_29+K@=z8Mx`oDAv_jJ{45q$8jDQ9h+i?8jA3 z_^THNl~egJc^hpq?D;m&GVqP50+io>Vz~j}9Omy>FIQPnrVx%%7H$6Y+P6WZgBc+y z&ie zQ{*Rxb6Cr*kAwNfgQ%}NU)AVUu~#i@U*aGa?hW5X{hqbNxWJ7&3{~eXq4R<0%5v*&Tf5DuZ|CXtq~I2-p6k)EeWmPe zxVbeUoTB=-EtthTYqW^GsrKY=maLZs#1eXpk%-zfJ>K8ii0MNQ>`J!awHZ|Rt-M~O z^>_2*RAsx5BVdeks~NUbJVKQflfKblY`~%oH7N^<@9ULOznj+_vGlo7@(OuvoW?Wj zc9K@Q%#v1>SM9l`JJKFgNxr3Ypd_<-rc!0O#AF?2pH%W2!!PxSQ$phy=d|eLNK?aG z&vDq?crOl^1#-&2N2G@FHnY$j^iRT6eq2l=sEYl>UWd5-%Y zCYhST@yo4#_QapSZ`()T+G<SSwoVZ$Ra%ce z$f+DXiWKak#)tY+@KcV^P`$E_E%wp*yASV~=d1*qf z>;^#;daBEFr`(=lR@_|KUtKx`{H55xBSP-%_Vu8;W3j(u=q+R4kO~~ryUO!XZtwls zUE$nA-PoAb(Ns7%@#>6+t_UyxpFUF}p})|V3$%p3%O`Pw%&N+wdl7o3#bWArq~?qL zo7%Xid9IRHFW$P7YwzK6E-gLUQWgjmsuxd(R#zA?y2Tt83$ zVk(94BbT#=vQ5IYI^sdnmP%AAUjdGdh!FH+XZKdVs&p(6{bvKa;pmP+Zhcch(FO|& zHl+iD!o>W<`v#F;R+Np3!hLdSV&44zxb$N5x~cRsx*VSHm?pA|st`n}lZSvHR?!u< zL=TS!Q^$6)*@uVV}$G2tX%tiOWh=xDm$Uf_~5s zUngGD&&rl1$pV(HS0yrOH;icwO4MW+Ed>C#?Cq9_*6*VP(OgzCty9Bfn1BPXea2ZU zIRx+Uf$nq%WIwyQIo4U$$i6Z7qUEYWx?p$B97;Mp{^ef-m)azg3o*%*Abu23JGKp7 zie@4qFfFW_)BLV+QuMpeHGjQIgQ$E3jF|g9<4!1C|Fucmp5*lcb^!kXo{pYhS&>YX z0a`g@;kD(D9D2mKg*!*e6LCick+Gp{-xnJTA#4vP!vX>< zzR}iU8|@HeGPiV#rUdQuEwEol1)+x)S(`AqT3D$yA*Jn343aka%arN$Ej!JN2VBF( z**O5z`71S8D^0!mI~Fz&L7>Z=G|2|PViDnp(L+J{7%kq+JQw3L3#n)@ZR%_QYI`rP z^jns*K{y*R7DXSA{OFeiMKBA)!$QX=4PY~$YC5qj{7_)}mZZKLEoy zgpV|hZj?r?^+tBToFkCvj0Ff(0=IH&@v-HZ2-fT^lEK`r6Xg(G>F@iFRV*{_8f70E z(B|P09OX8&uKKkeXOzGiCz>bTjjhQiy}e3p>yu-@<(*n7^GjF_&1X^$7=3chfs5ys0JJH5o4?%L>|&h|3x=wA@k-3le55 zv$Ks*+N{x`;;RA{v!O3bNJl%&GLV3>t9WP2g^X5%Qj;;M{5nJNxn(Cf=pXDXcAuE> z3X5>$&6#L`s9ld+yvnRYna9qh^70veUEC6=?UREu!U$&y#3fQ?^h3moW|cih3bxf2 zEX`9GzD{WAeZWmU@24?sVZ68?U@jA2+XjN)R5hu+aW~Xv4q9oRyXp+2{#6_Tvr8-^ z?x$3@-`V0Ewx?aLMu(1kXbI@=OL3s5FTy2x-e;U;cRt9PBvnP96&0RtpWIasg$H(~ zec}UKZME=qk2*U?W$}2$)OSy-41a$xE^jqC&|s+>HI15&pxM$l6LQR2znmy(S8_Y_ zJ`ZGQUiX-;dk>QzeNCxevvt zB?2GRGZBQmBxoI|EP`zig_|RPN_Jh z31nBz&GWq9Rx95{#LpUt7@l+?tt?4HK7?l7i$QC-qSLG}kJg2c(=*zyt5rMV<8BQ8!f->yW9-Ncg}`lap1M&IqE zfMG^XkZfH$#|00c5|&I9Jt6_3hXVWg;Y8bYY;**_*0yvs0atU!y~)}4?SD4@e(K{M z*1ehUiB#W2{XY5dGp=b|#^vb_?rnamKDye^VfXU8`)WzMe`z+rF=+**XNF~=>)-g> zuB_}Q@eTmlINkhwW?a2)4yoZ6gn?At7JU*mhD-o)`B`DVpAy3t#L5V*Czn%8DGtVO zr-UKUKUp~)h(m#LfUbkkxI=*j%x3S(Rg?lC9eR$?&TqlJzrru9jE_fbvB@1mg~4{4oFMe}q-2q)hIy*?N2!~l z<`iD%WMa3F)9}zj&LQE983yVK5b_lEeE0M)6a+{^wdUdIMYbfe8Rc?t5az*xbeDZxB z$PrgPgIy67OJcFB_^;kk?6EzM>T?F-&HE;#Or++LLSO-J;vLvgf@-lxz{yA3dz#V!8dt?&b1D|zSoALoc&Y+J!sxvqkWGYGs!w1vFGkjgU@!?P$l8}; zu8fu6bGv}ODhF>5HPBSN;HK$ zF!ZI$Y=B0Z?m>A{+B5gVo;-${r3BLroLPia6r}3@Kj(SW0c24D5a`LC&lBdKc7@Hq zE-Ghj!hi~Lhidl+3k)mjgfq-F#ywFqMWUrx%UM(;X&Jt2z62)>W8AOg-cr;wUN5(o zsw|{pn4%CyGnsyS=t!hu4nZ7>Gsp(_LR)fm zVdokzZV3*eUAf8@xwkChER*dy4GT_1gm`Czs>evM!-G1TTjaR8cLuO{<3aygf;E+V zlmpx=fn;d<`dncRR=DGwoG95$b=(YhoqICX|IB;)@zOrsBF8%`ZcDxrsOI9E6Rq>Ban8B5Cpa_`cyLl&^crG-uSRae|FEC34w0OZe5^>UeE z2<$EubcNR9x11cwr0CsfQR2N_pR;9itb?4GEZtqn%3jW?8YuWi)sm6OJ`Tp<@m`=G z9l+El>@A*8V{XEhnW(D-3JlFm3D|RBs_)D@AvvzpFknZIrI)yZ8nNN9!POAUM6PsY zSzKY{o1h!J0W{DviY6{g6-9#HS`mS7x93uLg@8e(8PIg~G_>RP6UrrQzqsz`ftBNtqwbaf@U45dy&kn;{0 z`SAc*%#HgG+N>Ca!??k!P}B`mQrWaKAqHL1EVsN;o}f}U$%rZ{z|x3yzeuH(g4vr` zSV_6pR4fR}vV_Dp&;->yB$l3n$;yH8b}KR+;!h-uT%)qPz-vE=BIG9FtVkj(as38SDcT=EEPj52spRO-l(q0Kp@TI`{ewL6F21L|BnU1e?dWC9qFk$W))Hbz@8XKHKgE!-bE2Uq8}``3pT>19_;2H}sAN?=tOvfL#A zc>*=%HJFjGz_Y#E?}|1tP=z(*9{&AO;>Ao zi?_?y>xbMxJf)l#5fLE~tNI_HIEer8zY*(y-^I-C|1tOYf11nxPZN1Wa2hTH0LNW( zWtwVbC6)630##N2R*48E1MQb1XreS?8i3wTDTNWWfi;H8CU1pw^}AnuYd4MSWkh*4FKZwMhQYh8S z2ETi)7*ONQ2K^GOh4lebvVbw91lq)nuU-sJ4`5*N+i<=m!zsFOcWEz0_QB)D3bK8Cy-ip+d|PUPBeN&%}*EW_KSPg1#W8-T)i%U=6^ ziT#rAaA)T5uvGU;);3WnRjP;Eq;6D8g*v2ESt?h`Uk2S*%a!eGz{I|)+h)PAdmcwY z5jfQJ`Lv_@9X z-U9{L0kHxW22sZtQgLWhgpPe-141I~5BxU&4{2Z|Di{cg3WA`31xQ>XMZ6$lg7&Q0 zt5)A!zV{d9=H6U}x`=Y|dVAYn#jEY5{PX?A&ixC#X3+x2Nnr(&P+(!|2{-Rvf2x#j zcl8!T5cpZ8Ukd!On>}pq8U|=UfGmN2sq5X94rbm;bJb6sDkV_G6|rRd>?40?#+i81 z1KF)qG$E+MCAN%1>+14BTTZaN$K5Azw&tR z6FxkC1Yg>3tEH9QBizv3WKrCdQt{*~=Dog*t@5JswGlTMU<|Lj0MqNfF;P36X(-s3(`|?GB z7H!_+`}*0YLPqeuPA#jmo&_=Ktx=eI3J*rX%D4nD+B7nmkP0H;Lnvq=L9mpC3qS!0 zq~K(x75YR{MsNu-AqG*m#PWeD17OnVL_|2AyiC4ALS#aIM=Q7ng%sccA5w4JG`_%* zh50@o2DDQ^OBRg_U`7BkhVcU8qhqj_;Y@Vz5Lx9LtJqbqn1|}pD@LLaTV|qXRXf`- zV+N56=)GyZO6rSYX4I_newb*$YET%>9T`4^LN;83BCa|k7bcrbv4pgAx}j-7-Wel|fyK}<9ZC-6kd96kn~2k-X- z8X_+~w{A7IK=En@qGI=9~fbqb1V!ZB#V}ux#f<&ue)o_s<@Cb6YMl-)~`JOCS< z5t~$)U;$r_EI|PE#54ovC}pk^Cmi>}k_cV|EDo0Znc$w^ChjwO<}lIdDX?nCWBz*! zFa#5P9Wc)THDE`96>vZS5{u3V1I-{Lbdn6=jJ?@sq{t-WsVc=Z|nPp z!QpXUIL3+)8if{3qtlqQG+Gu7p-slpW0%G*rw7qP$H&188lEh2Mck$sh#zYm)v+bu z8qRa;U|KjWaz9gPnQ!*U@dhvo`gZ_*BcNA;|HpsA|407|`1c3+_j|+#;KSt+{ZY;% z>Lc1u4}UWJRPmGh$Lb#~fB`rPTm|j}4|Id#lzEU0FYwZT%GJtPl;Ur~Bry}*>OXzYBX^{~8lqZlvFi;=_4~cfe z#xcg9pKOI4rrp7F|(&D2h%gtHz=fGG!W6V1LqAEb;R8B82V@>E{eAYf4Dh z$8}TDpP`u5Y`n;Nt$@teLWdJl0S2UeITx+vp>sK_s&Lg(P^y`yUPAW&=G08AV7bF2 zfPiR+QMijCfY9;|`{IHWA(_x}oNdsQ`(C7W^9#I%#BX8gA&K&~=8jrl-X4VCMG0yl zQP%kfgfwEKAXY1^P9mIKThao0-h=CfQyW#<9XHK4nE<P40PopL z->~hq0C4U-OC?#Fq8mf*2&5$lwqh!lDkRrzjHVm*1bIl@VB^RG%&-Up0LDs2C)KW; zV%?e1ek&9M8$iLijJB8LUXMT8m{K-7Ot0927;$8Ac-UVIPtVVA10N34Dw~Jv$H7u4 z3@!Qbp~=~401Wl{RD)aoDT~^|D_ka47vW_{R0}a@MvxAfiT8+gnapu4#YQ(ljtqxL zo^vpDNdnI4o&GX0x(MKi$Y%=@t_@o{ZpkJm$6Tf-A(J@{-dJ+9Z@nG!He?QhiWrQ@ zS4%9Wgjc5{SUa`8jsf+i)Hh~ac&l?cmPj=qZug$_Eg9N4E<(wMPG_8&ckenWt{yB3 zwV|fIC|hp9^e882Ptz-8zko#AMvg57mbABaWXJ%JGKw7Oh1ZNM2TFngMNvCP?>0@P z9|KW5!NH){{tfT2-W5mfFIu3qSc8UA{Dk~A{+VHfJrzA>?o~)9%v|fTkL^(=5R2sa z2lswdd|8L54Ypmx{ZZ%KXEV`z=z~WzS1p`dU|cO=f@t9JyW#mhMt56`$5<5XB>YTG zd+re}{7~dXsn4uFcc_u!h8!o;2@6Vmfje{kjB-aM9ycwMF;E8tKH^{Yp1gVQMOfbG(H;kl=E83UlO;;CAM9 zA!4rLNZlA+e3nw@P7Rnml}>ll|(#BhRZrG<>?TiVzDE2l!4do0!9a;7KL-<3@R_Tims zfT$BC|HIPnDSFII)=vTfNztvek2Ylx0uoq9le?xU1G76s7gjTk5jZu3ixeoymUwhH|fv*9G))Ccm_@6<|zUd10s&-L-lm1*8V$w zWurEffp(k|@>VU=_OAjZ=Zq~d2DJ0@_db&yy_DOnKvL%TQc3IPP2Qd-@_#mKP;_ze z-r=KBhlq;y3>{94e$l&K1{i{7R#hU^)(9_!Ljh_*L66;p6}D?dq%WQBQZxx_!>;QA z7sGw!tu#shuXb8vZTp;AAwnX(-arYcxwee*%`wLsFdu_Ck*1{qyiW?8!X@CTHVmDi zbqyhAhE#+U$MoF4N5OPuN`k@=IgwmL9T}F}9PRj>iwvu>SncJ{jtO6)BDpFsOUtE@ zoC>)b#!D{=_-1UGpb;m86`;-`+pBO~S^e;7oAj}rFK{em%EV{bC-3pGq8zf1z}+4Cg^nne5)^$EgumFZRaJOo zwIv2B|2`{@ZNWUfswuT+&x88&$*&&om*HJPKsebYc_A`|}c>ShyI%>}#nZ~9d@g01@OvP#1SKEJSocF-E z^_y79ud_0)EDwizw=ag_W(6+5fia?^68oK!7EA6=KJ$Rva(`-6hbneP&iJaZ`rw<( zo@J;T209x845LYQ*$OP0v3f~}kDcnpl|wY~IW7C^?ra-QYJACm)cZr-n$E_tg@Gi~ ziRVxH81k-)J(Fr;_BhPpHW z`l84F%Y{QXLLGePba~Fa>mrBpUZnp!1{WcB$ZW0!r*#uO>KQJUU7Du8ZN9AgJlFoy z7C^+s^9MV}IJ({>9PLW_tJ3mPc92?CPpU~MLr|*xbl9q(9GR8~ajvybY6m=OclGUs zVV_rOeGW$%v-?ZD_}O0$hPG+(CLaymMvut z&vFo-M7gCLnZue79ugT(Vu?EBW_jVTC$R6f9Zl zR?RaCqbD{ns{Yk^iP6<)v2UA29Og)+wEcO|RSV)9N4Rz-F!1pgC@b`RR*j-4W^tkm z*?$MtlJT=<0bzD503b_|SO%M=`#GPJ=auF8+0lGF^`?7?kNJJd3?;!wpPG|bmao&+ znmU@&GCyYvWVl`+ zl4tKiZmzwF+UPGFD0xysq+F_x;P_75w{KqX{kdHCG*9p%bojQtmpW2NK zL)DzW5FCrmBdtZ z^mdDGx2ljxW84u!M46Y1>QPssJYFW0;w-2(FDTM-7fX{F(@(l)5&Nn!DpyQhfjpm0 z_{V{$v=)~N&6WRj3E2aDQeL~Lzf@h2Bo!N3+>lorJ_lJygKwn_R>F%;Ll8$@%~tdJ zwz#wD5?NAWF2@s_d*Fw3O`Z9m$`;85`kly33PM?6I{X@WJ(bQ7zRm|EB}%Eb;4Sdy zFfLE`Aom4cZ)e-+BN;^DG+D>J3XVGpI(oeLDl@J&Z;xmGo?4KcB#i!BZfcO&@YyzF zL-DbHP7}-R-C23~jJ*7AxP!Bdx6iYTt&TDx-I@J2|Fqg47|-HuAF!E>tqNon(-$D{ zIP1di$S=4z()?n3m3z4?*P&qKt+UEy%@J$j(?m%^xgcx( zzl-I<6TAf8N#T-bpdihhItveww9|gw^EI?< zp;T1_l#ZO8Ic?9bT}U$X>SfGaL{H zNYGJK5Fn6a0jk_B*sa|A;=@lPgyblV%Ru2+YOMbH+yDfBWkXb^RHoYXj}Cln6&;Vz zQM3V9)OP(-)o<~CFLy)tC_2%gg9{};crL59k)A)4nnoKYrxE31Ye!A6$>3o$j&{9W zrvNrdR>aFLqRzA1sPiSgg-oU>v)O${E6UNbmJ|h`!d5|mt!N3$57-2)LPHS=&e8u| zRdr=$v|`ux#EDyloB0C%X5m(NHQ4bmx~=hQqloVen{M9k5xLGaTIXA^;>6mD-Keu{ zTR~O6$39N!wxs4E_1@nhu#r^Sg;brM?d0beb5%KMD>WpOPa?ut78zSU%{2jSO{Z@< zpO+%n7_!AFeL5e#Poj#kF^cY*-UzmqiRi?aI;IW=M+Vafxhos_{Kl1p+_XV-vDvSU zYqB#n8atC~x>K7M!>>0+3f;we4}#vqU2K;r!6_OsL@xHb<5{$`v}mWNrBHO=z$A3Q zb9pi$r_9<{v;tqcqM)z%NyU9znPt9xA>Otye}3@;6tF=bhRQ1rq3iMX^_x=4KjuM@ z_}S1GKUsI*@J0N(3$f8&LtuWO&9K)72I^5ZdD2tHju3Ll4#xT~9@uo3(meJI;)i$6 znK-P2h&%Qdw>k21kxz~sk;@PnK~G)JDlt;i1eU0(NL_LwS+#f}=ghV#;JZ|(m8E%P zsM9ku5MIIibB+{6Fq>l{ucgUZbd`pB7=PZmdSL>Gu7B!?5^>eRuHHZ1kKL|~iq)Hy zIi6CZ(v+`-$-NFe=h@^pwW`|Q;_JRU@bFtpMzFWXvdH2jx>Q%K+ADmu8lt+QbNOkp=rwz+P^~qaG@cq&q8&Xcuq$9<>TJW6J9<(xut}1l==0G!w$_yY z!LwC{iY*Hfak9)wqh7ex)IyuxsV~NsG(u)r7k? zDOb&wGg5Zl{ytvI_7`b#;C%BGV|A*unzE|4J$h|+nIkbQ_Q1rL(Emop*Yr7r9`VnPXPhOPK;ZoYfkl1j3C_V<-rpC0D)JR9;Sf5pX&Z3H(3ieuc13 z^NbWrl!~1atIk8BEle;+LUF&k}3ocl6XHSrhaTk%-EPcz2&O6mMS%7(Y>Z z*F-wn{ERk3@rJy;MtfFuY^TgFbM&B(_Pu%Q4JBcks)W8B4pXu|Z@@%(%|PCU-#9Jx zQSa<<>0RPoDRh2{)0FnI)-!UbL*t27+_eCvijJ72W~6xrnE}^ueHs64rRFf!v-V0) znv$mcM);A&8f4;`gDl#Qgx{tlnNCU}{FCbLZ~bpijSqDy>8 zyTdio!PW|e)iF_06=HI^Fzz%jm3KPMo~Juz$CI#@WG@FiduOX>gXfYOb&ZPRz9qsl zY}{p?E|kM{L~x$B-DhV0m&9z~e6*5vmNZ_b4kgsYDHFFZjrARS`K?Dd;!_bLN(R2a zr&waYqg(lWQoifcOnH^7^>_MffgPCBz_Hl4lT1eLWJQh0ktxcICZAEVXKD6$se)0M zCQftoppPNbQcq&KOJ^z1v*wj)c~^19A!=m8rld^PvZQFq!)UCG1MEVkf*M0rBqWd$ zb2^!?T>nVQ6o0%cM--Ny8yymz%g09fPZlJO*dpIi5{w)JhpCDZQ^GyMDRJpgwdtju z`-p3QIWtTyn}=H>rD41oV8xr)2nD}W{-W=!j6E8T-%^z#n#U2D`C471*~ECWWobiC z@X<(_Rxa7j%-HiK>qwY4Uy`^#Itkdt#{4oHik2A+Xc=n5p`xBl%naY0QEw=w5wJstdJPH$$?Z$XrQ61d4kUia_lTdn;-crG5nAwyu$?`=sR=gPlbQ3s z{q`+&e)^nEnn!KgcNf(oQBTXR&-w04o=dY0P&`wEl*X? zi=V5WGWyVIX^;K77bN75!M{X?x+QVS6yF4@OJ&{|qGWMnOc(9ZB1^3l`({|5oT)I% zO-VuWJ(pF78No3>cVB-GFHrctIrLZ7G|@#B>91!>Ip~p*(GgYu>5h^k9rz<1 zMW;LZRhd`p8CXcl)EV?fs)O88Nl-%r)tkRxV#u^!kWdwe{m#)!M(dsy;_gt8Sj(0*a}fxf|{(!COJO zHPc+z)kj(HS954%r*JB$%C*QWtYck3t7Av*SLNe=S-%IcNkz@v+ymKF>%wQ`eQd9G z&PdxQi}^N%?(F_F5U*i$b1GLmu6^uzdWfAlWzVi%R6W!GP$E7dykMKHqrp;_)CSH` zbm?|iRef6mAFC#cLMH!mjYE3CLCXI}^pvaeLi}HXOhc^Vh;2 zZEB-eo#=~cG9<^H3Wu}-nX_sy`ca7#KN=&pD?cyS^T%kZT+B-r$TpPguR}yE(-?-2 zU`0oDjcxQio0_TRbK<`F0~bn7K_nSDOmmYqr)6ply{g%m?)N!%Ah?D^ay!CN$FV{QI;(FFEMuh zIs9)&7#u_h>g|Ks{dcWDrSMW@l9uhbiQ6ElGIi3or_cLF#l%u^6iH;*zHW`rv0G^a zp6!IM|DxW=@tK16(_TTz`!vkGr=R8>@s3r^1nNxKS6g zD#R~jRm?hmjg$;hwdv?KEgeRmJ9_jaj-nizy)qNF_lEX~4iEl>{kZr2=lmdbfJR#z&Qx7c|Wt?v`(x z-@?Q49rIgwTE1=hj^(@NxA3w&W`4`^#>es<%VU=Bo8Lm0iH-3e;)jWa?3lg;RnwpE z0v-+gef^{vU)=9L0$4sDd5_KupSf1U0Vs@{q<*2l0qts80lDf77B z2pFK8`*g*wxxe^Z^uoOWyglK@;r)AWYav3^0$+AjMh(M|}3&aA!&n9{G8X7UgCfLnce!@zVu7T}bM2}KG z11Bb~Q_o|{Or3Gg2x`T6H9;O6fDQuaVnz+49SALAV53x@fX69e}EdLbQ5V2mZ~JVW}^Cqv2tB#91Ms_t#uc^6lkZP>rAS*sc;a;X{VD419@sM5`(S(9cQ zR#j?rXyDSyu1c$NSazN!6<3;?qj`?z%|(m3F59a`cAYn+`_^TZY`w*#W6f*MLD;^F zJbdYBDiOoBYRkR1XJP*Ky+($O<8 zGJTsnbgdP?7iD8tz@d;+kzys{#A8a3CpD4`wAFR<-nQfczj>BC*rchhN!HJLhGF0l1BVPg;@}|%2Llgf@R1A- z4j%I3^V22pz>Xh0@xp;O22Ol%;dcbH!mU$UnF%tgHIl7mjyT zbhKAV(SH%m233A)gSXApmB7Xw?M`a!Oh?U`$NwSp`ie1&0`Y) literal 0 HcmV?d00001 diff --git a/web-standalone/assets/fonts/ibm-plex-mono-latin-600.woff2 b/web-standalone/assets/fonts/ibm-plex-mono-latin-600.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..c6759ef37d87a7bf2251f1d1f4704204e978ae3f GIT binary patch literal 10120 zcmV;3CwJI)Pew8T0RR9104In54gdfE0A0iY04FT~0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/web-standalone/assets/fonts/ibm-plex-sans-latin-var.woff2 b/web-standalone/assets/fonts/ibm-plex-sans-latin-var.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e5ebabbddc52459948f27539fb06d60db5fc2929 GIT binary patch literal 40240 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

@c9dd0tdWKJRyVy<;N5h+G* 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 literal 0 HcmV?d00001 diff --git a/web-standalone/index.html b/web-standalone/index.html index 633067c..2cf4346 100644 --- a/web-standalone/index.html +++ b/web-standalone/index.html @@ -16,18 +16,98 @@ [hidden] { display: none !important; } + /* ── DMC house style (#139) ────────────────────────────────────────── + Tokens, names and values from DutchMeshCore-Branding/STYLE-GUIDE.md. + Its first principle: raw hex lives ONLY in these :root blocks, and + every rule below consumes a var(). That is what keeps dark and light + in step, so resist reaching for a literal further down. */ + @font-face { + font-family: 'Aldrich'; + src: url('assets/fonts/aldrich-v22-latin-400.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; + } + @font-face { + font-family: 'IBM Plex Sans'; + src: url('assets/fonts/ibm-plex-sans-latin-var.woff2') format('woff2-variations'); + font-weight: 100 700; + font-style: normal; + font-display: swap; + } + @font-face { + font-family: 'IBM Plex Mono'; + src: url('assets/fonts/ibm-plex-mono-latin-400.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; + } + @font-face { + font-family: 'IBM Plex Mono'; + src: url('assets/fonts/ibm-plex-mono-latin-600.woff2') format('woff2'); + font-weight: 600; + font-style: normal; + font-display: swap; + } + :root { - --bg: #08141b; - --panel: rgba(7, 25, 35, 0.88); - --panel-border: rgba(143, 187, 201, 0.18); - --text: #f3fbff; - --muted: #9eb6c0; - /* Help text sits a step below --muted so a field's label always reads - louder than the sentence explaining it (#132). */ - --faint: #6b8794; - --accent: #00b894; - --accent-2: #ff9f43; - --shadow: 0 18px 50px rgba(0, 0, 0, 0.28); + color-scheme: dark; + + /* Brand constants — identical in both themes. */ + --red: #df2020; + --white: #f4f4f5; + --blue: #1976e8; + --green: #3ecf8e; + --yellow: #f5c542; + + /* Dark palette. */ + --bg: #060709; + --text: #e9edf4; + --text-muted: #b9c1cf; + --text-faint: #6b7480; + --heading: #ffffff; + --link: #61a8ff; + --accent: #1976e8; + --accent-light: #74adff; + --accent-strong: #93bfff; + --border: rgba(255, 255, 255, 0.14); + --border-strong: rgba(255, 255, 255, 0.22); + --surface-hover: rgba(255, 255, 255, 0.055); + --code-bg: rgba(0, 0, 0, 0.38); + + /* Semantic state — used for meaning, never the raw brand tokens. */ + --success: var(--green); + --warning: var(--yellow); + --danger: var(--red); + --danger-text: #ff8080; + + /* Glass over glow. */ + --surface: + linear-gradient(135deg, rgba(255, 255, 255, 0.07), transparent 34%), + linear-gradient(180deg, rgba(22, 24, 29, 0.94), rgba(6, 7, 10, 0.95)); + --surface-2: rgba(8, 10, 13, 0.80); + --surface-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.035), 0 18px 40px rgba(0, 0, 0, 0.35); + --body-bg: + radial-gradient(circle at 18% 18%, rgba(223, 32, 32, 0.15), transparent 28%), + radial-gradient(circle at 82% 28%, rgba(25, 118, 232, 0.14), transparent 30%), + linear-gradient(180deg, #090b10 0%, #06070a 48%, #030304 100%); + --sheen-opacity: 0.15; + --grid-opacity: 0.28; + --scan-opacity: 0.11; + + /* Type. */ + --font-sans: 'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, Roboto, sans-serif; + --font-head: 'Aldrich', 'Segoe UI', system-ui, sans-serif; + --font-mono: 'IBM Plex Mono', ui-monospace, Consolas, 'Fira Mono', monospace; + --heading-shadow: 0 3px 0 #000; + --fs-sm: 12px; + --fs-md: 14px; + --fs-lg: 16px; + --fs-xl: 18px; + + /* Geometry: one base radius for controls, one for large surfaces. */ + --radius: 8px; + --radius-lg: 16px; } * { @@ -37,12 +117,66 @@ body { margin: 0; min-height: 100vh; - font-family: "Avenir Next", Avenir, "Segoe UI", sans-serif; + font-family: var(--font-sans); color: var(--text); - background: - radial-gradient(circle at top left, rgba(0, 184, 148, 0.18), transparent 32%), - radial-gradient(circle at top right, rgba(255, 159, 67, 0.16), transparent 30%), - linear-gradient(180deg, #0a1b24 0%, #071118 100%); + /* Red glow top-left, blue top-right, over a dark fade. The house + "glass over glow" ground (#139); it was teal and orange. */ + background-color: var(--bg); + background-image: var(--body-bg); + background-attachment: fixed; + position: relative; + } + + /* Grid and scanlines (STYLE-GUIDE §6). Both sit under the content and + above the ground, and both go to zero opacity in light mode. */ + body::before, + body::after { + content: ""; + position: fixed; + inset: 0; + pointer-events: none; + z-index: 0; + } + body::before { + background-image: + linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(255, 255, 255, 0.024) 1px, transparent 1px); + background-size: 42px 42px; + -webkit-mask-image: radial-gradient(ellipse at 50% 30%, #000 0%, transparent 78%); + mask-image: radial-gradient(ellipse at 50% 30%, #000 0%, transparent 78%); + opacity: var(--grid-opacity); + } + body::after { + background-image: repeating-linear-gradient(0deg, + rgba(255, 255, 255, 0.043), + rgba(255, 255, 255, 0.043) 1px, + transparent 1px, + transparent 4px); + mix-blend-mode: overlay; + opacity: var(--scan-opacity); + } + /* Everything the operator touches sits above the two overlays. */ + .topbar, + .shell, + .intro-overlay, + .loading-overlay { + position: relative; + z-index: 1; + } + + /* Headings and the brand run in the display face, uppercased, with a hard + drop shadow that light mode drops (STYLE-GUIDE §3). */ + h1, h2, h3, + .step-kicker, + .topbar-title { + font-family: var(--font-head); + text-transform: uppercase; + letter-spacing: 0.03em; + color: var(--heading); + text-shadow: var(--heading-shadow); + } + code, kbd, samp, pre { + font-family: var(--font-mono); } /* Full-width bar above everything: dutchmeshcore.nl branding + community @@ -57,19 +191,17 @@ flex-wrap: wrap; width: min(1200px, calc(100% - 32px)); margin: 16px auto 0; - padding: 10px 16px 10px 20px; - border-radius: 12px; - background: #0b0d12; - border: 1px solid rgba(255, 255, 255, 0.08); - } - .topbar-stripe { - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 4px; - border-radius: 12px 0 0 12px; - background: linear-gradient(180deg, #c8102e 0%, #c8102e 33%, #ffffff 33%, #ffffff 66%, #21468b 66%, #21468b 100%); + padding: 10px 16px; + border-radius: var(--radius); + background: var(--surface-2); + border: 1px solid var(--border); + } + /* Every DMC surface opens with this band (STYLE-GUIDE §9): full width, in + normal flow, above the navbar. It was a 4px vertical bar beside the + topbar, which is the same idea in the wrong orientation. */ + .page-stripe { + height: var(--stripe-h); + background: linear-gradient(90deg, var(--red), var(--white) 50%, var(--blue)); } .topbar-brand { display: flex; @@ -81,7 +213,7 @@ width: 24px; height: 24px; border-radius: 6px; - background: linear-gradient(135deg, #c8102e, #21468b); + background: linear-gradient(135deg, var(--red), var(--blue)); display: flex; align-items: center; justify-content: center; @@ -101,11 +233,11 @@ align-items: center; gap: 14px; font-size: 0.8rem; - color: var(--muted); + color: var(--text-muted); flex-wrap: wrap; } .topbar-nav a { - color: var(--muted); + color: var(--text-muted); text-decoration: none; white-space: nowrap; } @@ -135,10 +267,10 @@ gap: 6px 16px; padding: 12px 14px; min-width: 260px; - border-radius: 12px; + border-radius: var(--radius); background: rgba(7, 25, 35, 0.97); border: 1px solid rgba(143, 187, 201, 0.18); - box-shadow: var(--shadow); + box-shadow: var(--surface-shadow); z-index: 20; } .topbar-dropdown-menu a { @@ -160,10 +292,10 @@ justify-content: center; line-height: 1; font-size: 0.8rem; - border-radius: 9px; + border-radius: var(--radius); border: 1px solid rgba(255, 255, 255, 0.12); background: rgba(255, 255, 255, 0.04); - color: var(--muted); + color: var(--text-muted); cursor: pointer; } .topbar-meta .is-icon:hover { @@ -180,12 +312,12 @@ .topbar-github { flex: 0 0 auto; - border-radius: 10px; + border-radius: var(--radius); padding: 6px 12px; font-weight: 600; font-size: 0.8rem; background: rgba(255, 255, 255, 0.04); - color: var(--muted); + color: var(--text-muted); border: 1px solid rgba(255, 255, 255, 0.12); text-decoration: none; } @@ -205,10 +337,10 @@ } .map-wrap { - background: var(--panel); - border: 1px solid var(--panel-border); - border-radius: 24px; - box-shadow: var(--shadow); + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + box-shadow: var(--surface-shadow); backdrop-filter: blur(16px); } @@ -228,7 +360,7 @@ align-items: center; gap: 8px; padding: 8px 10px; - border-radius: 14px; + border-radius: var(--radius); background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.08); } @@ -236,7 +368,7 @@ font-size: 0.64rem; letter-spacing: 0.09em; text-transform: uppercase; - color: var(--faint); + color: var(--text-faint); margin-right: 2px; } /* Share is the one control here that is not about the map, so it sits at @@ -258,14 +390,14 @@ z-index: 20; width: 250px; padding: 10px 12px; - border-radius: 12px; + border-radius: var(--radius); background: rgba(7, 25, 35, 0.97); border: 1px solid rgba(143, 187, 201, 0.28); - box-shadow: var(--shadow); + box-shadow: var(--surface-shadow); } .controls-card button { margin: 0; - border-radius: 10px; + border-radius: var(--radius); padding: 7px 12px; font: inherit; font-weight: 600; @@ -290,7 +422,7 @@ flex: 1 0 100%; margin: 0; font-size: 0.74rem; - color: var(--muted); + color: var(--text-muted); } .share-status.is-copied { color: var(--accent); @@ -299,17 +431,17 @@ flex: 1 0 100%; margin: 0; font-size: 0.74rem; - color: var(--muted); + color: var(--text-muted); } .share-fallback input { width: 100%; margin-top: 4px; padding: 7px 9px; - border-radius: 9px; + border-radius: var(--radius); border: 1px solid rgba(0, 184, 148, 0.35); background: rgba(5, 15, 22, 0.9); color: var(--text); - font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-family: var(--font-mono); font-size: 0.72rem; } @@ -362,7 +494,7 @@ width: 8px; height: 8px; border-radius: 50%; - background: var(--accent-2); + background: var(--warning); } .whats-new-panel { position: absolute; @@ -375,10 +507,10 @@ max-height: 360px; overflow-y: auto; padding: 12px 14px; - border-radius: 16px; + border-radius: var(--radius-lg); background: rgba(7, 25, 35, 0.97); border: 1px solid rgba(143, 187, 201, 0.18); - box-shadow: var(--shadow); + box-shadow: var(--surface-shadow); } .whats-new-entry { padding: 8px 0; @@ -390,7 +522,7 @@ .whats-new-entry time { display: block; font-size: 0.72rem; - color: var(--muted); + color: var(--text-muted); } .whats-new-entry strong { display: block; @@ -400,7 +532,7 @@ .whats-new-entry p { margin: 0; font-size: 0.82rem; - color: var(--muted); + color: var(--text-muted); line-height: 1.4; } @@ -429,7 +561,7 @@ gap: 4px; margin: 0; font-size: 0.72rem; - color: var(--muted); + color: var(--text-muted); } .radius-row input { width: 100%; } @@ -444,7 +576,7 @@ grid-template-columns: 1fr 1fr; gap: 3px; padding: 3px; - border-radius: 12px; + border-radius: var(--radius); background: rgba(255, 255, 255, 0.045); border: 1px solid rgba(255, 255, 255, 0.08); margin-bottom: 14px; @@ -453,14 +585,14 @@ .step-panel .entry-tabs .entry-tab { margin: 0; border: 0; - border-radius: 9px; + border-radius: var(--radius); padding: 7px 6px; font-size: 0.78rem; font-weight: 500; background: transparent; /* --faint is for text that recedes under a label; a tab is a control you have to be able to read and click. */ - color: var(--muted); + color: var(--text-muted); box-shadow: none; } .step-panel .entry-tabs .entry-tab[aria-pressed="true"] { @@ -483,7 +615,7 @@ .hop2-details summary { cursor: pointer; list-style: none; - color: var(--muted); + color: var(--text-muted); font-size: 0.8rem; } .hop2-details summary::-webkit-details-marker { display: none; } @@ -498,7 +630,7 @@ .step-panel select.import-select { width: 100%; - border-radius: 12px; + border-radius: var(--radius); border: 1px solid rgba(255, 255, 255, 0.12); background: rgba(5, 15, 22, 0.9); color: var(--text); @@ -531,7 +663,7 @@ margin: 5px 0 0; font-size: 0.75rem; line-height: 1.45; - color: var(--faint); + color: var(--text-faint); } .step-panel p.hint:empty { display: none; @@ -540,14 +672,14 @@ margin: 6px 0 0; font-size: 0.72rem; line-height: 1.45; - font-family: ui-monospace, SFMono-Regular, Menlo, monospace; - color: var(--muted); + font-family: var(--font-mono); + color: var(--text-muted); padding-left: 9px; border-left: 2px solid var(--accent); } /* A caveat is not the same as a result (#54, #85). */ .step-panel p.hint.is-caveat { - border-left-color: var(--accent-2); + border-left-color: var(--warning); } /* A field group needs air before the next one starts, or the reply line still reads as the next label's opening words (#132). */ @@ -556,19 +688,19 @@ margin-top: 14px; } .step-panel .label-optional { - color: var(--faint); + color: var(--text-faint); font-weight: 400; font-size: 0.94em; } /* An inline example of what to type, instead of the literal backticks that used to ship as UI text. */ .step-panel .sample { - font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-family: var(--font-mono); font-size: 0.92em; background: rgba(255, 255, 255, 0.06); border-radius: 4px; padding: 1px 5px; - color: var(--muted); + color: var(--text-muted); } /* Nothing styled links inside the panels, so the browser default #0000EE landed on a dark teal card (#132). */ @@ -592,7 +724,7 @@ .node-meta { margin: 0; - color: var(--muted); + color: var(--text-muted); line-height: 1.5; font-size: 0.93rem; } @@ -607,9 +739,10 @@ .step-panel, .utility-panel { padding: 14px 16px; - border-radius: 18px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: var(--radius-lg); + background: var(--surface); + border: 1px solid var(--border); + box-shadow: var(--surface-shadow); } .utility-panel { @@ -656,7 +789,7 @@ .step-panel .step-head h3 { grid-area: title; } .step-panel .step-head .step-chev { grid-area: chevron; - color: var(--faint); + color: var(--text-faint); font-size: 0.7rem; transition: transform 0.15s ease; } @@ -716,13 +849,13 @@ .prefix-panel label { display: block; margin-bottom: 8px; - color: var(--muted); + color: var(--text-muted); font-size: 0.84rem; } .prefix-panel input { width: 100%; - border-radius: 12px; + border-radius: var(--radius); border: 1px solid rgba(255, 255, 255, 0.12); background: rgba(5, 15, 22, 0.9); color: var(--text); @@ -732,7 +865,7 @@ .prefix-panel p { margin: 10px 0 0; - color: var(--muted); + color: var(--text-muted); font-size: 0.84rem; line-height: 1.45; } @@ -756,10 +889,10 @@ .workflow-step { padding: 10px 12px; - border-radius: 12px; + border-radius: var(--radius); border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.03); - color: var(--muted); + color: var(--text-muted); font-size: 0.84rem; line-height: 1.4; } @@ -801,7 +934,7 @@ .step-panel input, .utility-panel input { width: 100%; - border-radius: 12px; + border-radius: var(--radius); border: 1px solid rgba(255, 255, 255, 0.12); background: rgba(5, 15, 22, 0.9); color: var(--text); @@ -814,11 +947,11 @@ .step-panel button { margin-top: 12px; border: 0; - border-radius: 12px; + border-radius: var(--radius); padding: 10px 14px; font: inherit; font-weight: 600; - color: #071118; + color: var(--bg); background: var(--accent); cursor: pointer; } @@ -834,7 +967,7 @@ text-align: center; text-decoration: none; border: 1px solid rgba(255, 255, 255, 0.16); - border-radius: 12px; + border-radius: var(--radius); padding: 9px 14px; font: inherit; font-weight: 600; @@ -868,7 +1001,7 @@ .button-muted, .step-panel button.button-muted { background: rgba(255, 255, 255, 0.04); - color: var(--muted); + color: var(--text-muted); border: 1px solid rgba(255, 255, 255, 0.12); } @@ -945,7 +1078,7 @@ width: 7px; height: 7px; border-radius: 999px; - background: #9be564; + background: var(--success); flex: 0 0 auto; } @@ -953,7 +1086,7 @@ .step-panel p, .utility-panel p { margin: 10px 0 0; - color: var(--muted); + color: var(--text-muted); font-size: 0.84rem; line-height: 1.45; } @@ -989,7 +1122,7 @@ background: rgba(7, 17, 24, 0.45); color: var(--text); border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 14px; + border-radius: var(--radius); padding: 10px 12px; cursor: pointer; } @@ -1031,7 +1164,7 @@ /* --muted measured against the composited card surface: 7.01:1 at rest, 6.41:1 on hover, 5.25:1 selected, taking the worst backdrop zone. */ .step-panel .candidate-card span { - color: var(--muted); + color: var(--text-muted); font-size: 0.8rem; line-height: 1.35; } @@ -1048,7 +1181,7 @@ gap: 8px; align-items: center; padding: 5px 8px; - border-radius: 10px; + border-radius: var(--radius); background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.07); } @@ -1110,7 +1243,7 @@ } .observer-copy span { - color: var(--muted); + color: var(--text-muted); font-size: 0.72rem; line-height: 1.3; white-space: nowrap; @@ -1126,16 +1259,16 @@ font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase; - background: rgba(255, 159, 67, 0.16); - color: #ffb86b; - border: 1px solid rgba(255, 159, 67, 0.3); + background: color-mix(in srgb, var(--warning) 16%, transparent); + color: var(--warning); + border: 1px solid color-mix(in srgb, var(--warning) 35%, transparent); cursor: help; } .observer-reason.is-range { - background: rgba(124, 58, 237, 0.18); - color: #c4b5fd; - border-color: rgba(124, 58, 237, 0.35); + background: color-mix(in srgb, var(--accent) 18%, transparent); + color: var(--accent-strong); + border-color: color-mix(in srgb, var(--accent) 45%, transparent); } .observer-support { margin-top: 6px; @@ -1145,7 +1278,7 @@ .observer-support > summary { cursor: pointer; list-style: none; - color: #c4b5fd; + color: var(--text-muted); font-size: 0.74rem; padding: 5px 2px; user-select: none; @@ -1159,7 +1292,7 @@ was what made every observer row 60px (#134). */ .step-panel .observer-weight { width: 100%; - border-radius: 8px; + border-radius: var(--radius); border: 1px solid rgba(255, 255, 255, 0.12); background: rgba(5, 15, 22, 0.9); color: var(--text); @@ -1196,9 +1329,9 @@ #map3d { width: 100%; height: 100%; - border-radius: 18px; + border-radius: var(--radius-lg); overflow: hidden; - background: #071118; + background: var(--bg); } /* MapLibre popups (#91). The old Leaflet popup got a dark text colour from @@ -1215,10 +1348,10 @@ .maplibregl-popup .maplibregl-popup-content { background: rgba(7, 25, 35, 0.96); color: var(--text); - border: 1px solid var(--panel-border); - border-radius: 14px; + border: 1px solid var(--border); + border-radius: var(--radius); padding: 12px 14px; - box-shadow: var(--shadow); + box-shadow: var(--surface-shadow); font: inherit; font-size: 0.82rem; } @@ -1236,7 +1369,7 @@ .maplibregl-popup .maplibregl-popup-close-button { background: transparent; border: 0; - color: var(--muted); + color: var(--text-muted); font-size: 1.1rem; line-height: 1; padding: 2px 7px; @@ -1264,7 +1397,7 @@ font-size: 15px; line-height: 14px; text-align: center; - color: #8ef0d1; + color: var(--accent-light); /* Outlined both ways: the basemap under a link can be near-white farmland or near-black water. */ text-shadow: @@ -1277,10 +1410,10 @@ margin-top: 8px; width: 100%; padding: 6px 8px; - border-radius: 8px; - border: 1px solid rgba(225, 29, 72, 0.5); - background: rgba(225, 29, 72, 0.16); - color: #ff8aa6; + border-radius: var(--radius); + border: 1px solid color-mix(in srgb, var(--danger) 50%, transparent); + background: color-mix(in srgb, var(--danger) 16%, transparent); + color: var(--danger-text); font: inherit; font-size: 0.8rem; cursor: pointer; @@ -1335,8 +1468,8 @@ max-height: 85vh; border-radius: 20px; background: rgba(7, 25, 35, 0.97); - border: 1px solid var(--panel-border); - box-shadow: var(--shadow); + border: 1px solid var(--border); + box-shadow: var(--surface-shadow); } .intro-head { padding: 20px 20px 0; @@ -1349,7 +1482,7 @@ .intro-lede { margin: 0; font-size: 0.78rem; - color: var(--muted); + color: var(--text-muted); line-height: 1.45; } .intro-body { @@ -1384,7 +1517,7 @@ .intro-detail { margin: 0 0 8px 29px; font-size: 0.75rem; - color: var(--muted); + color: var(--text-muted); line-height: 1.5; } .intro-detail code { @@ -1404,7 +1537,7 @@ .intro-sub p { margin: 0; font-size: 0.75rem; - color: var(--muted); + color: var(--text-muted); line-height: 1.5; } .intro-sub p.intro-sub-title { @@ -1417,17 +1550,17 @@ gap: 10px; padding: 12px 20px 16px; margin-top: 4px; - border-top: 1px solid var(--panel-border); + border-top: 1px solid var(--border); } .intro-hint, .intro-loading { flex: 1; min-width: 0; font-size: 0.7rem; - color: var(--muted); + color: var(--text-muted); } .intro-hint strong { - color: var(--muted); + color: var(--text-muted); font-weight: 600; } .intro-loading { @@ -1448,7 +1581,7 @@ .intro-foot button { flex: none; margin: 0; - border-radius: 10px; + border-radius: var(--radius); padding: 7px 15px; font: inherit; font-weight: 600; @@ -1462,7 +1595,7 @@ border-radius: 20px; background: rgba(7, 25, 35, 0.96); border: 1px solid rgba(143, 187, 201, 0.18); - box-shadow: var(--shadow); + box-shadow: var(--surface-shadow); text-align: center; } .loading-spinner { @@ -1487,7 +1620,7 @@ margin-top: 6px; font-size: 0.72rem; font-weight: 400; - color: var(--muted); + color: var(--text-muted); } @@ -1505,7 +1638,7 @@ align-items: baseline; gap: 8px; font-size: 0.74rem; - color: var(--muted); + color: var(--text-muted); margin-bottom: 6px; } @@ -1516,7 +1649,7 @@ .terrain-control input[type="range"] { width: 100%; - accent-color: #9be564; + accent-color: var(--accent); margin: 0; } @@ -1524,7 +1657,7 @@ margin: 7px 0 0; font-size: 0.66rem; line-height: 1.35; - color: var(--muted); + color: var(--text-muted); } @media (max-width: 860px) { @@ -1659,8 +1792,8 @@ +

-
DMC MeshCore Triangulator From 8168d19884ed8a0637b0e1da0fa8d06e020a2dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20H=C3=A4gele?= Date: Thu, 10 Sep 2026 13:50:02 +0200 Subject: [PATCH 2/6] feat(web-standalone): add the light theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second of three on #139. The app had no light theme at all — no data-theme, no prefers-color-scheme, nothing. Light is an override on the same token names, so no rule below the :root blocks changed. Dark stays the default: no attribute on means dark. A pre-paint script in applies the saved choice before the stylesheet renders, so a light user never gets a flash of dark, and color-scheme is set per root block so native selects and scrollbars follow. The picker is dark | light | system, persisted under the canonical meshcore-theme key so the choice carries across the DMC subdomains, following system as it changes. It reuses the topbar's existing
dropdown so the bar has one pattern, with the guide's menuitemradio + checkmark semantics. Getting there meant tokenising 64 more rgba() literals by role — fields, menus, scrims, hover fills, borders — since a hardcoded rgba(5,15,22,.9) field stays dark whatever the theme says. Their dark values also moved off the old teal tints onto the neutral near-black ground. Two literals stay: the text-shadow outline on map labels, which has to read against a basemap that is light in both themes. Refs #139 Co-Authored-By: Claude Opus 5 --- web-standalone/index.html | 313 ++++++++++++++++++++++++++++---------- 1 file changed, 235 insertions(+), 78 deletions(-) diff --git a/web-standalone/index.html b/web-standalone/index.html index 2cf4346..74084a7 100644 --- a/web-standalone/index.html +++ b/web-standalone/index.html @@ -4,6 +4,16 @@ MC Repeater Map + means dark. */ + :root[data-theme="light"] { + color-scheme: light; + + --bg: #f4f6fb; + --text: #1a1c2e; + --text-muted: #5c6487; + --text-faint: #8a90ab; + --heading: #1a1c2e; + --link: #3d6fdb; + --accent: #3d6fdb; + --accent-light: #5b86e5; + --accent-strong: #3455b0; + --border: #cdd2e8; + --border-strong: #b5bce0; + --surface-hover: #eef0f8; + --code-bg: rgba(20, 30, 60, 0.06); + + --success: #1a9e6e; + --warning: #a07008; + --danger: #c43a3a; + --danger-text: #c43a3a; + + --surface: #ffffff; + --surface-2: #eef0f8; + --surface-shadow: 0 10px 26px rgba(20, 30, 60, 0.08); + /* Flat ground, and the two overlays switched off by their tokens. */ + --body-bg: none; + --sheen-opacity: 0; + --grid-opacity: 0; + --scan-opacity: 0; + + --heading-shadow: none; + + --field-bg: #ffffff; + --menu-bg: #ffffff; + --chip-bg: #eef0f8; + --scrim: rgba(26, 28, 46, 0.35); + --raised: rgba(20, 30, 60, 0.06); + } + * { box-sizing: border-box; } @@ -268,14 +330,58 @@ padding: 12px 14px; min-width: 260px; border-radius: var(--radius); - background: rgba(7, 25, 35, 0.97); - border: 1px solid rgba(143, 187, 201, 0.18); + background: var(--menu-bg); + border: 1px solid var(--border); box-shadow: var(--surface-shadow); z-index: 20; } .topbar-dropdown-menu a { font-size: 0.82rem; } + /* Theme picker: chip trigger, checkable menu (STYLE-GUIDE §9). */ + .theme-dd > summary { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 9px; + border: 1px solid var(--border); + background: var(--surface-hover); + font-size: 0.8rem; + line-height: 1; + } + .theme-dd > summary::after { content: none; } + .theme-dd > summary:hover { border-color: var(--accent); } + .theme-menu { + left: auto; + right: 0; + min-width: 150px; + grid-template-columns: 1fr; + gap: 2px; + padding: 6px; + } + .theme-menu button { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + width: 100%; + margin: 0; + padding: 7px 9px; + border: 0; + border-radius: var(--radius); + background: none; + color: var(--text-muted); + font: inherit; + font-size: 0.82rem; + cursor: pointer; + text-align: left; + } + .theme-menu button:hover { background: var(--surface-hover); color: var(--text); } + .theme-menu .chk { color: var(--accent); visibility: hidden; } + .theme-menu button[aria-checked="true"] { color: var(--text); } + .theme-menu button[aria-checked="true"] .chk { visibility: visible; } .topbar-meta { margin-left: auto; display: flex; @@ -293,13 +399,13 @@ line-height: 1; font-size: 0.8rem; border-radius: var(--radius); - border: 1px solid rgba(255, 255, 255, 0.12); - background: rgba(255, 255, 255, 0.04); + border: 1px solid var(--border); + background: var(--surface-hover); color: var(--text-muted); cursor: pointer; } .topbar-meta .is-icon:hover { - background: rgba(255, 255, 255, 0.09); + background: var(--raised); color: var(--text); } /* The panel hangs off the topbar now, so it opens downward from the right @@ -316,13 +422,13 @@ padding: 6px 12px; font-weight: 600; font-size: 0.8rem; - background: rgba(255, 255, 255, 0.04); + background: var(--surface-hover); color: var(--text-muted); - border: 1px solid rgba(255, 255, 255, 0.12); + border: 1px solid var(--border); text-decoration: none; } .topbar-github:hover { - background: rgba(255, 255, 255, 0.08); + background: var(--border); color: var(--text); } @@ -361,8 +467,8 @@ gap: 8px; padding: 8px 10px; border-radius: var(--radius); - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.08); + background: var(--chip-bg); + border: 1px solid var(--border); } .layer-chips-label { font-size: 0.64rem; @@ -391,8 +497,8 @@ width: 250px; padding: 10px 12px; border-radius: var(--radius); - background: rgba(7, 25, 35, 0.97); - border: 1px solid rgba(143, 187, 201, 0.28); + background: var(--menu-bg); + border: 1px solid var(--border-strong); box-shadow: var(--surface-shadow); } .controls-card button { @@ -407,8 +513,8 @@ /* 3D View is a toggle, not a one-way "open" (#29): the same control enters and exits the mode, so it needs a visible pressed state. */ .controls-card button[aria-pressed="true"] { - background: rgba(0, 184, 148, 0.16); - border-color: rgba(0, 184, 148, 0.55); + background: color-mix(in srgb, var(--accent) 16%, transparent); + border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--accent); } /* Share (#34): confirmation text and the manual-copy fallback both take @@ -438,8 +544,8 @@ margin-top: 4px; padding: 7px 9px; border-radius: var(--radius); - border: 1px solid rgba(0, 184, 148, 0.35); - background: rgba(5, 15, 22, 0.9); + border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); + background: var(--field-bg); color: var(--text); font-family: var(--font-mono); font-size: 0.72rem; @@ -508,13 +614,13 @@ overflow-y: auto; padding: 12px 14px; border-radius: var(--radius-lg); - background: rgba(7, 25, 35, 0.97); - border: 1px solid rgba(143, 187, 201, 0.18); + background: var(--menu-bg); + border: 1px solid var(--border); box-shadow: var(--surface-shadow); } .whats-new-entry { padding: 8px 0; - border-top: 1px solid rgba(255, 255, 255, 0.08); + border-top: 1px solid var(--border); } .whats-new-entry:first-child { border-top: none; @@ -577,8 +683,8 @@ gap: 3px; padding: 3px; border-radius: var(--radius); - background: rgba(255, 255, 255, 0.045); - border: 1px solid rgba(255, 255, 255, 0.08); + background: var(--chip-bg); + border: 1px solid var(--border); margin-bottom: 14px; } /* Beats `.step-panel button` (0,1,1) on the accent fill and the margin. */ @@ -596,10 +702,10 @@ box-shadow: none; } .step-panel .entry-tabs .entry-tab[aria-pressed="true"] { - background: rgba(0, 184, 148, 0.18); + background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--text); font-weight: 600; - box-shadow: inset 0 0 0 1px rgba(0, 184, 148, 0.35); + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent); } .step-panel .entry-tabs .entry-tab:hover { color: var(--text); @@ -609,7 +715,7 @@ /* The uncommon half of Step 1, closed until asked for (#133). */ .hop2-details { margin-top: 14px; - border-top: 1px solid rgba(255, 255, 255, 0.08); + border-top: 1px solid var(--border); padding-top: 12px; } .hop2-details summary { @@ -631,8 +737,8 @@ .step-panel select.import-select { width: 100%; border-radius: var(--radius); - border: 1px solid rgba(255, 255, 255, 0.12); - background: rgba(5, 15, 22, 0.9); + border: 1px solid var(--border); + background: var(--field-bg); color: var(--text); padding: 12px; font: inherit; @@ -697,7 +803,7 @@ .step-panel .sample { font-family: var(--font-mono); font-size: 0.92em; - background: rgba(255, 255, 255, 0.06); + background: var(--chip-bg); border-radius: 4px; padding: 1px 5px; color: var(--text-muted); @@ -708,7 +814,7 @@ .utility-panel a { color: var(--accent); text-underline-offset: 2px; - text-decoration-color: rgba(0, 184, 148, 0.45); + text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); } .step-panel a:hover, .utility-panel a:hover { @@ -856,8 +962,8 @@ .prefix-panel input { width: 100%; border-radius: var(--radius); - border: 1px solid rgba(255, 255, 255, 0.12); - background: rgba(5, 15, 22, 0.9); + border: 1px solid var(--border); + background: var(--field-bg); color: var(--text); padding: 12px; font: inherit; @@ -890,8 +996,8 @@ .workflow-step { padding: 10px 12px; border-radius: var(--radius); - border: 1px solid rgba(255, 255, 255, 0.08); - background: rgba(255, 255, 255, 0.03); + border: 1px solid var(--border); + background: var(--surface-hover); color: var(--text-muted); font-size: 0.84rem; line-height: 1.4; @@ -905,13 +1011,13 @@ } .workflow-step.is-active { - border-color: rgba(155, 229, 100, 0.35); - background: rgba(155, 229, 100, 0.1); + border-color: color-mix(in srgb, var(--success) 35%, transparent); + background: color-mix(in srgb, var(--success) 10%, transparent); } .workflow-step.is-done { - border-color: rgba(0, 184, 148, 0.32); - background: rgba(0, 184, 148, 0.12); + border-color: color-mix(in srgb, var(--accent) 32%, transparent); + background: color-mix(in srgb, var(--accent) 12%, transparent); } .source-grid { @@ -935,8 +1041,8 @@ .utility-panel input { width: 100%; border-radius: var(--radius); - border: 1px solid rgba(255, 255, 255, 0.12); - background: rgba(5, 15, 22, 0.9); + border: 1px solid var(--border); + background: var(--field-bg); color: var(--text); padding: 12px; font: inherit; @@ -966,19 +1072,19 @@ display: block; text-align: center; text-decoration: none; - border: 1px solid rgba(255, 255, 255, 0.16); + border: 1px solid var(--raised); border-radius: var(--radius); padding: 9px 14px; font: inherit; font-weight: 600; color: var(--text); - background: rgba(255, 255, 255, 0.05); + background: var(--chip-bg); cursor: pointer; } .utility-panel button:hover, .utility-panel .button-secondary:hover { - background: rgba(255, 255, 255, 0.10); - border-color: rgba(255, 255, 255, 0.26); + background: var(--raised); + border-color: var(--border-strong); } .button-row { @@ -990,19 +1096,19 @@ .button-secondary, .step-panel button.button-secondary { - background: rgba(255, 255, 255, 0.06); + background: var(--chip-bg); color: var(--text); - border: 1px solid rgba(255, 255, 255, 0.16); + border: 1px solid var(--raised); } .step-panel button.button-secondary:hover { - background: rgba(255, 255, 255, 0.10); + background: var(--raised); } .button-muted, .step-panel button.button-muted { - background: rgba(255, 255, 255, 0.04); + background: var(--surface-hover); color: var(--text-muted); - border: 1px solid rgba(255, 255, 255, 0.12); + border: 1px solid var(--border); } /* Focus visibility + disabled states (accessibility polish). */ @@ -1029,7 +1135,7 @@ was never applied by anything, so it is reused rather than a second mode concept being invented next to it. */ .map-wrap.is-draw-mode { - outline: 2px solid rgba(155, 229, 100, 0.4); + outline: 2px solid color-mix(in srgb, var(--success) 40%, transparent); } .manual-banner { @@ -1044,8 +1150,8 @@ max-width: min(420px, calc(100% - 70px)); padding: 6px 12px; border-radius: 999px; - background: rgba(7, 25, 35, 0.92); - border: 1px solid rgba(155, 229, 100, 0.5); + background: var(--menu-bg); + border: 1px solid color-mix(in srgb, var(--success) 50%, transparent); color: var(--text); font-size: 0.76rem; font-weight: 600; @@ -1059,7 +1165,7 @@ .manual-banner button { margin: 0; padding: 3px 9px; - border: 1px solid rgba(155, 229, 100, 0.6); + border: 1px solid color-mix(in srgb, var(--success) 60%, transparent); border-radius: 999px; background: transparent; color: var(--text); @@ -1119,9 +1225,9 @@ margin-top: 0; text-align: left; font-weight: 400; - background: rgba(7, 17, 24, 0.45); + background: var(--scrim); color: var(--text); - border: 1px solid rgba(255, 255, 255, 0.08); + border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; cursor: pointer; @@ -1131,7 +1237,7 @@ which is near-invisible on a surface this dark. Hover lifts the card towards the panel rather than washing it white. */ .step-panel .candidate-card:hover { - background: rgba(7, 17, 24, 0.30); + background: var(--surface-hover); border-color: rgba(255, 255, 255, 0.22); filter: none; } @@ -1140,14 +1246,14 @@ on. The inset bar carries the state on its own, so the tint never has to be strong enough to hurt the text sitting on it. */ .step-panel .candidate-card.is-selected { - border-color: rgba(155, 229, 100, 0.55); + border-color: color-mix(in srgb, var(--success) 55%, transparent); /* Two layers, not two colours: the lime wash sits ON the same dark tint as a resting card, so selection changes the hue without giving back the contrast the dark tint bought. */ background: - linear-gradient(rgba(155, 229, 100, 0.12), rgba(155, 229, 100, 0.12)), - rgba(7, 17, 24, 0.45); - box-shadow: inset 3px 0 0 rgba(155, 229, 100, 0.8); + linear-gradient(color-mix(in srgb, var(--success) 12%, transparent), color-mix(in srgb, var(--success) 12%, transparent)), + var(--scrim); + box-shadow: inset 3px 0 0 color-mix(in srgb, var(--success) 80%, transparent); } .step-panel .candidate-card strong, @@ -1182,7 +1288,7 @@ align-items: center; padding: 5px 8px; border-radius: var(--radius); - background: rgba(255, 255, 255, 0.04); + background: var(--surface-hover); border: 1px solid rgba(255, 255, 255, 0.07); } @@ -1212,7 +1318,7 @@ .observer-row.is-excluded { opacity: 0.65; - background: rgba(255, 255, 255, 0.02); + background: var(--surface-hover); } .observer-row input[type="checkbox"] { @@ -1272,7 +1378,7 @@ } .observer-support { margin-top: 6px; - border-top: 1px solid rgba(255, 255, 255, 0.08); + border-top: 1px solid var(--border); padding-top: 4px; } .observer-support > summary { @@ -1293,8 +1399,8 @@ .step-panel .observer-weight { width: 100%; border-radius: var(--radius); - border: 1px solid rgba(255, 255, 255, 0.12); - background: rgba(5, 15, 22, 0.9); + border: 1px solid var(--border); + background: var(--field-bg); color: var(--text); padding: 5px 6px; font: inherit; @@ -1302,8 +1408,8 @@ } .node-label { - background: rgba(7, 25, 35, 0.92); - border: 1px solid rgba(143, 187, 201, 0.26); + background: var(--menu-bg); + border: 1px solid var(--border-strong); color: var(--text); padding: 2px 6px; border-radius: 999px; @@ -1346,7 +1452,7 @@ specificity is what makes these survive the load order. Same trap as the candidate cards in #73, from the other direction. */ .maplibregl-popup .maplibregl-popup-content { - background: rgba(7, 25, 35, 0.96); + background: var(--menu-bg); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); @@ -1360,10 +1466,10 @@ used depends on the popup's anchor. Setting all four means it matches whichever way MapLibre decides to point it. */ .maplibregl-popup .maplibregl-popup-tip { - border-top-color: rgba(7, 25, 35, 0.96); - border-bottom-color: rgba(7, 25, 35, 0.96); - border-left-color: rgba(7, 25, 35, 0.96); - border-right-color: rgba(7, 25, 35, 0.96); + border-top-color: var(--menu-bg); + border-bottom-color: var(--menu-bg); + border-left-color: var(--menu-bg); + border-right-color: var(--menu-bg); } .maplibregl-popup .maplibregl-popup-close-button { @@ -1419,7 +1525,7 @@ cursor: pointer; } .link-remove-btn:hover { - background: rgba(225, 29, 72, 0.28); + background: color-mix(in srgb, var(--danger) 28%, transparent); } /* Deep-link auto-discovery splash (#26): a visitor arriving via a @@ -1452,7 +1558,7 @@ position: fixed; inset: 0; z-index: 5100; /* above #loading-overlay (5000) */ - background: rgba(7, 17, 24, 0.62); + background: var(--scrim); backdrop-filter: blur(3px); padding: 16px; } @@ -1467,7 +1573,7 @@ width: min(440px, 92vw); max-height: 85vh; border-radius: 20px; - background: rgba(7, 25, 35, 0.97); + background: var(--menu-bg); border: 1px solid var(--border); box-shadow: var(--surface-shadow); } @@ -1509,7 +1615,7 @@ width: 20px; height: 20px; border-radius: 50%; - background: rgba(0, 184, 148, 0.16); + background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); font-size: 0.7rem; font-weight: 600; @@ -1532,7 +1638,7 @@ .intro-sub { margin: 0 0 6px 29px; padding-left: 9px; - border-left: 2px solid rgba(0, 184, 148, 0.3); + border-left: 2px solid color-mix(in srgb, var(--accent) 30%, transparent); } .intro-sub p { margin: 0; @@ -1593,8 +1699,8 @@ width: min(260px, 80%); padding: 20px; border-radius: 20px; - background: rgba(7, 25, 35, 0.96); - border: 1px solid rgba(143, 187, 201, 0.18); + background: var(--menu-bg); + border: 1px solid var(--border); box-shadow: var(--surface-shadow); text-align: center; } @@ -1603,7 +1709,7 @@ height: 28px; margin: 0 auto 12px; border-radius: 50%; - border: 3px solid rgba(0, 184, 148, 0.2); + border: 3px solid color-mix(in srgb, var(--accent) 20%, transparent); border-top-color: var(--accent); animation: deep-link-spin 0.8s linear infinite; } @@ -1815,6 +1921,14 @@ MC-Radar ↗
+
+ 🌙 + +