mirror of
https://github.com/aljazceru/satshkd-vercel.git
synced 2025-12-17 05:04:24 +01:00
Merge branch 'main' of github.com:aljazceru/satshkd-vercel
This commit is contained in:
@@ -1 +1 @@
|
||||
Fri Nov 21 04:11:16 UTC 2025
|
||||
Sat Nov 22 04:10:37 UTC 2025
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"homepage": "https://github.com/bitkarrot/satshkd-vercel#readme",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"axios": "^1.13.2",
|
||||
"axios": "^0.26.1",
|
||||
"csv-parser": "^3.0.0",
|
||||
"express": "^4.17.1",
|
||||
"express-handlebars": "^5.3.4",
|
||||
|
||||
8953
public/historical
8953
public/historical
File diff suppressed because one or more lines are too long
@@ -162,7 +162,7 @@ table.minimalistBlack td, table.minimalistBlack th {
|
||||
padding: 8px 9px;
|
||||
}
|
||||
table.minimalistBlack tbody td {
|
||||
font-size: 13px;
|
||||
font-size: 16px;
|
||||
}
|
||||
table.minimalistBlack thead {
|
||||
background: #CFCFCF;
|
||||
@@ -172,20 +172,20 @@ table.minimalistBlack thead {
|
||||
border-bottom: 2px solid #000000;
|
||||
}
|
||||
table.minimalistBlack thead th {
|
||||
font-size: 15px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: left;
|
||||
}
|
||||
table.minimalistBlack tfoot td {
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.total{
|
||||
font-weight:bold;
|
||||
text-align:right!important;
|
||||
}
|
||||
td.total{
|
||||
font-size:15px;
|
||||
font-size:17px;
|
||||
}
|
||||
.symbol{
|
||||
font-weight:bold;
|
||||
@@ -194,14 +194,14 @@ td.total{
|
||||
content: "$";
|
||||
}
|
||||
table.minimalistBlack tfoot {
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
background: #EBEBEB;
|
||||
color: #000000;
|
||||
border-top: 3px solid #000000;
|
||||
}
|
||||
table.minimalistBlack tfoot td {
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.small-print{
|
||||
|
||||
193
public/static/mobile.css
Normal file
193
public/static/mobile.css
Normal file
@@ -0,0 +1,193 @@
|
||||
/* Mobile-Responsive Styles for SatsEUR */
|
||||
|
||||
/* Base responsive improvements */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* Container adjustments for mobile */
|
||||
.container {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Responsive typography */
|
||||
h3 {
|
||||
font-size: clamp(1.2rem, 5vw, 2rem);
|
||||
line-height: 1.3;
|
||||
word-wrap: break-word;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
#current {
|
||||
display: inline-block;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* Table responsive design */
|
||||
table.u-full-width {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
table.u-full-width thead th {
|
||||
font-size: 1.2rem;
|
||||
padding: 10px 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table.u-full-width tbody td {
|
||||
padding: 12px 5px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* Mobile-specific styles */
|
||||
@media screen and (max-width: 768px) {
|
||||
body {
|
||||
margin-top: 40px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-top: 10px !important;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* Responsive heading */
|
||||
h3 {
|
||||
font-size: clamp(1rem, 4.5vw, 1.5rem);
|
||||
margin-bottom: 15px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
/* Table optimization for mobile */
|
||||
table.u-full-width {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
table.u-full-width thead th {
|
||||
font-size: 1rem;
|
||||
padding: 8px 3px;
|
||||
}
|
||||
|
||||
table.u-full-width tbody td {
|
||||
padding: 10px 3px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Chart container */
|
||||
#historical {
|
||||
margin: 15px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Dark mode toggle - better positioning for mobile */
|
||||
.floating-button {
|
||||
bottom: 15px;
|
||||
left: 15px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.dark-toggle-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small mobile devices */
|
||||
@media screen and (max-width: 480px) {
|
||||
body {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-top: 5px !important;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(0.9rem, 4vw, 1.3rem);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Make table more compact on very small screens */
|
||||
table.u-full-width {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
table.u-full-width thead th {
|
||||
font-size: 0.95rem;
|
||||
padding: 6px 2px;
|
||||
}
|
||||
|
||||
table.u-full-width tbody td {
|
||||
padding: 8px 2px;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* Smaller dark toggle for small screens */
|
||||
.floating-button {
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.dark-toggle-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Landscape orientation on mobile */
|
||||
@media screen and (max-width: 896px) and (orientation: landscape) {
|
||||
body {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-top: 5px !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#historical {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure chart is responsive */
|
||||
#historical canvas {
|
||||
max-width: 100%;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* Fix text alignment for better cross-browser support */
|
||||
th[style*="-webkit-left"],
|
||||
td[style*="-webkit-left"] {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
th[style*="text-align:end"],
|
||||
td[style*="text-align:end"] {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
/* Improve touch targets for mobile */
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
a, button, .floating-button {
|
||||
min-height: 44px;
|
||||
min-width: 44px;
|
||||
}
|
||||
}
|
||||
1
public/static/skeleton.css
vendored
1
public/static/skeleton.css
vendored
@@ -423,6 +423,7 @@ there.
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url(mem8YaGs126MiZpBA-UFVZ0e.ttf) format('truetype');
|
||||
}
|
||||
~
|
||||
|
||||
126
views/sats.hbs
126
views/sats.hbs
@@ -2,16 +2,23 @@
|
||||
<title>EURSAT</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!-- Preconnect to external resources for faster loading -->
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="preconnect" href="https://api-pub.bitfinex.com">
|
||||
<link rel="preconnect" href="https://analytics.cypherpunk.cloud">
|
||||
<!-- CSS only -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/static/skeleton.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/mobile.css">
|
||||
<link rel="shortcut icon" type="image/png" href="/static/favicon.png" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Raleway&display=swap" rel="stylesheet">
|
||||
<script src="/static/chart.min.js"></script>
|
||||
<script src="/static/chartjs-adapter-date-fns.min.js"></script>
|
||||
<script src="/static/chartjs-plugin-annotation.min.js"></script>
|
||||
<script defer src="/static/chart.min.js"></script>
|
||||
<script defer src="/static/chartjs-adapter-date-fns.min.js"></script>
|
||||
<script defer src="/static/chartjs-plugin-annotation.min.js"></script>
|
||||
<script>
|
||||
// Auto-detect domain for Plausible Analytics
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@@ -25,7 +32,7 @@
|
||||
});
|
||||
</script>
|
||||
<!-- JavaScript Bundle with Popper -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script>
|
||||
<style>
|
||||
#historical {
|
||||
position: relative;
|
||||
@@ -108,22 +115,86 @@
|
||||
<table class="u-full-width">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:-webkit-left;font-size:2rem;">{{ date }} </th>
|
||||
<th style="text-align:end;font-size:2rem;">{{ price }} </th>
|
||||
<th style="text-align:end;font-size:2rem;white-space: pre;"> {{ percentchange }} </th>
|
||||
<th style="text-align:left;">{{ date }} </th>
|
||||
<th style="text-align:right;">{{ price }} </th>
|
||||
<th style="text-align:right;white-space: pre;"> {{ percentchange }} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each yeardata}}
|
||||
<tr>
|
||||
<td style="text-align:-webkit-left">{{ this.year }}</td>
|
||||
<td style="text-align:end">{{ this.sats }} sats </td>
|
||||
<td style="text-align:end">{{ this.percent }} % </td>
|
||||
<td style="text-align:left">{{ this.year }}</td>
|
||||
<td style="text-align:right">{{ this.sats }} sats </td>
|
||||
<td style="text-align:right">{{ this.percent }} % </td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-5">
|
||||
<h4 class="mb-4">The Most Spectacularly Wrong Bitcoin Predictions by ECB Officials</h4>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>November 15, 2018</strong> - Benoît Cœuré, ECB Executive Board Member</h6>
|
||||
<p><em>"In more ways than one, Bitcoin is the evil spawn of the financial crisis. Lightning may strike me for saying this in the Tower of Basel – but Bitcoin was an extremely clever idea. Sadly, not every clever idea is a good idea. I believe that Agustín Carstens summed its manifold problems up well when he said that Bitcoin is 'a combination of a bubble, a Ponzi scheme and an environmental disaster.'"</em></p>
|
||||
<p><small>Sources: <a href="https://www.ccn.com/bitcoin-is-the-evil-spawn-of-the-financial-crisis-european-central-bank-board-member/" target="_blank">CCN</a>, <a href="https://bitcoinist.com/the-ecb-is-right-bitcoin-was-spawned-by-the-financial-crisis-created-by-the-ecb/" target="_blank">Bitcoinist</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>May 9, 2019</strong> - Mario Draghi, ECB President</h6>
|
||||
<p><em>"Cryptocurrencies or bitcoins, or anything like that, are not really currencies — they are assets. A euro is a euro — today, tomorrow, in a month — it's always a euro. And the ECB is behind the euro. Who is behind the cryptocurrencies? So they are very, very risky assets."</em></p>
|
||||
<p><small>Sources: <a href="https://cointelegraph.com/news/ecb-president-mario-draghi-cryptos-are-not-currencies-they-are-very-risky-assets" target="_blank">Cointelegraph</a>, <a href="https://finance.yahoo.com/news/draghi-comments-ecb-press-conference-133645028.html" target="_blank">Yahoo Finance</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>May 29, 2019</strong> - Yves Mersch, ECB Executive Board Member</h6>
|
||||
<p><em>"Bitcoin and other crypto-assets claim to need neither trust nor the backing of a sovereign. These self-proclaimed currencies, more accurately described as crypto-assets, have proved to be unfit for purpose, demonstrating that well-executed central bank policies are still the only sound basis for stability."</em></p>
|
||||
<p><small>Source: <a href="https://www.bis.org/review/r190529a.htm" target="_blank">BIS</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>January 13, 2021</strong> - Christine Lagarde, ECB President</h6>
|
||||
<p><em>"For those who had assumed that it might turn into a currency -- terribly sorry, but this is an asset and it's a highly speculative asset which has conducted some funny business and some interesting and totally reprehensible money-laundering activity."</em></p>
|
||||
<p><small>Sources: <a href="https://www.bloomberg.com/news/articles/2021-01-13/lagarde-blasts-bitcoin-s-role-in-facilitating-money-laundering" target="_blank">Bloomberg</a>, <a href="https://www.theglobeandmail.com/business/international-business/european-business/article-ecbs-lagarde-calls-for-global-regulation-of-bitcoin-to-prevent-use-in/" target="_blank">The Globe and Mail</a>, <a href="https://www.coindesk.com/policy/2021/01/13/ecbs-christine-lagarde-says-speculative-bitcoin-needs-global-regulation" target="_blank">CoinDesk</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>April 9, 2021</strong> - Isabel Schnabel, ECB Executive Board Member</h6>
|
||||
<p><em>"In our view it is wrong to describe bitcoin as a currency, because it does not fulfil the basic properties of money. It is a speculative asset without any recognisable fundamental value and is subject to massive price swings."</em></p>
|
||||
<p><small>Source: <a href="https://www.ecb.europa.eu/press/inter/date/2021/html/ecb.in210409~c8c348a12c.en.html" target="_blank">ECB</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>May 19, 2021</strong> - Luis de Guindos, ECB Vice President</h6>
|
||||
<p><em>"When you have difficulties to find out what are the real fundamentals of an investment, then what you're doing is not a real investment. This is an asset with very weak fundamentals, and that is going to be subject to a lot of volatility."</em></p>
|
||||
<p><small>Sources: <a href="https://www.coindesk.com/markets/2021/05/19/crypto-assets-arent-a-real-investment-ecb-vice-president-says/" target="_blank">CoinDesk</a>, <a href="https://cointelegraph.com/news/ecb-veep-says-crypto-has-weak-fundamentals-is-not-a-real-asset-amid-30-dip" target="_blank">Cointelegraph</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>April 25, 2022</strong> - Fabio Panetta, ECB Executive Board Member</h6>
|
||||
<p><em>"Crypto-assets are speculative assets that can cause major damage to society. They derive their value mainly from greed, they rely on the greed of others and the hope that the scheme continues unhindered. In fact, they are a gamble disguised as an investment asset."</em></p>
|
||||
<p><small>Sources: <a href="https://www.bis.org/review/r220425j.htm" target="_blank">BIS</a>, <a href="https://www.paymentscardsandmobile.com/fabio-panetta-why-we-must-reign-in-the-wild-west-of-crypto/" target="_blank">Payments Cards & Mobile</a>, <a href="https://www.ledgerinsights.com/european-central-bank-ecb-panetta-likens-crypto-to-wild-west-ponzi-scheme/" target="_blank">Ledger Insights</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>May 22, 2022</strong> - Christine Lagarde, ECB President</h6>
|
||||
<p><em>"My very humble assessment is that it is worth nothing. It is based on nothing, there is no underlying assets to act as an anchor of safety."</em></p>
|
||||
<p><small>Sources: <a href="https://www.cnbc.com/amp/2022/05/23/ecb-chief-christine-lagarde-crypto-is-worth-nothing.html" target="_blank">CNBC</a>, <a href="https://forkast.news/cryptocurrency-ecb-christine-lagarde/" target="_blank">Forkast</a>, <a href="https://www.techspot.com/news/94679-european-central-bank-president-calls-crypto-worthless-based.html" target="_blank">TechSpot</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>December 7, 2022</strong> - Fabio Panetta, ECB Executive Board Member</h6>
|
||||
<p><em>"Crypto assets should be banned if they are too energy intensive. Investors have been caught in the textbook definition of a bubble, lured by the promise of ever-rising prices. Many cryptocurrencies are just a new way of gambling."</em></p>
|
||||
<p><small>Sources: <a href="https://www.coindesk.com/policy/2022/12/07/ban-energy-intensive-crypto-says-ecb-official" target="_blank">CoinDesk</a>, <a href="https://uk.finance.yahoo.com/news/ecb-ban-crypto-bitcoin-ethereum-123751593.html" target="_blank">Yahoo Finance UK</a></small></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h6><strong>January 30, 2025</strong> - Christine Lagarde, ECB President</h6>
|
||||
<p><em>"I am confident that bitcoin will not enter the reserves of any of the central banks of the General Council... reserves have to be liquid, that reserves have to be secure, that they have to be safe, that they should not be plagued by the suspicion of money laundering."</em></p>
|
||||
<p><small>Sources: <a href="https://www.bloomberg.com/news/articles/2025-01-30/lagarde-is-confident-eu-central-banks-will-shun-bitcoin-reserves" target="_blank">Bloomberg</a>, <a href="https://cointelegraph.com/news/ecb-president-christine-lagarde-bitcoin-central-bank-reserves" target="_blank">Cointelegraph</a></small></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
@@ -199,7 +270,24 @@
|
||||
patternImage.src = '/static/assets/100eur.jpg';
|
||||
|
||||
patternImage.onload = function() {
|
||||
const pattern = ctx.createPattern(patternImage, 'repeat');
|
||||
// Scale the pattern image based on viewport size for better mobile display
|
||||
const scaleFactor = window.innerWidth < 768
|
||||
? Math.max(0.3, window.innerWidth / 1500) // Mobile: scale down proportionally
|
||||
: window.innerWidth < 1200
|
||||
? 0.7 // Tablet: moderate scaling
|
||||
: 1.0; // Desktop: full size
|
||||
|
||||
// Create a temporary canvas to scale the image
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
const tempCtx = tempCanvas.getContext('2d');
|
||||
tempCanvas.width = patternImage.width * scaleFactor;
|
||||
tempCanvas.height = patternImage.height * scaleFactor;
|
||||
|
||||
// Draw scaled image to temporary canvas
|
||||
tempCtx.drawImage(patternImage, 0, 0, tempCanvas.width, tempCanvas.height);
|
||||
|
||||
// Create pattern from scaled image
|
||||
const pattern = ctx.createPattern(tempCanvas, 'repeat');
|
||||
|
||||
// Initialize Chart.js
|
||||
const chart = new Chart(ctx, {
|
||||
@@ -226,7 +314,7 @@
|
||||
display: true,
|
||||
text: '{{ subtitle }}',
|
||||
font: {
|
||||
size: 16
|
||||
size: window.innerWidth < 768 ? 12 : 16
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
@@ -257,10 +345,10 @@
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.8)',
|
||||
color: 'white',
|
||||
font: {
|
||||
size: 10,
|
||||
size: window.innerWidth < 768 ? 8 : 10,
|
||||
weight: 'bold'
|
||||
},
|
||||
padding: 4
|
||||
padding: window.innerWidth < 768 ? 2 : 4
|
||||
},
|
||||
click: function() {
|
||||
marker.click();
|
||||
@@ -280,7 +368,10 @@
|
||||
}
|
||||
},
|
||||
ticks: {
|
||||
maxTicksLimit: 16
|
||||
maxTicksLimit: window.innerWidth < 768 ? 8 : 16,
|
||||
font: {
|
||||
size: window.innerWidth < 768 ? 10 : 12
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
display: true
|
||||
@@ -294,7 +385,10 @@
|
||||
callback: function(value) {
|
||||
return value.toLocaleString() + ' sats';
|
||||
},
|
||||
maxTicksLimit: 12
|
||||
maxTicksLimit: window.innerWidth < 768 ? 8 : 12,
|
||||
font: {
|
||||
size: window.innerWidth < 768 ? 10 : 12
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
display: true
|
||||
|
||||
Reference in New Issue
Block a user