Synced + few of my changes

Drop Less support: The style.less and themes/libreqr/theme.php files are converted to plain CSS.

The main Less features used in LibreQR were variables and selector nesting, but since CSS custom properties and nesting are now widely supported across browsers, the less.php dependency can be ditched.

To read the background color for contrast improvement, a regex is used on the theme CSS file.

(5468a43a2f)

Format locales according to Weblate

(f3e2249a84)

Estonian Translation (eb0ea03857)

doc: Add link to Weblate + enhance markup

(49394ebd9b)
This commit is contained in:
FbIN Support 2025-11-29 21:56:41 +05:30
commit 77f048085b
18 changed files with 834 additions and 940 deletions

View file

@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
To ease with webserver configuration, `index.php` is now able to serve any HTTP ressource that is used in the LibreQR interface. This means that every request can be forwarded to `index.php`. To ease with webserver configuration, `index.php` is now able to serve any HTTP ressource that is used in the LibreQR interface. This means that every request can be forwarded to `index.php`.
* German localization (PR [#25](https://code.antopie.org/miraty/libreqr/pulls/25)) * German localization (PR [#25](https://code.antopie.org/miraty/libreqr/pulls/25))
### Removed
* *Less* support, and related `less.php` dependency
## 2.0.1 - 2023-07-08 ## 2.0.1 - 2023-07-08
### Added ### Added

View file

@ -28,7 +28,7 @@ LibreQR can be chrooted using PHP-FPM.
### YunoHost ### YunoHost
There is [a package](https://code.antopie.org/miraty/qr_ynh/) for [YunoHost](https://yunohost.org/). There is [a package for YunoHost](https://apps.yunohost.org/app/qr).
For historical reasons, LibreQR is technically named `qr` in YunoHost. For historical reasons, LibreQR is technically named `qr` in YunoHost.
@ -45,23 +45,18 @@ You can customize your LibreQR instance look by changing the colors in `theme.ph
## Contribute ## Contribute
The public forge is <https://code.antopie.org/miraty/libreqr>. You can open issues and pull requests there. You can open issues and pull requests on [the public forge](https://code.antopie.org/miraty/libreqr).
### Translations ### Translations
You can add your translations in `locales/<language-code>.php`. [Contribute on Codeberg's Weblate](https://translate.codeberg.org/engage/libreqr2/)
You can also manually edit translations in `locales/<language-code>.php`.
## Contact ## Contact
You can get my contact details on <https://miraty.antopie.org/>, feel free to use them if you want more informations about using or contributing to LibreQR. You can get [contact details for the maintainer](https://miraty.niv.re/contact), feel free to use them if you want more information about using or contributing to LibreQR.
## License ## License
LibreQR is published under [AGPLv3+](https://code.antopie.org/miraty/libreqr/src/branch/main/LICENSE). Librairies located in the `vendor` subdirectory use their own licenses. LibreQR is published under [AGPLv3+](LICENSE). Librairies located in the `vendor` subdirectory use their own compatible licenses.
LibreQR is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
LibreQR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

View file

@ -1,6 +1,5 @@
{ {
"require": { "require": {
"endroid/qr-code": "^4.4", "endroid/qr-code": "^4.4"
"wikimedia/less.php": "^3.1"
} }
} }

View file

View file

@ -10,7 +10,8 @@ use Endroid\QrCode\Color\Color;
require "config.inc.php"; require "config.inc.php";
require "vendor/autoload.php"; require "vendor/autoload.php";
define("LIBREQR_VERSION", "2.0.1"); const CONTRAST_THRESHOLD = 64;
const LIBREQR_VERSION = '2.0.1+dev';
// Defines the locale to be used // Defines the locale to be used
$locale = DEFAULT_LOCALE; $locale = DEFAULT_LOCALE;
@ -61,15 +62,6 @@ function getIntlString(
return "<span lang=\"en\">" . $template_loc[$string_label] . "</span>"; return "<span lang=\"en\">" . $template_loc[$string_label] . "</span>";
} }
require "themes/" . THEME . "/theme.php";
$colorScheme['theme'] = THEME;
$css_filename = Less_Cache::Get(
less_files: ['style.less' => ''],
parser_options: ['cache_dir' => 'css/', 'compress' => true],
modify_vars: $colorScheme,
);
preg_match('#.*/(?<page>.*)$#', $_SERVER['REQUEST_URI'], $matches); preg_match('#.*/(?<page>.*)$#', $_SERVER['REQUEST_URI'], $matches);
define('PAGE', match ($matches['page']) { define('PAGE', match ($matches['page']) {
'wifi' => 'wifi', 'wifi' => 'wifi',
@ -77,10 +69,15 @@ define('PAGE', match ($matches['page']) {
default => 'unknown', default => 'unknown',
}); });
define('ICONS_DIR', 'themes/' . THEME . '/icons');
$icon_files = array_diff(scandir(ICONS_DIR), ['.', '..']);
if (PAGE === 'unknown') { if (PAGE === 'unknown') {
$allowed_filenames['css/' . $css_filename] = 'text/css'; $allowed_filenames['style.css'] = 'text/css';
foreach ($themeDimensionsIcons as $icon_dimension) $allowed_filenames['themes/' . THEME . '/theme.css'] = 'text/css';
$allowed_filenames['themes/' . THEME . '/icons/' . $icon_dimension . '.png'] = 'image/png'; $allowed_filenames['themes/' . THEME . '/logo-dark.png'] = 'image/png';
$allowed_filenames['themes/' . THEME . '/logo-light.png'] = 'image/png';
foreach ($icon_files as $icon_file)
$allowed_filenames[ICONS_DIR . '/' . $icon_file] = 'image/png';
foreach ($allowed_filenames as $filename => $type) { foreach ($allowed_filenames as $filename => $type) {
if (str_ends_with($_SERVER['REQUEST_URI'], $filename)) { if (str_ends_with($_SERVER['REQUEST_URI'], $filename)) {
header('Content-Type: ' . $type); header('Content-Type: ' . $type);
@ -195,7 +192,7 @@ if ($_POST['main']['txt'] !== "") {
} catch (Exception $ex) { } catch (Exception $ex) {
http_response_code(500); http_response_code(500);
$qrCodeAvailable = false; $qrCodeAvailable = false;
error_log("LibreQR encountered an error while generating a QR code: " . $ex); error_log("FbIN QR encountered an error while generating a QR code: " . $ex);
} }
} }
@ -206,22 +203,30 @@ if ($_POST['main']['txt'] !== "") {
<meta charset="utf-8"> <meta charset="utf-8">
<title><?= <title><?=
match (PAGE) { match (PAGE) {
'home' => 'LibreQR · ' . getIntlString('subtitle'), 'home' => 'FbIN QR' . getIntlString('subtitle'),
'wifi' => 'LibreQR · ' .getIntlString('tab_wifi_title'), 'wifi' => 'FbIN QR' .getIntlString('tab_wifi_title'),
'unknown' => 'LibreQR · ' .getIntlString('error_404'), 'unknown' => 'FbIN QR' .getIntlString('error_404'),
} }
?></title> ?></title>
<meta name="description" content="<?= getIntlString('description', raw: true) ?>"> <meta name="description" content="<?= getIntlString('description', raw: true) ?>">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark light"> <meta name="color-scheme" content="dark light">
<meta name="application-name" content="LibreQR"> <meta name="application-name" content="FbIN QR">
<meta name="referrer" content="no-referrer"> <meta name="referrer" content="no-referrer">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' data:; style-src 'self'; form-action 'self';"> <meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' data:; style-src 'self'; form-action 'self';">
<link rel="stylesheet" media="screen" href="css/<?= $css_filename ?>"> <!-- Avoids leaking the "prefers-color-scheme" media query to the server -->
<link rel="preload" as="image" href="themes/<?= THEME ?>/logo-dark.png">
<link rel="preload" as="image" href="themes/<?= THEME ?>/logo-light.png">
<link rel="stylesheet" media="screen" href="style.css">
<link rel="stylesheet" media="screen" href="themes/<?= THEME ?>/theme.css">
<?php <?php
foreach($themeDimensionsIcons as $dimFav) // Set all icons dimensions natsort($icon_files);
echo ' <link rel="icon" type="image/png" href="themes/' . THEME . '/icons/' . $dimFav . '.png" sizes="' . $dimFav . 'x' . $dimFav . '">' . "\n"; foreach($icon_files as $icon_file) {
if (ctype_digit($icon_size = substr($icon_file, 0, -4)))
echo ' <link rel="icon" type="image/png" href="' . ICONS_DIR . '/' . $icon_size . '.png" sizes="' . $icon_size . 'x' . $icon_size . '">' . "\n";
}
?> ?>
</head> </head>
@ -230,7 +235,7 @@ foreach($themeDimensionsIcons as $dimFav) // Set all icons dimensions
<header> <header>
<a id="linkTitles" href="./"> <a id="linkTitles" href="./">
<hgroup id="titles"> <hgroup id="titles">
<h1>LibreQR</h1> <h1>FbIN QR</h1>
<p><?= getIntlString('subtitle') ?></p> <p><?= getIntlString('subtitle') ?></p>
</hgroup> </hgroup>
</a> </a>
@ -297,16 +302,27 @@ if ($qrCodeAvailable) {
<div class="centered" id="showOnlyQR"> <div class="centered" id="showOnlyQR">
<a title="<?= getIntlString('title_showOnlyQR', raw: true) ?>" href="<?= $dataUri ?>"><img width="<?= $qrSize ?>" height="<?= $qrSize ?>" alt='<?= getIntlString('alt_QR_before', raw: true) ?><?= htmlspecialchars($_POST['main']['txt']); ?><?= getIntlString('alt_QR_after', raw: true) ?>' id="qrCode"<?php <a title="<?= getIntlString('title_showOnlyQR', raw: true) ?>" href="<?= $dataUri ?>"><img width="<?= $qrSize ?>" height="<?= $qrSize ?>" alt='<?= getIntlString('alt_QR_before', raw: true) ?><?= htmlspecialchars($_POST['main']['txt']); ?><?= getIntlString('alt_QR_after', raw: true) ?>' id="qrCode"<?php
// Compute the difference between the QR code and theme background colors // Compute the difference between the QR code and theme background colors to determine whether a CSS corner is needed to let the user see the margin of the QR code
$diffLight = abs($rgbBgColor['r']-hexdec(substr($colorScheme['bg-light'],-6,2))) + abs($rgbBgColor['g']-hexdec(substr($colorScheme['bg-light'],-4,2))) + abs($rgbBgColor['b']-hexdec(substr($colorScheme['bg-light'],-2,2))); preg_match(
$diffDark = abs($rgbBgColor['r']-hexdec(substr($colorScheme['bg-dark'],-6,2))) + abs($rgbBgColor['g']-hexdec(substr($colorScheme['bg-dark'],-4,2))) + abs($rgbBgColor['b']-hexdec(substr($colorScheme['bg-dark'],-2,2))); '/prefers-color-scheme: light.+--bg: (?<bg_light>#[A-Fa-f0-9]{6});.+prefers-color-scheme: dark.+--bg: (?<bg_dark>#[A-Fa-f0-9]{6});.+/s',
file_get_contents('themes/' . THEME . '/theme.css'),
// Determine whether a CSS corner is needed to let the user see the margin of the QR code $css,
$contrastThreshold = 64; );
if ($diffLight < $contrastThreshold) if (
abs($rgbBgColor['r'] - hexdec(substr($css['bg_light'], -6, 2)))
+ abs($rgbBgColor['g'] - hexdec(substr($css['bg_light'], -4, 2)))
+ abs($rgbBgColor['b'] - hexdec(substr($css['bg_light'], -2, 2)))
< CONTRAST_THRESHOLD
)
echo " class='needLightContrast'"; echo " class='needLightContrast'";
if ($diffDark < $contrastThreshold) if (
abs($rgbBgColor['r'] - hexdec(substr($css['bg_dark'], -6, 2)))
+ abs($rgbBgColor['g'] - hexdec(substr($css['bg_dark'], -4, 2)))
+ abs($rgbBgColor['b'] - hexdec(substr($css['bg_dark'], -2, 2)))
< CONTRAST_THRESHOLD
)
echo " class='needDarkContrast'"; echo " class='needDarkContrast'";
?> src="<?= $dataUri ?>"></a> ?> src="<?= $dataUri ?>"></a>
</div> </div>
<?php if (PAGE === "wifi") { ?> <?php if (PAGE === "wifi") { ?>
@ -330,20 +346,12 @@ if ($qrCodeAvailable) {
<footer> <footer>
<section id="info" class="metaText">
<?= getIntlString('metaText_qr') ?>
</section>
<?php if (CUSTOM_TEXT_ENABLED) { ?> <?php if (CUSTOM_TEXT_ENABLED) { ?>
<section class="metaText"> <section class="metaText">
<?= CUSTOM_TEXT ?> <?= CUSTOM_TEXT ?>
</section> </section>
<?php } ?> <?php } ?>
<section class="metaText">
<small><?= getIntlString('metaText_legal') ?></small>
</section>
</footer> </footer>
</body> </body>

View file

@ -1,42 +1,41 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
'subtitle' => "QR-Code-Generator",
'description' => "Erstellen Sie QR-Codes kostenlos. Wählen Sie Inhalt, Größe, Farben…",
'label_content' => "Text zum Kodieren",
'label_redundancy' => "Redundanzgrad",
'label_margin' => "Randgröße",
'label_size' => "Bildgröße",
'label_bgColor' => "Hintergrundfarbe",
'label_fgColor' => "Vordergrundfarbe",
'placeholder' => "Geben Sie den Text ein, den Sie im QR-Code kodieren möchten",
$loc = [
'subtitle' => "QR Code Generator",
'description' => "Create QR codes for free. Choose content, size, colors…",
'label_content' => "Text to be coded",
'label_redundancy' => "Redundancy level",
'label_margin' => "margin size",
'label_size' => "Image size",
'label_bgColor' => "background color",
'label_fgColor' => "foreground color",
'placeholder' => "Enter the text you want to encode in the QR code",
'help_content' => " 'help_content' => "
<p>Sie können jeden Text kodieren, den Sie möchten.</p> <p>You can encode any text you want.</p>
<p>Software, die diese QR-Codes dekodiert, kann je nach <a href='https://de.wikipedia.org/wiki/Uniform_Resource_Identifier#Schema' hreflang='de' rel='help external noreferrer'>URI-Schema</a> vorschlagen, sie mit spezieller Software zu öffnen.</p> Software that decodes these QR codes may suggest opening them with special software, depending on the URI scheme.
<p>Beispielsweise, um eine Webseite zu öffnen: <code>https://www.example/</code></p> <p>For example, to open a website: <code>https://www.example/</code></p>
<p>Um eine E-Mail zu senden: <code>mailto:contact@email.example</code></p> <p>To send an email: <code>mailto:contact@email.example</code></p>
<p>Um geografische Koordinaten zu teilen: <code>geo:48.867564,2.364057</code></p> <p>To share geographic coordinates: <code>geo:48.867564,2.364057</code></p>
", ",
'help_redundancy' => "Redundanz ist die Duplizierung von Informationen im QR-Code, um Fehler während der Dekodierung zu korrigieren. Ein höherer Grad produziert einen größeren QR-Code, aber hat eine bessere Chance, korrekt dekodiert zu werden.", 'help_redundancy' => "Redundancy is the duplication of information in the QR code to correct errors during decoding. A higher degree produces a larger QR code, but has a better chance of being decoded correctly."
'help_margin' => "Breite des Randes um den QR-Code in Pixel.", 'help_margin' => "Width of the border around the QR code in pixels."
'help_size' => "Bildbreite und -höhe in Pixel, ohne den Rand.", 'help_size' => "Image width and height in pixels, excluding the border."
'button_create' => "Create",
'button_create' => "Erstellen", 'button_download' => "Save this QR code",
'button_download' => "Diesen QR-Code speichern", 'title_showOnlyQR' => "Show only this QR code",
'alt_QR_before' => 'QR code with the meaning "',
'title_showOnlyQR' => "Nur diesen QR-Code anzeigen",
'alt_QR_before' => 'QR-Code mit der Bedeutung "',
'alt_QR_after' => '"', 'alt_QR_after' => '"',
'error_generation' => "An error occurred while generating the QR code. Try different parameters."
'metaText_qr' => " 'label_wifi_password' => "",
<h3>Was ist ein QR-Code?</h3> 'button_edit' => "",
Ein QR-Code ist ein zweidimensionaler Barcode, in dem Text in Binärcode geschrieben ist. Er kann mit einem Gerät mit Fotosensor und geeigneter Software dekodiert werden. 'tab_wifi' => "",
<a href='https://de.wikipedia.org/wiki/QR-Code' hreflang='de' rel='help external noreferrer'>QR-Code auf Wikipedia</a>. 'tab_wifi_title' => "",
", 'placeholder_wifi_ssid' => "",
'metaText_legal' => "LibreQR " . LIBREQR_VERSION . " ist Freie Software, deren <a href='https://git.flossboxin.org.in/FbIN/libreqr/' rel='external noreferrer'>Quellcode</a> unter den Bedingungen der <abbr title='GNU Affero General Public License Version 3 oder einer späteren Version'><a href='LICENSE.html' hreflang='en' rel='license'>AGPLv3</a>+</abbr> verfügbar ist.", 'wifi_raw_content_after' => "",
'help_wifi_password' => "",
'error_generation' => "Ein Fehler ist aufgetreten, während der QR-Code generiert wurde. Versuchen Sie es mit anderen Parametern.", 'wifi_raw_content_before' => "",
); 'placeholder_wifi_password' => "",
'label_wifi_ssid' => "",
'error_404' => "",
'tab_text' => "",
];

View file

@ -1,12 +1,11 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
'subtitle' => "Text & WiFi QR codes generator", $loc = [
'subtitle' => "",
'description' => "Generate QR codes freely. Choose content, size, colors…", 'description' => "Generate QR codes freely. Choose content, size, colors…",
'tab_text' => "Text", 'tab_text' => "Text",
'tab_wifi' => "WiFi", 'tab_wifi' => "Wifi",
'tab_wifi_title' => "WiFi QR codes generator", 'tab_wifi_title' => "Wifi QR codes generation",
'label_wifi_ssid' => "Network name / SSID", 'label_wifi_ssid' => "Network name / SSID",
'label_wifi_password' => "Password", 'label_wifi_password' => "Password",
'label_content' => "Text to encode", 'label_content' => "Text to encode",
@ -15,11 +14,9 @@ $loc = array(
'label_size' => "Image size", 'label_size' => "Image size",
'label_bgColor' => "Background color", 'label_bgColor' => "Background color",
'label_fgColor' => "Foreground color", 'label_fgColor' => "Foreground color",
'placeholder' => "Enter the text to encode in the QR code", 'placeholder' => "Enter the text to encode in the QR code",
'placeholder_wifi_ssid' => "Box-A31B", 'placeholder_wifi_ssid' => "Box-A31B",
'placeholder_wifi_password' => "correct horse battery staple", 'placeholder_wifi_password' => "correct horse battery staple",
'help_wifi_password' => "The WPA, WPA2 or WPA3 key. Leave empty if it's an open network.", 'help_wifi_password' => "The WPA, WPA2 or WPA3 key. Leave empty if it's an open network.",
'help_content' => " 'help_content' => "
<p>You can encode whatever text you want.</p> <p>You can encode whatever text you want.</p>
@ -31,26 +28,14 @@ $loc = array(
'help_redundancy' => "Redundancy is the duplication of information in the QR code to correct errors during decoding. A higher rate will produce a bigger QR code, but will have a better chance of being decoded correctly.", 'help_redundancy' => "Redundancy is the duplication of information in the QR code to correct errors during decoding. A higher rate will produce a bigger QR code, but will have a better chance of being decoded correctly.",
'help_margin' => "Number of pixels in each white band around the QR code.", 'help_margin' => "Number of pixels in each white band around the QR code.",
'help_size' => "Image width and height in pixels, without the margin.", 'help_size' => "Image width and height in pixels, without the margin.",
'button_create' => "Generate", 'button_create' => "Generate",
'button_download' => "Save this QR code", 'button_download' => "Save this QR code",
'button_edit' => "Edit", 'button_edit' => "Edit",
'title_showOnlyQR' => "Show this QR code only", 'title_showOnlyQR' => "Show this QR code only",
'alt_QR_before' => 'QR code meaning "', 'alt_QR_before' => 'QR code meaning "',
'alt_QR_after' => '"', 'alt_QR_after' => '"',
'wifi_raw_content_before' => "This QR code contains: ", 'wifi_raw_content_before' => "This QR code contains: ",
'wifi_raw_content_after' => "", 'wifi_raw_content_after' => "",
'metaText_qr' => "
<h3>What's a QR code?</h3>
A QR code is a 2 dimensional barcode in which text is written in binary. It can be decoded with a device equipped with a photo sensor and adequate software.
<a href='https://en.wikipedia.org/wiki/QR_code' hreflang='en' rel='help external noreferrer'>QR code on Wikipedia</a>.
",
'metaText_legal' => "LibreQR " . LIBREQR_VERSION . " is free software whose <a href='https://git.flossboxin.org.in/FbIN/libreqr/' rel='external noreferrer'>source code</a> is available under the terms of the <abbr title='GNU Affero General Public License version 3 or any later version'><a href='LICENSE.html' hreflang='en' rel='license'>AGPLv3</a>+</abbr>.",
'error_generation' => "An error occurred while generating the QR code. Try with different parameters.", 'error_generation' => "An error occurred while generating the QR code. Try with different parameters.",
'error_404' => "This page doesn't exist.", 'error_404' => "This page doesn't exist.",
); ];

41
locales/et.php Normal file
View file

@ -0,0 +1,41 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = [
'subtitle' => "QR-koodide looja",
'description' => "Tee selliseid QR-koode, nagu vaja. Vali sisu, suurus või värvid…",
'tab_text' => "Tekst",
'tab_wifi' => "WiFi",
'tab_wifi_title' => "QR-koodid WiFi jaoks",
'label_wifi_ssid' => "Võrgunimi / SSID",
'label_wifi_password' => "Salasõna",
'label_content' => "Kodeeritav tekst",
'label_redundancy' => "Veakorrektsiooni tase",
'label_margin' => "Veeriste suurus",
'label_size' => "Pildi suurus",
'label_bgColor' => "Taustavärv",
'label_fgColor' => "Esiplaani värv",
'placeholder' => "Sisesta tekst, mida tahaksid QR-koodis näha",
'placeholder_wifi_ssid' => "Ruuter-A31B",
'placeholder_wifi_password' => "kena hobune valge traktor",
'help_wifi_password' => "WPA, WPA2 või WPA3 salasõna. Avatud võrgu puhul jäta tühjaks.",
'help_content' => "
<p>Sa võid kodeerida igasugust soovitud teksti.</p>
<p>Tarkvara, mis siis neid QR-koode dekodeerib peaks vastavalt sisu <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>URI skeemile</a> soovitama avamiseks sobivat rakendust.</p>
<p>Näiteks veebilehe vaatamiseks: <code>https://www.example/</code></p>
<p>E-kirja saatmiseks: <code>mailto:contact@email.example</code></p>
<p>Asukoha jagamiseks: <code>geo:48.867564,2.364057</code></p>
",
'help_redundancy' => "Veakorrektsioon tähendab antud juhul QR-koodis leiduvat topeltteavet, mis peaks välistama, et dekodeerimisvigadest hoolimata on kood loetav. Kui veakorrektsiooni tase on suurem, siis tulemuseks on suurem QR-kood, aga see peaks ka suurema tõenäosusega olema hiljem loetav.",
'help_margin' => "QR-koodi ümbristeva valge riba laius pikslites.",
'help_size' => "Pildi laius ja kõrgus ilma veeristeta.",
'button_create' => "Genereeri",
'button_download' => "Salvesta see QR-kood",
'button_edit' => "Muuda",
'title_showOnlyQR' => "Näita vaid seda QR-koodi",
'alt_QR_before' => 'QR-kood tähendusega „',
'alt_QR_after' => '“',
'wifi_raw_content_before' => "Selles QR-koodis sisaldub: ",
'wifi_raw_content_after' => "",
'error_generation' => "QR-koodi loomisel tekkis viga. Proovi muid parameetreid.",
'error_404' => "Seda lehte pole olemas.",
];

View file

@ -1,42 +1,41 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
$loc = [
'subtitle' => "QR kode sortzailea", 'subtitle' => "QR kode sortzailea",
'description' => "Sortu QR kodeak nahieran. Aukeratu edukia, neurria, kolorea…", 'description' => "Sortu QR kodeak nahieran. Aukeratu edukia, neurria, kolorea…",
'label_content' => "Kodetzeko testua", 'label_content' => "Kodetzeko testua",
'label_redundancy' => "Erredundantzia-tasa", 'label_redundancy' => "Erredundantzia-tasa",
'label_margin' => "Marjinaren tamaina", 'label_margin' => "Marjinaren tamaina",
'label_size' => "Irudiaren neurria", 'label_size' => "Irudiaren neurria",
'label_bgColor' => "Hondoaren kolorea", 'label_bgColor' => "Hondoaren kolorea",
'label_fgColor' => "Kolore nagusia", 'label_fgColor' => "Kolore nagusia",
'placeholder' => "Sartu QR kodean kodetzeko testua", 'placeholder' => "Sartu QR kodean kodetzeko testua",
'help_content' => " 'help_content' => "
<p>Nahi duzun testua kodetu dezakezu.</p> <p>Nahi duzun testua kodetu dezakezu.</p>
<p>QR kode horiek deskodetzen dituen softwareak software dedikatuarekin irekitzea iradoki lezake, <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>URI eskema</a>ren arabera.</p> <p>QR kode horiek deskodetzen dituen softwareak software dedikatuarekin irekitzea iradoki lezake, <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>URI eskema</a>ren arabera.</p>
<p>Adibidez, webgune bat irekitzeko: <code>https://www.adibidea.eus/</code></p> <p>Adibidez, webgune bat irekitzeko: <code>https://www.adibidea.eus/</code></p>
<p>ePosta bidaltzeko: <code>mailto:lur_axpe@adibidea.eus</code></p> <p>ePosta bidaltzeko: <code>mailto:lur_axpe@adibidea.eus</code></p>
<p>Koordenatu geografikoak partekatzeko: <code>geo:42.895367,-2.167805</code></p>", <p>Koordenatu geografikoak partekatzeko: <code>geo:42.895367,-2.167805</code></p>
'help_redundancy' => "Erredundantzia QR kodearen informazioa bikoiztean datza, deskodetzean akatsak zuzentzeko. Tasa altuagoak QR kode handiagoa sortuko du, baina behar bezala deskodetzeko aukera handiagoa izango du.
", ",
'help_redundancy' => "Erredundantzia QR kodearen informazioa bikoiztean datza, deskodetzean akatsak zuzentzeko. Tasa altuagoak QR kode handiagoa sortuko du, baina behar bezala deskodetzeko aukera handiagoa izango du.",
'help_margin' => "QR kodearen inguruko banda zuriaren pixel kopurua.", 'help_margin' => "QR kodearen inguruko banda zuriaren pixel kopurua.",
'help_size' => "Irudiaren zabalera eta altuera pixeletan, marjinarik gabe.", 'help_size' => "Irudiaren zabalera eta altuera pixeletan, marjinarik gabe.",
'button_create' => "Sortu", 'button_create' => "Sortu",
'button_download' => "Gorde QR kodea", 'button_download' => "Gorde QR kodea",
'title_showOnlyQR' => "Erakutsi QR kode hau bakarrik", 'title_showOnlyQR' => "Erakutsi QR kode hau bakarrik",
'alt_QR_before' => 'QR kodearen esanahia "', 'alt_QR_before' => 'QR kodearen esanahia "',
'alt_QR_after' => '"', 'alt_QR_after' => '"',
'metaText_qr' => "
<h3>Zer da QR kode bat?</h3>
QR kodea bi dimentsioko barra-kodea da, testua bitarrean idatzita duena. Argazki-sentsore bat eta software egokia dituen gailu batekin deskodetzen da.
<a href='https://eu.wikipedia.org/wiki/QR_kode' hreflang='eu' rel='help external noreferrer'>QR kodea Wikipedian</a>.
",
'metaText_legal' => "LibreQR " . LIBREQR_VERSION . " software librea da, eta <a href='https://git.flossboxin.org.in/FbIN/libreqr/' rel='external noreferrer'>iturburu-kodea</a> <abbr title='GNU Affero Lizentzia Publiko Orokorraren 3. bertsioaren edo ondorengo edozein bertsio'><a href='LICENSE.html' hreflang='en' rel='license'>AGPLv3</a>+</abbr>ren arabera dago eskuragarri.",
'error_generation' => "Errorea gertatu da QR kodea sortzerakoan. Saiatu berriro parametro desberdinak erabiliz.", 'error_generation' => "Errorea gertatu da QR kodea sortzerakoan. Saiatu berriro parametro desberdinak erabiliz.",
); 'label_wifi_password' => "",
'button_edit' => "",
'tab_wifi' => "",
'tab_wifi_title' => "",
'placeholder_wifi_ssid' => "",
'wifi_raw_content_after' => "",
'help_wifi_password' => "",
'wifi_raw_content_before' => "",
'placeholder_wifi_password' => "",
'label_wifi_ssid' => "",
'error_404' => "",
'tab_text' => "",
];

View file

@ -1,12 +1,11 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
$loc = [
'subtitle' => "Générer des codes QR", 'subtitle' => "Générer des codes QR",
'description' => "Générer des codes QR librement. Choix du contenu, de la taille, des couleurs…", 'description' => "Générer des codes QR librement. Choix du contenu, de la taille, des couleurs…",
'tab_text' => "Texte", 'tab_text' => "Texte",
'tab_wifi' => "Wifi", 'tab_wifi' => "Wifi",
'tab_wifi_title' => "Générer des codes QR Wifi", 'tab_wifi_title' => "Générer des codes QR Wifi",
'label_wifi_ssid' => "Nom du réseau / SSID", 'label_wifi_ssid' => "Nom du réseau / SSID",
'label_wifi_password' => "Mot de passe", 'label_wifi_password' => "Mot de passe",
'label_content' => "Texte à encoder", 'label_content' => "Texte à encoder",
@ -15,11 +14,9 @@ $loc = array(
'label_size' => "Taille de l'image", 'label_size' => "Taille de l'image",
'label_bgColor' => "Couleur de fond", 'label_bgColor' => "Couleur de fond",
'label_fgColor' => "Couleur de premier plan", 'label_fgColor' => "Couleur de premier plan",
'placeholder' => "Entrez le texte à encoder dans le code QR", 'placeholder' => "Entrez le texte à encoder dans le code QR",
'placeholder_wifi_ssid' => "Box-A31B", 'placeholder_wifi_ssid' => "Box-A31B",
'placeholder_wifi_password' => "correct cheval batterie agrafe", 'placeholder_wifi_password' => "correct cheval batterie agrafe",
'help_wifi_password' => "La clé WPA, WPA2 ou WPA3. Laisser vide si c'est un réseau ouvert.", 'help_wifi_password' => "La clé WPA, WPA2 ou WPA3. Laisser vide si c'est un réseau ouvert.",
'help_content' => " 'help_content' => "
<p>Vous pouvez encoder ce que vous voulez sous forme de texte.</p> <p>Vous pouvez encoder ce que vous voulez sous forme de texte.</p>
@ -31,26 +28,14 @@ $loc = array(
'help_redundancy' => "La redondance est la duplication des informations dans le code QR afin de corriger les erreurs lors du décodage. Un taux plus élevé produira un code QR plus grand, mais aura plus de chance d'être décodé correctement.", 'help_redundancy' => "La redondance est la duplication des informations dans le code QR afin de corriger les erreurs lors du décodage. Un taux plus élevé produira un code QR plus grand, mais aura plus de chance d'être décodé correctement.",
'help_margin' => "Nombre de pixels de chaque bande blanche autour du code QR.", 'help_margin' => "Nombre de pixels de chaque bande blanche autour du code QR.",
'help_size' => "Largeur et hauteur de l'image en pixels, sans la marge.", 'help_size' => "Largeur et hauteur de l'image en pixels, sans la marge.",
'button_create' => "Générer", 'button_create' => "Générer",
'button_download' => "Enregistrer ce code QR", 'button_download' => "Enregistrer ce code QR",
'button_edit' => "Modifier", 'button_edit' => "Modifier",
'title_showOnlyQR' => "Afficher uniquement ce code QR", 'title_showOnlyQR' => "Afficher uniquement ce code QR",
'alt_QR_before' => "Code QR signifiant « ", 'alt_QR_before' => "Code QR signifiant « ",
'alt_QR_after' => " »", 'alt_QR_after' => " »",
'wifi_raw_content_before' => "Ce code QR contient&nbsp;: ", 'wifi_raw_content_before' => "Ce code QR contient&nbsp;: ",
'wifi_raw_content_after' => "", 'wifi_raw_content_after' => "",
'metaText_qr' => "
<h3>Qu'est-ce qu'un code QR ?</h3>
Un code QR est un code-barres en 2 dimensions dans lequel du texte est inscrit en binaire. Il peut être décodé avec un appareil muni d'un capteur photo et d'un logiciel adéquat.
<a href='https://fr.wikipedia.org/wiki/Code_QR' hreflang='fr' rel='help external noreferrer'>Code QR sur Wikipédia</a>.
",
'metaText_legal' => "LibreQR " . LIBREQR_VERSION . " est un logiciel libre dont le <a href='https://git.flossboxin.org.in/FbIN/libreqr/' rel='external noreferrer'>code source</a> est disponible selon les termes de l'<abbr title='GNU Affero General Public License version 3 ou toute version ultérieure'><a href='LICENSE.html' hreflang='en' rel='license'>AGPLv3</a>+</abbr>.",
'error_generation' => "Une erreur a eu lieu lors de la génération du code QR. Essayez avec des paramètres différents.", 'error_generation' => "Une erreur a eu lieu lors de la génération du code QR. Essayez avec des paramètres différents.",
'error_404' => "Cette page n'existe pas.", 'error_404' => "Cette page n'existe pas.",
); ];

View file

@ -1,17 +1,15 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
'subtitle' => "Pembuat kode QR",
'description' => "Membuat kode QR dengan bebas. Pilih konten, ukuran warna, ...",
$loc = [
'subtitle' => "Pembuat kode QR",
'description' => "Membuat kode QR dengan bebas. Pilih konten, ukuran warna, …",
'label_content' => "Teks untuk dienkode", 'label_content' => "Teks untuk dienkode",
'label_redundancy' => "Tingkat redundansi", 'label_redundancy' => "Tingkat redundansi",
'label_margin' => "Ukuran tepi", 'label_margin' => "Ukuran tepi",
'label_size' => "Ukuran gambar", 'label_size' => "Ukuran gambar",
'label_bgColor' => "Warna latar belakang", 'label_bgColor' => "Warna latar belakang",
'label_fgColor' => "Warna latar depan", 'label_fgColor' => "Warna latar depan",
'placeholder' => "Masukkan teks untuk dienkode di kode QR", 'placeholder' => "Masukkan teks untuk dienkode di kode QR",
'help_content' => " 'help_content' => "
<p>Anda bisa mengenkode teks apa pun.</p> <p>Anda bisa mengenkode teks apa pun.</p>
<p>Perangkat lunak yang mendekodekan kode QR tersebut bisa memberikan pilihan untuk membuka dengan perangkat lunak tertentu, tergantung pada <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>Skema URI</a> mereka.</p> <p>Perangkat lunak yang mendekodekan kode QR tersebut bisa memberikan pilihan untuk membuka dengan perangkat lunak tertentu, tergantung pada <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>Skema URI</a> mereka.</p>
@ -22,21 +20,22 @@ $loc = array(
'help_redundancy' => "Redundansi adalah duplikasi informasi di kode QR untuk memperbaiki galat saat pendekodean. Tingkat lebih besar akan menghasilkan kode QR yang lebih besar, tetapi akan dapat hasil lebih baik untuk didekodekan dengan benar.", 'help_redundancy' => "Redundansi adalah duplikasi informasi di kode QR untuk memperbaiki galat saat pendekodean. Tingkat lebih besar akan menghasilkan kode QR yang lebih besar, tetapi akan dapat hasil lebih baik untuk didekodekan dengan benar.",
'help_margin' => "Jumlah piksel di tepi putih di sekitar kode QR.", 'help_margin' => "Jumlah piksel di tepi putih di sekitar kode QR.",
'help_size' => "Tinggi dan lebar gambar dalam piksel, tanpa tepian.", 'help_size' => "Tinggi dan lebar gambar dalam piksel, tanpa tepian.",
'button_create' => "Buat", 'button_create' => "Buat",
'button_download' => "Simpan kode QR ini", 'button_download' => "Simpan kode QR ini",
'title_showOnlyQR' => "Tampilkan kode QR ini saja", 'title_showOnlyQR' => "Tampilkan kode QR ini saja",
'alt_QR_before' => 'Arti kode QR "', 'alt_QR_before' => 'Arti kode QR "',
'alt_QR_after' => '"', 'alt_QR_after' => '"',
'metaText_qr' => "
<h3>Apa itu Kode QR?</h3>
Kode QR adalah kode batang 2 dimensi yang mana teks ditulis dalam biner. Bisa didekodekan dengan perangkat yang memiliki sensor foto dan perangkat lunak yang memadai.
<a href='https://id.wikipedia.org/wiki/Kode_QR' hreflang='id' rel='help external noreferrer'>Kode QR di Wikipedia</a>.
",
'metaText_legal' => "LibreQR " . LIBREQR_VERSION . " adalah perangkat lunak bebas yang <a href='https://code.antopie.org/miraty/libreqr/' rel='external noreferrer'>kode sumber</a> tersedia di bawah ketentuan <abbr title='GNU Affero General Public License versi 3 atau selanjutnya version'><a href='LICENSE.html' hreflang='en' rel='license'>AGPLv3</a>+</abbr>.",
'error_generation' => "Galat terjadi ketika membuat kode QR. Coba dengan parameter yang berbeda.", 'error_generation' => "Galat terjadi ketika membuat kode QR. Coba dengan parameter yang berbeda.",
); 'label_wifi_password' => "",
'button_edit' => "",
'tab_wifi' => "",
'tab_wifi_title' => "",
'placeholder_wifi_ssid' => "",
'wifi_raw_content_after' => "",
'help_wifi_password' => "",
'wifi_raw_content_before' => "",
'placeholder_wifi_password' => "",
'label_wifi_ssid' => "",
'error_404' => "",
'tab_text' => "",
];

View file

@ -1,42 +1,41 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
$loc = [
'subtitle' => "Generator de còdis QR", 'subtitle' => "Generator de còdis QR",
'description' => "Generatz de còdis QR liurament. Causissètz lo contengut, la talha, las colors…", 'description' => "Generatz de còdis QR liurament. Causissètz lo contengut, la talha, las colors…",
'label_content' => "Tèxt de codar", 'label_content' => "Tèxt de codar",
'label_redundancy' => "Taus de redondància", 'label_redundancy' => "Taus de redondància",
'label_margin' => "Talha del marge", 'label_margin' => "Talha del marge",
'label_size' => "Talha de limatge", 'label_size' => "Talha de limatge",
'label_bgColor' => "Color de fons", 'label_bgColor' => "Color de fons",
'label_fgColor' => "Color del primièr plan", 'label_fgColor' => "Color del primièr plan",
'placeholder' => "Dintratz lo tèxt de codar en còdi QR", 'placeholder' => "Dintratz lo tèxt de codar en còdi QR",
'help_content' => " 'help_content' => "
<p>Podètz pas que codar lo tèxt que volètz.</p> <p>Podètz pas que codar lo tèxt que volètz.</p>
<p>Los logicials que deschifran los còdis QR poirián suggerir de los dubrir dins de logicials especials, segon lor <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>esquèma URI</a>.</p> <p>Los logicials que deschifran los còdis QR poirián suggerir de los dubrir dins de logicials especials, segon lor <a href='https://en.wikipedia.org/wiki/List_of_URI_schemes' hreflang='en' rel='help external noreferrer'>esquèma URI</a>.</p>
<p>Per exemple, per dubrir la pagina web: https://www.example/</p> <p>Per exemple, per dubrir la pagina web: <code>https://www.example/</code></p>
<p>Per enviar un corrièl: mailto:contact@email.example</p> <p>Per enviar un corrièl: <code>mailto:contact@email.example</code></p>
<p>Per partejar de coordonadas geograficas: geo:48.867564,2.364057</p> <p>Per partejar de coordonadas geograficas: <code>geo:48.867564,2.364057</code></p>
", ",
'help_redundancy' => "La redondància es la duplicacion de las informacions al còdi QR per dire de corregir las errors pendent lo deschiframent. Un taux mai naut produirà un còdi mai grand, mas serà de melhor deschifrar corrèctament.", 'help_redundancy' => "La redondància es la duplicacion de las informacions al còdi QR per dire de corregir las errors pendent lo deschiframent. Un taux mai naut produirà un còdi mai grand, mas serà de melhor deschifrar corrèctament.",
'help_margin' => "Nombre de pixèls de la banda blanca a lentorn del còdi QR.", 'help_margin' => "Nombre de pixèls de la banda blanca a lentorn del còdi QR.",
'help_size' => "Per quant deu la dimensions de limatge èsser multiplicada?", 'help_size' => "Per quant deu la dimensions de limatge èsser multiplicada?",
'button_create' => "Generar", 'button_create' => "Generar",
'button_download' => "Telecargar aqueste còdi QR", 'button_download' => "Telecargar aqueste còdi QR",
'title_showOnlyQR' => "Mostrar sonque aqueste còdi QR", 'title_showOnlyQR' => "Mostrar sonque aqueste còdi QR",
'alt_QR_before' => 'Significacion de còdi QR"', 'alt_QR_before' => 'Significacion de còdi QR"',
'alt_QR_after' => '"', 'alt_QR_after' => '"',
'error_generation' => "",
'metaText_qr' => " 'label_wifi_password' => "",
<h3>Ques aquò un còdi QR?</h3> 'button_edit' => "",
Un còdi QR es un còdi de barras en doas dimensions dins lo qual lo tèxt es escrich en binari. Un aparalh equipat dun capteur optic pòt lo deschifrar, amb laplicacion que cal. 'tab_wifi' => "",
<a lang='ca' href='https://ca.wikipedia.org/wiki/Codi_QR' hreflang='ca' rel='help external noreferrer'>Còdi QR a la Wikipèdia</a>. 'tab_wifi_title' => "",
", 'placeholder_wifi_ssid' => "",
'metaText_legal' => "LibreQR " . LIBREQR_VERSION . " es un logicial liure que son <a href='https://git.flossboxin.org.in/FbIN/libreqr/' rel='external noreferrer'>còdi font</a> es disponible jols tèrmes de la licéncia <abbr title='GNU Affero General Public License version 3 or any later version'><a href='LICENSE.html' hreflang='en' rel='license'>AGPLv3</a>+</abbr>.", 'wifi_raw_content_after' => "",
'help_wifi_password' => "",
'error_generation' => "An error occurred while generating the QR code. Try with different parameters.", 'wifi_raw_content_before' => "",
); 'placeholder_wifi_password' => "",
'label_wifi_ssid' => "",
'error_404' => "",
'tab_text' => "",
];

View file

@ -1,12 +1,11 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license <?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
$loc = array(
$loc = [
'subtitle' => "subtitle", 'subtitle' => "subtitle",
'description' => "description", 'description' => "description",
'tab_text' => "tab_text", 'tab_text' => "tab_text",
'tab_wifi' => "tab_wifi", 'tab_wifi' => "tab_wifi",
'tab_wifi_title' => "tab_wifi_title", 'tab_wifi_title' => "tab_wifi_title",
'label_wifi_ssid' => "label_wifi_ssid", 'label_wifi_ssid' => "label_wifi_ssid",
'label_wifi_password' => "label_wifi_password", 'label_wifi_password' => "label_wifi_password",
'label_content' => "label_content", 'label_content' => "label_content",
@ -15,32 +14,24 @@ $loc = array(
'label_size' => "label_size", 'label_size' => "label_size",
'label_bgColor' => "label_bgColor", 'label_bgColor' => "label_bgColor",
'label_fgColor' => "label_fgColor", 'label_fgColor' => "label_fgColor",
'placeholder' => "placeholder", 'placeholder' => "placeholder",
'placeholder_wifi_ssid' => "placeholder_wifi_ssid", 'placeholder_wifi_ssid' => "placeholder_wifi_ssid",
'placeholder_wifi_password' => "placeholder_wifi_password", 'placeholder_wifi_password' => "placeholder_wifi_password",
'help_wifi_password' => "help_wifi_password", 'help_wifi_password' => "help_wifi_password",
'help_content' => "help_content", 'help_content' => "help_content",
'help_redundancy' => "help_redundancy", 'help_redundancy' => "help_redundancy",
'help_margin' => "help_margin", 'help_margin' => "help_margin",
'help_size' => "help_size", 'help_size' => "help_size",
'button_create' => "button_create", 'button_create' => "button_create",
'button_download' => "button_download", 'button_download' => "button_download",
'button_edit' => "button_edit", 'button_edit' => "button_edit",
'title_showOnlyQR' => "title_showOnlyQR", 'title_showOnlyQR' => "title_showOnlyQR",
'alt_QR_before' => "alt_QR_before", 'alt_QR_before' => "alt_QR_before",
'alt_QR_after' => "alt_QR_after", 'alt_QR_after' => "alt_QR_after",
'wifi_raw_content_before' => "wifi_raw_content_before", 'wifi_raw_content_before' => "wifi_raw_content_before",
'wifi_raw_content_after' => "wifi_raw_content_after", 'wifi_raw_content_after' => "wifi_raw_content_after",
'metaText_qr' => "metaText_qr", 'metaText_qr' => "metaText_qr",
'metaText_legal' => "metaText_legal", 'metaText_legal' => "metaText_legal",
'error_generation' => "error_generation", 'error_generation' => "error_generation",
'error_404' => "error_404", 'error_404' => "error_404",
); ];

458
style.css Normal file
View file

@ -0,0 +1,458 @@
/* This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license */
:root {
@media (prefers-color-scheme: light) {
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
color-scheme: dark;
}
}
* {
font-family: system-ui, sans-serif;
scrollbar-width: auto;
scrollbar-color: var(--text) var(--bg);
}
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
max-width: 812px;
height: 100%;
margin: 0;
margin-left: auto;
margin-right: auto;
font-weight: normal;
font-size: 20px;
color: var(--text);
background-color: var(--bg);
}
a {
text-decoration: underline;
color: var(--text);
&:hover {
text-decoration: none;
}
}
nav {
margin-top: 10px;
margin-bottom: 10px;
display: flex;
justify-content: center;
& ul {
display: flex;
flex-direction: row;
list-style: none;
padding: 0;
margin: 0;
a {
text-decoration: none;
}
& li {
& div {
padding: 8px 25px;
}
&.tab-selected {
border: solid;
border-width: 2px 2px 0;
border-radius: 10px 10px 0 0;
background-color: var(--bg);
}
&:not(&.tab-selected) {
border-bottom: 2px solid;
border-top: 2px solid var(--bg);
&:first-child {
border-left: 2px solid var(--bg);
}
&:last-child {
border-right: 2px solid var(--bg);
}
}
border-color: var(--border);
}
}
}
label[for="ssid"] {
padding-left: 18px;
}
/* Hide content from screen but not from screen readers */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
code {
font-family: monospace;
user-select: all;
}
.helpText {
margin: 5px 0 0;
padding: 5px;
border-radius: 10px;
border-width: 2px;
border-style: dashed;
text-align: left;
background-color: var(--bg-help);
border-color: var(--border-help);
p {
margin-top: 0;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
#sideParams {
width: 100%;
text-align: center;
display: flex;
flex-flow: row wrap;
justify-content: center;
.param {
max-width: 270px;
box-sizing: border-box;
}
}
summary {
margin-left: 20px;
cursor: help;
}
#qrCode {
max-width: 94%;
width: auto;
height: auto;
--qr-border-width: 2px;
--qr-border-length: 16px;
padding: var(--qr-border-width);
&.needLightContrast {
@media (prefers-color-scheme: light) {
background:
linear-gradient(to right, var(--border-qr) var(--qr-border-width), transparent 0) 0 0,
linear-gradient(to right, var(--border-qr) var(--qr-border-width), transparent 0) 0 100%,
linear-gradient(to left, var(--border-qr) var(--qr-border-width), transparent 0) 100% 0,
linear-gradient(to left, var(--border-qr) var(--qr-border-width), transparent 0) 100% 100%,
linear-gradient(to bottom, var(--border-qr) var(--qr-border-width), transparent 0) 0 0,
linear-gradient(to bottom, var(--border-qr) var(--qr-border-width), transparent 0) 100% 0,
linear-gradient(to top, var(--border-qr) var(--qr-border-width), transparent 0) 0 100%,
linear-gradient(to top, var(--border-qr) var(--qr-border-width), transparent 0) 100% 100%;
background-repeat: no-repeat;
background-size: var(--qr-border-length) var(--qr-border-length);
}
}
&.needDarkContrast {
@media (prefers-color-scheme: dark) {
background:
linear-gradient(to right, var(--border-qr) var(--qr-border-width), transparent 0) 0 0,
linear-gradient(to right, var(--border-qr) var(--qr-border-width), transparent 0) 0 100%,
linear-gradient(to left, var(--border-qr) var(--qr-border-width), transparent 0) 100% 0,
linear-gradient(to left, var(--border-qr) var(--qr-border-width), transparent 0) 100% 100%,
linear-gradient(to bottom, var(--border-qr) var(--qr-border-width), transparent 0) 0 0,
linear-gradient(to bottom, var(--border-qr) var(--qr-border-width), transparent 0) 100% 0,
linear-gradient(to top, var(--border-qr) var(--qr-border-width), transparent 0) 0 100%,
linear-gradient(to top, var(--border-qr) var(--qr-border-width), transparent 0) 100% 100%;
background-repeat: no-repeat;
background-size: var(--qr-border-length) var(--qr-border-length);
}
}
}
#output form,
#output input[type="submit"],
#output p {
display: inline;
}
#output input[type="submit"] {
font-size: 20px;
padding: 5px 10px;
}
.centered {
text-align: center;
}
.button {
padding: 3px 10px;
text-decoration: none;
}
header {
text-align: center;
padding-top: 12px;
height: 64px;
}
#linkTitles::before {
width: 64px;
height: 64px;
content: "";
background-repeat: no-repeat;
background-image: var(--logo);
}
hgroup p {
margin: 0;
}
#titles {
margin-left: 2%;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
font-weight: normal;
}
h1 {
font-size: 29px;
}
h2 {
font-size: 22px;
}
#linkTitles {
text-align: left;
justify-content: center;
text-decoration: none;
display: flex;
flex-direction: row;
}
#downloadQR {
margin-top: 20px;
}
#showOnlyQR {
margin-top: 30px;
}
.param {
padding: 4px;
margin-left: 0;
margin-right: 0;
}
::selection {
color: var(--bg);
background-color: var(--text);
}
label[for="txt"] summary {
margin-left: 22px;
}
#colors {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
text-align: center;
.param {
text-align: center;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
}
.metaText {
padding: 6px;
color: var(--text);
a,
a:visited {
text-decoration: underline;
color: var(--text);
}
}
footer {
font-size: 16px;
margin-top: auto;
padding-top: 10px;
text-align: left;
}
small {
font-size: 14px;
}
#info {
font-size: 16px;
margin: 0;
h3 {
font-size: 20px;
font-weight: normal;
padding-bottom: 10px;
}
}
/* Inputs */
#redundancy,
#margin,
#ssid,
#password,
#txt,
#size,
input[type="color"],
input[type="submit"],
.button {
border-width: 2px;
border-style: solid;
border-radius: 10px;
font-size: 20px;
padding-left: 10px;
font-weight: normal;
transition: border-color 0.1s ease;
margin: 6px;
color: var(--text);
background-color: var(--bg-field);
border-color: var(--border);
&:hover {
border-width: 3px;
margin: 5px;
border-style: solid;
border-color: var(--border-hover);
}
&:focus {
border-width: 4px;
margin: 4px;
border-style: solid;
outline: none;
border-color: var(--border-focus);
}
}
#password,
#ssid {
height: 38px;
}
#redundancy {
width: 250px;
height: 44px;
&:hover {
width: 252px;
height: 46px;
}
&:focus {
width: 254px;
height: 48px;
}
}
input[type="color"] {
height: 60px;
width: 84px;
padding: 5px;
&:hover {
height: 62px;
width: 86px;
}
&:focus {
height: 64px;
width: 88px;
}
}
#size,
#margin {
width: 234px;
height: 38px;
}
#redundancy,
#size,
#margin {
background-color: var(--bg-field);
}
.textboxParam {
display: flex;
flex-direction: column;
}
#txt {
padding: 10px;
width: auto;
scrollbar-width: auto;
background-color: var(--bg-textarea);
color: var(--textarea-text);
scrollbar-color: var(--textarea-text) var(--bg-textarea);
}
input[type="submit"] {
cursor: pointer;
font-size: 28px;
padding: 10px;
padding-left: 14px;
padding-right: 14px;
}
#password::placeholder,
#ssid::placeholder,
#txt::placeholder {
opacity: 1;
font-family: system-ui, sans-serif;
font-weight: normal;
font-size: 1em;
color: var(--textarea-placeholder);
}
a[download]::before {
content: "💾 ";
filter:
drop-shadow(-1px 1px 1px white) drop-shadow(1px -1px 1px white);
}

View file

@ -1,560 +0,0 @@
// This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
@light: ~"(prefers-color-scheme: light)";
@dark: ~"(prefers-color-scheme: dark)";
@import "themes/@{theme}/logo.less";
:root {
@media @light {
color-scheme: light;
}
@media @dark {
color-scheme: dark;
}
}
* {
font-family: system-ui, sans-serif;
scrollbar-width: auto;
@media @light {
scrollbar-color: @text-light @bg-light;
}
@media @dark {
scrollbar-color: @text-dark @bg-dark;
}
}
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
max-width: 812px;
height: 100%;
margin: 0px;
margin-left: auto;
margin-right: auto;
font-weight: normal;
font-size: 20px;
@media @light {
color: @text-light;
background-color: @bg-light;
}
@media @dark {
color: @text-dark;
background-color: @bg-dark;
}
}
a {
text-decoration: underline;
@media @light {
color: @text-light;
}
@media @dark {
color: @text-dark;
}
&:hover {
text-decoration: none;
}
}
nav {
margin-top: 10px;
margin-bottom: 10px;
display: flex;
justify-content: center;
& ul {
display: flex;
flex-direction: row;
list-style: none;
padding: 0;
margin: 0;
a {
text-decoration: none;
}
& li {
& div {
padding: 8px 25px 8px 25px;
}
&.tab-selected {
border: solid;
border-width: 2px 2px 0px 2px;
border-radius: 10px 10px 0px 0px;
@media @light {
background-color: @bg-light;
}
@media @dark {
background-color: @bg-dark;
}
}
&:not(&.tab-selected) {
border-bottom: 2px solid;
@media @light {
border-top: 2px solid @bg-light;
}
@media @dark {
border-top: 2px solid @bg-dark;
}
&:first-child {
@media @light {
border-left: 2px solid @bg-light;
}
@media @dark {
border-left: 2px solid @bg-dark;
}
}
&:last-child {
@media @light {
border-right: 2px solid @bg-light;
}
@media @dark {
border-right: 2px solid @bg-dark;
}
}
}
@media @light {
border-color: @border-light;
}
@media @dark {
border-color: @border-dark;
}
}
}
}
label[for=ssid] {
padding-left: 18px;
}
.sr-only { /* Hide content from screen but not from screen readers */
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
code {
font-family: monospace;
user-select: all;
}
.helpText {
margin: 5px 0px 0px 0px;
padding: 5px;
border-radius: 10px;
border-width: 2px;
border-style: dashed;
text-align: left;
@media @light {
background-color: @bgHelp-light;
border-color: @borderHelp-light;
}
@media @dark {
background-color: @bgHelp-dark;
border-color: @borderHelp-dark;
}
& p {
margin-top: 0px;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0px;
}
}
}
#sideParams {
width: 100%;
text-align: center;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
& .param {
max-width: 270px;
box-sizing: border-box;
}
}
summary {
margin-left: 20px;
cursor: help;
}
#qrCode {
max-width: 94%;
width: auto;
height: auto;
@width: 2px;
@lenght: 16px;
padding: @width;
&.needLightContrast {
@media @light {
background:
linear-gradient(to right, @borderQr-light @width, transparent 0px) 0 0,
linear-gradient(to right, @borderQr-light @width, transparent 0px) 0 100%,
linear-gradient(to left, @borderQr-light @width, transparent 0px) 100% 0,
linear-gradient(to left, @borderQr-light @width, transparent 0px) 100% 100%,
linear-gradient(to bottom, @borderQr-light @width, transparent 0px) 0 0,
linear-gradient(to bottom, @borderQr-light @width, transparent 0px) 100% 0,
linear-gradient(to top, @borderQr-light @width, transparent 0px) 0 100%,
linear-gradient(to top, @borderQr-light @width, transparent 0px) 100% 100%;
background-repeat: no-repeat;
background-size: @lenght @lenght;
}
}
&.needDarkContrast {
@media @dark {
background:
linear-gradient(to right, @borderQr-dark @width, transparent 0px) 0 0,
linear-gradient(to right, @borderQr-dark @width, transparent 0px) 0 100%,
linear-gradient(to left, @borderQr-dark @width, transparent 0px) 100% 0,
linear-gradient(to left, @borderQr-dark @width, transparent 0px) 100% 100%,
linear-gradient(to bottom, @borderQr-dark @width, transparent 0px) 0 0,
linear-gradient(to bottom, @borderQr-dark @width, transparent 0px) 100% 0,
linear-gradient(to top, @borderQr-dark @width, transparent 0px) 0 100%,
linear-gradient(to top, @borderQr-dark @width, transparent 0px) 100% 100%;
background-repeat: no-repeat;
background-size: @lenght @lenght;
}
}
}
#output form, #output input[type=submit], #output p {
display: inline;
}
#output input[type=submit] {
font-size: 20px;
padding: 5px 10px;
}
.centered {
text-align: center;
}
.button {
padding: 3px 10px 3px 10px;
text-decoration: none;
}
header {
text-align: center;
padding-top: 12px;
height: 64px;
}
#linkTitles::before {
width: 64px;
height: 64px;
content: "";
background-repeat: no-repeat;
@media @light {
background-image: var(--logo-light);
}
@media @dark {
background-image: var(--logo-dark);
}
}
hgroup p {
margin: 0;
}
#titles {
margin-left: 2%;
}
h1, h2, h3, h4, h5, h6 {
margin: 0px;
font-weight: normal;
}
h1 {
font-size: 29px;
}
h2 {
font-size: 22px;
}
#linkTitles {
text-align: left;
justify-content: center;
text-decoration: none;
display: flex;
flex-direction: row;
}
#downloadQR {
margin-top: 20px;
}
#showOnlyQR {
margin-top: 30px;
}
.param {
padding: 4px;
margin-left: 0px;
margin-right: 0px;
}
::selection {
@media @light {
color: @bg-light;
background-color: @text-light;
}
@media @dark {
color: @bg-dark;
background-color: @text-dark;
}
}
label[for=txt] summary {
margin-left: 22px;
}
#colors {
display: flex;
flex-direction: row;
justify-content: space-around;
flex-wrap: wrap;
text-align: center;
& .param {
text-align: center;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
}
.metaText {
padding: 6px;
@media @light {
color: @text-light;
}
@media @dark {
color: @text-dark;
}
& a, a:visited {
text-decoration: underline;
@media @light {
color: @text-light;
}
@media @dark {
color: @text-dark;
}
}
}
footer {
font-size: 16px;
margin-top: auto;
padding-top: 10px;
text-align: left;
}
small {
font-size: 14px;
}
#info {
font-size: 16px;
margin: 0px;
& h3 {
font-size: 20px;
font-weight: normal;
padding-bottom: 10px;
}
}
/* Inputs */
#redundancy, #margin, #ssid, #password, #txt, #size, input[type=color], input[type=submit], .button {
border-width: 2px;
border-style: solid;
border-radius: 10px;
font-size: 20px;
padding-left: 10px;
font-weight: normal;
transition: border-color 0.1s ease;
margin: 6px;
@media @light {
color: @text-light;
background-color: @bgField-light;
border-color: @border-light;
}
@media @dark {
color: @text-dark;
background-color: @bgField-dark;
border-color: @border-dark;
}
&:hover {
border-width: 3px;
margin: 5px;
border-style: solid;
@media @light {
border-color: @borderHover-light;
}
@media @dark {
border-color: @borderHover-dark;
}
}
&:focus {
border-width: 4px;
margin: 4px;
border-style: solid;
outline: none;
@media @light {
border-color: @borderFocus-light;
}
@media @dark {
border-color: @borderFocus-dark;
}
}
}
#password, #ssid {
height: 38px;
}
#redundancy {
width: 250px;
height: 44px;
&:hover {
width: 252px;
height: 46px;
}
&:focus {
width: 254px;
height: 48px;
}
}
input[type=color] {
height: 60px;
width: 84px;
padding: 5px;
&:hover {
height: 62px;
width: 86px;
}
&:focus {
height: 64px;
width: 88px;
}
}
#size, #margin {
width: 234px;
height: 38px;
}
#redundancy, #size, #margin {
@media @light {
background-color: @bgField-light;
}
@media @dark {
background-color: @bgField-dark;
}
}
.textboxParam {
display: flex;
flex-direction: column;
}
#txt {
padding: 10px;
width: auto;
scrollbar-width: auto;
@media @light {
background-color: @bgTextarea-light;
color: @textareaText-light;
scrollbar-color: @textareaText-light @bgTextarea-light;
}
@media @dark {
background-color: @bgTextarea-dark;
color: @textareaText-dark;
scrollbar-color: @textareaText-dark @bgTextarea-dark;
}
}
input[type=submit] {
cursor: pointer;
font-size: 28px;
padding: 10px;
padding-left: 14px;
padding-right: 14px;
}
#password::placeholder, #ssid::placeholder, #txt::placeholder {
opacity: 1;
font-family: system-ui, sans-serif;
font-weight: normal;
font-size: 1em;
@media @light {
color: @textareaPlaceholder-light;
}
@media @dark {
color: @textareaPlaceholder-dark;
}
}
a[download]::before {
content: "💾 ";
filter:
drop-shadow(-1px 1px 1px white)
drop-shadow(1px -1px 1px white);
}

View file

@ -1,7 +0,0 @@
:root {
// base64 -w 0 logo-light.png
--logo-light: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX///8AAABVwtN+AAAAWElEQVQoz43O0RHAMAgCUDZg/y3ZgKJtP8PF/LzkiApcFG3IVgVICB0cqCPH368jMvCffsLuPWMLmOQ+FMBxNqvgXCZ8xixGsSNppWsF33hFaLjD27Xioh5ZH8ftcymlGAAAAABJRU5ErkJggg==");
// base64 -w 0 logo-dark.png
--logo-dark: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAABlBMVEX///8AAABVwtN+AAAAXklEQVQoz43SsRHAIAxDUW3g/bfUBoqckDL/AgWvMFgcKGcIYCkjDSJ2JgwvhhFHZ9cn2vDt/oUNvkcS3MpNRuh0ew6iyyYjbDCPGa2+WxL8lCN6vZYy+nBxED/+xgWM9DYk64ncIgAAAABJRU5ErkJggg==");
}

35
themes/libreqr/theme.css Normal file
View file

@ -0,0 +1,35 @@
/* This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license */
:root {
@media (prefers-color-scheme: light) {
--logo: url("themes/libreqr/logo-light.png");
--text: black;
--bg: #ffffff; /* Must be a long hexadecimal color */
--bg-field: white;
--bg-help: white;
--bg-textarea: white;
--textarea-text: black;
--textarea-placeholder: #868686;
--border: black;
--border-hover: black;
--border-focus: black;
--border-help: black;
--border-qr: black;
}
@media (prefers-color-scheme: dark) {
--logo: url("themes/libreqr/logo-dark.png");
--text: white;
--bg: #000000; /* Must be a long hexadecimal color */
--bg-field: #000000;
--bg-help: #000000;
--bg-textarea: #000000;
--textarea-text: white;
--textarea-placeholder: #bababa;
--border: white;
--border-hover: white;
--border-focus: white;
--border-help: white;
--border-qr: white;
}
}

View file

@ -1,36 +0,0 @@
<?php // This file is part of LibreQR, which is distributed under the GNU AGPLv3+ license
// List icons dimensions
$themeDimensionsIcons = array(16, 32, 48, 64, 96, 128, 192, 256, 384, 512);
$colorScheme = array(
// Light theme
"text-light" => "black",
"bg-light" => "#ffffff", // Must be a long hexadecimal color
"bgField-light" => "white",
"bgHelp-light" => "white",
"bgTextarea-light" => "white",
"textareaText-light" => "black",
"textareaPlaceholder-light" => "#868686",
"border-light" => "black",
"borderHover-light" => "black",
"borderFocus-light" => "black",
"borderHelp-light" => "black",
"borderQr-light" => "black",
// Dark theme
"text-dark" => "white",
"bg-dark" => "#000000", // Must be a long hexadecimal color
"bgField-dark" => "#000000",
"bgHelp-dark" => "#000000",
"bgTextarea-dark" => "#000000",
"textareaText-dark" => "white",
"textareaPlaceholder-dark" => "#bababa",
"border-dark" => "white",
"borderWidth-dark" => "2px",
"borderHover-dark" => "white",
"borderHoverWidth-dark" => "3px",
"borderFocus-dark" => "white",
"borderFocusWidth-dark" => "4px",
"borderHelp-dark" => "white",
"borderQr-dark" => "white",
);