mirror of
https://github.com/thiloho/archtika.git
synced 2025-11-22 02:41:35 +01:00
Add theme toggle for templates
This commit is contained in:
@@ -23,7 +23,10 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
api = pkgs.mkShell {
|
api = pkgs.mkShell {
|
||||||
packages = with pkgs; [ postgresql_16 ];
|
packages = with pkgs; [
|
||||||
|
postgresql_16
|
||||||
|
postgrest
|
||||||
|
];
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
alias dbmate="${pkgs.dbmate}/bin/dbmate --no-dump-schema --url postgres://postgres@localhost:15432/archtika?sslmode=disable"
|
alias dbmate="${pkgs.dbmate}/bin/dbmate --no-dump-schema --url postgres://postgres@localhost:15432/archtika?sslmode=disable"
|
||||||
alias formatsql="${pkgs.pgformatter}/bin/pg_format -s 2 -f 2 -U 2 -i db/migrations/*.sql"
|
alias formatsql="${pkgs.pgformatter}/bin/pg_format -s 2 -f 2 -U 2 -i db/migrations/*.sql"
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
graphics = false;
|
graphics = false;
|
||||||
|
memorySize = 2048;
|
||||||
|
cores = 2;
|
||||||
sharedDirectories = {
|
sharedDirectories = {
|
||||||
websites = {
|
websites = {
|
||||||
source = "/var/www/archtika-websites";
|
source = "/var/www/archtika-websites";
|
||||||
@@ -59,6 +61,11 @@
|
|||||||
};
|
};
|
||||||
nginx = {
|
nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedZstdSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
|
||||||
virtualHosts."_" = {
|
virtualHosts."_" = {
|
||||||
listen = [
|
listen = [
|
||||||
{
|
{
|
||||||
@@ -67,13 +74,15 @@
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
locations = {
|
locations = {
|
||||||
|
"/previews/" = {
|
||||||
|
alias = "/var/www/archtika-websites/previews/";
|
||||||
|
index = "index.html";
|
||||||
|
tryFiles = "$uri $uri/ $uri.html =404";
|
||||||
|
};
|
||||||
"/" = {
|
"/" = {
|
||||||
root = "/var/www/archtika-websites";
|
root = "/var/www/archtika-websites";
|
||||||
index = "index.html";
|
index = "index.html";
|
||||||
tryFiles = "$uri $uri/ $uri.html =404";
|
tryFiles = "$uri $uri/ $uri.html =404";
|
||||||
extraConfig = ''
|
|
||||||
autoindex on;
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ in
|
|||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
|
WorkingDirectory = "${cfg.package}/rest-api";
|
||||||
};
|
};
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ CREATE TABLE internal.website (
|
|||||||
is_published BOOLEAN NOT NULL DEFAULT FALSE,
|
is_published BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
||||||
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
||||||
last_modified_by UUID REFERENCES internal.user (id) ON DELETE SET NULL,
|
last_modified_by UUID REFERENCES internal.user (id) ON DELETE SET NULL
|
||||||
title_search TSVECTOR GENERATED ALWAYS AS (TO_TSVECTOR('english', title)) STORED
|
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE internal.media (
|
CREATE TABLE internal.media (
|
||||||
@@ -107,7 +106,6 @@ CREATE TABLE internal.article (
|
|||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
||||||
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT CLOCK_TIMESTAMP(),
|
||||||
last_modified_by UUID REFERENCES internal.user (id) ON DELETE SET NULL,
|
last_modified_by UUID REFERENCES internal.user (id) ON DELETE SET NULL,
|
||||||
title_description_search TSVECTOR GENERATED ALWAYS AS (TO_TSVECTOR('english', COALESCE(title, '') || ' ' || COALESCE(meta_description, ''))) STORED,
|
|
||||||
UNIQUE (website_id, category, article_weight)
|
UNIQUE (website_id, category, article_weight)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
-- migrate:up
|
-- migrate:up
|
||||||
CREATE FUNCTION pgrst_watch ()
|
CREATE FUNCTION internal.pgrst_watch ()
|
||||||
RETURNS EVENT_TRIGGER
|
RETURNS EVENT_TRIGGER
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
@@ -10,10 +10,10 @@ $$
|
|||||||
LANGUAGE plpgsql;
|
LANGUAGE plpgsql;
|
||||||
|
|
||||||
CREATE EVENT TRIGGER pgrst_watch ON ddl_command_end
|
CREATE EVENT TRIGGER pgrst_watch ON ddl_command_end
|
||||||
EXECUTE FUNCTION pgrst_watch ();
|
EXECUTE FUNCTION internal.pgrst_watch ();
|
||||||
|
|
||||||
-- migrate:down
|
-- migrate:down
|
||||||
DROP EVENT TRIGGER pgrst_watch;
|
DROP EVENT TRIGGER pgrst_watch;
|
||||||
|
|
||||||
DROP FUNCTION pgrst_watch ();
|
DROP FUNCTION internal.pgrst_watch ();
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ CREATE FUNCTION internal.user_role (username TEXT, pass TEXT, OUT role_name NAME
|
|||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT
|
SELECT
|
||||||
ROLE INTO role_name
|
u.role INTO role_name
|
||||||
FROM
|
FROM
|
||||||
internal.user AS u
|
internal.user AS u
|
||||||
WHERE
|
WHERE
|
||||||
@@ -111,7 +111,7 @@ AS $$
|
|||||||
DECLARE
|
DECLARE
|
||||||
_role NAME;
|
_role NAME;
|
||||||
_user_id UUID;
|
_user_id UUID;
|
||||||
_exp INTEGER;
|
_exp INTEGER := EXTRACT(EPOCH FROM CLOCK_TIMESTAMP())::INTEGER + 86400;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT
|
SELECT
|
||||||
internal.user_role (login.username, login.pass) INTO _role;
|
internal.user_role (login.username, login.pass) INTO _role;
|
||||||
@@ -120,12 +120,11 @@ BEGIN
|
|||||||
USING message = 'Invalid username or password';
|
USING message = 'Invalid username or password';
|
||||||
ELSE
|
ELSE
|
||||||
SELECT
|
SELECT
|
||||||
id INTO _user_id
|
u.id INTO _user_id
|
||||||
FROM
|
FROM
|
||||||
internal.user AS u
|
internal.user AS u
|
||||||
WHERE
|
WHERE
|
||||||
u.username = login.username;
|
u.username = login.username;
|
||||||
_exp := EXTRACT(EPOCH FROM CLOCK_TIMESTAMP())::INTEGER + 86400;
|
|
||||||
SELECT
|
SELECT
|
||||||
SIGN(JSON_BUILD_OBJECT('role', _role, 'user_id', _user_id, 'username', login.username, 'exp', _exp), CURRENT_SETTING('app.jwt_secret')) INTO token;
|
SIGN(JSON_BUILD_OBJECT('role', _role, 'user_id', _user_id, 'username', login.username, 'exp', _exp), CURRENT_SETTING('app.jwt_secret')) INTO token;
|
||||||
END IF;
|
END IF;
|
||||||
|
|||||||
@@ -99,17 +99,7 @@ BEGIN
|
|||||||
INSERT INTO internal.home (website_id, main_content)
|
INSERT INTO internal.home (website_id, main_content)
|
||||||
VALUES (_website_id, '## About
|
VALUES (_website_id, '## About
|
||||||
|
|
||||||
archtika is a FLOSS, modern, performant and lightweight CMS (Content Mangement System) in the form of a web application. It allows you to easily create, manage and publish minimal, responsive and SEO friendly blogging and documentation websites with official, professionally designed templates.
|
archtika is a FLOSS, modern, performant and lightweight CMS (Content Mangement System) in the form of a web application. It allows you to easily create, manage and publish minimal, responsive and SEO friendly blogging and documentation websites with official, professionally designed templates. It is also possible to add contributors to your sites, which is very useful for larger projects where, for example, several people are constantly working on the documentation.');
|
||||||
|
|
||||||
It is also possible to add contributors to your sites, which is very useful for larger projects where, for example, several people are constantly working on the documentation.
|
|
||||||
|
|
||||||
## How it works
|
|
||||||
|
|
||||||
For the backend, PostgreSQL is used in combination with PostgREST to create a RESTful API. JSON web tokens along with row-level security control authentication and authorisation flows.
|
|
||||||
|
|
||||||
The web application uses SvelteKit with SSR (Server Side Rendering) and Svelte version 5, currently in beta.
|
|
||||||
|
|
||||||
NGINX is used to deploy the websites, serving the static site files from the `/var/www/archtika-websites` directory. The static files can be found in this directory via the path `<user_id>/<website_id>`, which is dynamically created by the web application.');
|
|
||||||
INSERT INTO internal.footer (website_id, additional_text)
|
INSERT INTO internal.footer (website_id, additional_text)
|
||||||
VALUES (_website_id, 'archtika is a free, open, modern, performant and lightweight CMS');
|
VALUES (_website_id, 'archtika is a free, open, modern, performant and lightweight CMS');
|
||||||
website_id := _website_id;
|
website_id := _website_id;
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ DECLARE
|
|||||||
BEGIN
|
BEGIN
|
||||||
IF (NOT EXISTS (
|
IF (NOT EXISTS (
|
||||||
SELECT
|
SELECT
|
||||||
id
|
u.id
|
||||||
FROM
|
FROM
|
||||||
internal.user
|
internal.user AS u
|
||||||
WHERE
|
WHERE
|
||||||
id = _user_id)) THEN
|
u.id = _user_id)) THEN
|
||||||
RETURN COALESCE(NEW, OLD);
|
RETURN COALESCE(NEW, OLD);
|
||||||
END IF;
|
END IF;
|
||||||
IF TG_OP != 'DELETE' THEN
|
IF TG_OP != 'DELETE' THEN
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ BEGIN
|
|||||||
SELECT
|
SELECT
|
||||||
UNNEST(_allowed_mimetypes))) THEN
|
UNNEST(_allowed_mimetypes))) THEN
|
||||||
RAISE invalid_parameter_value
|
RAISE invalid_parameter_value
|
||||||
USING message = 'Invalid MIME type. Allowed types are: png, jpg, webp';
|
USING message = 'Invalid MIME type. Allowed types are: png, jpg, webp, avif, gif, svg';
|
||||||
ELSIF OCTET_LENGTH($1) > _max_file_size THEN
|
ELSIF OCTET_LENGTH($1) > _max_file_size THEN
|
||||||
RAISE program_limit_exceeded
|
RAISE program_limit_exceeded
|
||||||
USING message = FORMAT('File size exceeds the maximum limit of %s MB', _max_file_size / (1024 * 1024));
|
USING message = FORMAT('File size exceeds the maximum limit of %s MB', _max_file_size / (1024 * 1024));
|
||||||
@@ -56,7 +56,7 @@ BEGIN
|
|||||||
SELECT
|
SELECT
|
||||||
m.blob
|
m.blob
|
||||||
FROM
|
FROM
|
||||||
internal.media m
|
internal.media AS m
|
||||||
WHERE
|
WHERE
|
||||||
m.id = retrieve_file.id INTO _blob;
|
m.id = retrieve_file.id INTO _blob;
|
||||||
IF FOUND THEN
|
IF FOUND THEN
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ DECLARE
|
|||||||
BEGIN
|
BEGIN
|
||||||
IF (NOT EXISTS (
|
IF (NOT EXISTS (
|
||||||
SELECT
|
SELECT
|
||||||
id
|
u.id
|
||||||
FROM
|
FROM
|
||||||
internal.user
|
internal.user AS u
|
||||||
WHERE
|
WHERE
|
||||||
id = _user_id) OR (to_jsonb (OLD.*) - 'last_modified_at' - 'last_modified_by') = (to_jsonb (NEW.*) - 'last_modified_at' - 'last_modified_by')) THEN
|
u.id = _user_id) OR (to_jsonb (OLD.*) - 'last_modified_at' - 'last_modified_by') = (to_jsonb (NEW.*) - 'last_modified_at' - 'last_modified_by')) THEN
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
END IF;
|
END IF;
|
||||||
IF TG_TABLE_NAME = 'website' THEN
|
IF TG_TABLE_NAME = 'website' THEN
|
||||||
@@ -40,21 +40,21 @@ BEGIN
|
|||||||
ELSIF (TG_OP = 'UPDATE'
|
ELSIF (TG_OP = 'UPDATE'
|
||||||
AND EXISTS (
|
AND EXISTS (
|
||||||
SELECT
|
SELECT
|
||||||
id
|
w.id
|
||||||
FROM
|
FROM
|
||||||
internal.website
|
internal.website AS w
|
||||||
WHERE
|
WHERE
|
||||||
id = _website_id)) THEN
|
w.id = _website_id)) THEN
|
||||||
INSERT INTO internal.change_log (website_id, table_name, operation, old_value, new_value)
|
INSERT INTO internal.change_log (website_id, table_name, operation, old_value, new_value)
|
||||||
VALUES (_website_id, TG_TABLE_NAME, TG_OP, HSTORE (OLD) - HSTORE (NEW), HSTORE (NEW) - HSTORE (OLD));
|
VALUES (_website_id, TG_TABLE_NAME, TG_OP, HSTORE (OLD) - HSTORE (NEW), HSTORE (NEW) - HSTORE (OLD));
|
||||||
ELSIF (TG_OP = 'DELETE'
|
ELSIF (TG_OP = 'DELETE'
|
||||||
AND EXISTS (
|
AND EXISTS (
|
||||||
SELECT
|
SELECT
|
||||||
id
|
w.id
|
||||||
FROM
|
FROM
|
||||||
internal.website
|
internal.website AS w
|
||||||
WHERE
|
WHERE
|
||||||
id = _website_id)) THEN
|
w.id = _website_id)) THEN
|
||||||
INSERT INTO internal.change_log (website_id, table_name, operation, old_value)
|
INSERT INTO internal.change_log (website_id, table_name, operation, old_value)
|
||||||
VALUES (_website_id, TG_TABLE_NAME, TG_OP, HSTORE (OLD));
|
VALUES (_website_id, TG_TABLE_NAME, TG_OP, HSTORE (OLD));
|
||||||
END IF;
|
END IF;
|
||||||
|
|||||||
@@ -24,6 +24,16 @@
|
|||||||
const scrollHeight = previewElement.scrollHeight - previewElement.clientHeight;
|
const scrollHeight = previewElement.scrollHeight - previewElement.clientHeight;
|
||||||
previewElement.scrollTop = (textareaScrollTop.value / 100) * scrollHeight;
|
previewElement.scrollTop = (textareaScrollTop.value / 100) * scrollHeight;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
"settings",
|
||||||
|
"articles",
|
||||||
|
"categories",
|
||||||
|
"collaborators",
|
||||||
|
"legal-information",
|
||||||
|
"publish",
|
||||||
|
"logs"
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<input type="checkbox" id="toggle-mobile-preview" hidden />
|
<input type="checkbox" id="toggle-mobile-preview" hidden />
|
||||||
@@ -34,27 +44,17 @@
|
|||||||
|
|
||||||
<nav class="operations__nav">
|
<nav class="operations__nav">
|
||||||
<ul class="unpadded">
|
<ul class="unpadded">
|
||||||
<li>
|
{#each tabs.filter((tab) => (tab !== "categories" && contentType === "Blog") || contentType === "Docs") as tab}
|
||||||
<a href="/website/{id}">Settings</a>
|
<li>
|
||||||
</li>
|
<a
|
||||||
<li>
|
href="/website/{id}{tab === 'settings' ? '' : `/${tab}`}"
|
||||||
<a href="/website/{id}/articles">Articles</a>
|
class:active={tab === "settings"
|
||||||
</li>
|
? $page.url.pathname === `/website/${id}`
|
||||||
{#if contentType === "Docs"}
|
: $page.url.pathname.includes(tab)}
|
||||||
<a href="/website/{id}/categories">Categories</a>
|
>{(tab.charAt(0).toUpperCase() + tab.slice(1)).replace("-", " ") || "Settings"}</a
|
||||||
{/if}
|
>
|
||||||
<li>
|
</li>
|
||||||
<a href="/website/{id}/collaborators">Collaborators</a>
|
{/each}
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="/website/{id}/legal-information">Legal information</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="/website/{id}/publish">Publish</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="/website/{id}/logs">Logs</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -117,6 +117,11 @@
|
|||||||
gap: var(--space-s);
|
gap: var(--space-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
text-underline-offset: 0.375rem;
|
||||||
|
text-decoration-thickness: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
label[for="toggle-mobile-preview"] {
|
label[for="toggle-mobile-preview"] {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ export interface Article {
|
|||||||
created_at: Date;
|
created_at: Date;
|
||||||
last_modified_at: Date;
|
last_modified_at: Date;
|
||||||
last_modified_by: string | null;
|
last_modified_by: string | null;
|
||||||
title_description_search: any | null;
|
|
||||||
}
|
}
|
||||||
export interface ArticleInput {
|
export interface ArticleInput {
|
||||||
id?: string;
|
id?: string;
|
||||||
@@ -44,7 +43,6 @@ export interface ArticleInput {
|
|||||||
created_at?: Date;
|
created_at?: Date;
|
||||||
last_modified_at?: Date;
|
last_modified_at?: Date;
|
||||||
last_modified_by?: string | null;
|
last_modified_by?: string | null;
|
||||||
title_description_search?: any | null;
|
|
||||||
}
|
}
|
||||||
const article = {
|
const article = {
|
||||||
tableName: "article",
|
tableName: "article",
|
||||||
@@ -62,8 +60,7 @@ const article = {
|
|||||||
"article_weight",
|
"article_weight",
|
||||||
"created_at",
|
"created_at",
|
||||||
"last_modified_at",
|
"last_modified_at",
|
||||||
"last_modified_by",
|
"last_modified_by"
|
||||||
"title_description_search"
|
|
||||||
],
|
],
|
||||||
requiredForInsert: ["website_id", "title"],
|
requiredForInsert: ["website_id", "title"],
|
||||||
primaryKey: "id",
|
primaryKey: "id",
|
||||||
@@ -463,7 +460,6 @@ export interface Website {
|
|||||||
created_at: Date;
|
created_at: Date;
|
||||||
last_modified_at: Date;
|
last_modified_at: Date;
|
||||||
last_modified_by: string | null;
|
last_modified_by: string | null;
|
||||||
title_search: any | null;
|
|
||||||
}
|
}
|
||||||
export interface WebsiteInput {
|
export interface WebsiteInput {
|
||||||
id?: string;
|
id?: string;
|
||||||
@@ -474,7 +470,6 @@ export interface WebsiteInput {
|
|||||||
created_at?: Date;
|
created_at?: Date;
|
||||||
last_modified_at?: Date;
|
last_modified_at?: Date;
|
||||||
last_modified_by?: string | null;
|
last_modified_by?: string | null;
|
||||||
title_search?: any | null;
|
|
||||||
}
|
}
|
||||||
const website = {
|
const website = {
|
||||||
tableName: "website",
|
tableName: "website",
|
||||||
@@ -486,8 +481,7 @@ const website = {
|
|||||||
"is_published",
|
"is_published",
|
||||||
"created_at",
|
"created_at",
|
||||||
"last_modified_at",
|
"last_modified_at",
|
||||||
"last_modified_by",
|
"last_modified_by"
|
||||||
"title_search"
|
|
||||||
],
|
],
|
||||||
requiredForInsert: ["content_type", "title"],
|
requiredForInsert: ["content_type", "title"],
|
||||||
primaryKey: "id",
|
primaryKey: "id",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<svelte:head>
|
<svelte:head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>{title}</title>
|
<title>{websiteOverview.title === title ? title : `${websiteOverview.title} | ${title}`}</title>
|
||||||
<meta name="description" content={metaDescription ?? title} />
|
<meta name="description" content={metaDescription ?? title} />
|
||||||
<link rel="stylesheet" href={`${"../".repeat(nestingLevel)}styles.css`} />
|
<link rel="stylesheet" href={`${"../".repeat(nestingLevel)}styles.css`} />
|
||||||
{#if websiteOverview.settings.favicon_image}
|
{#if websiteOverview.settings.favicon_image}
|
||||||
|
|||||||
@@ -82,5 +82,32 @@
|
|||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
|
<label style="margin-inline-start: auto;" for="toggle-theme">
|
||||||
|
<input type="checkbox" id="toggle-theme" hidden />
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10 2a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0v-1.5A.75.75 0 0 1 10 2ZM10 15a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0v-1.5A.75.75 0 0 1 10 15ZM10 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6ZM15.657 5.404a.75.75 0 1 0-1.06-1.06l-1.061 1.06a.75.75 0 0 0 1.06 1.06l1.06-1.06ZM6.464 14.596a.75.75 0 1 0-1.06-1.06l-1.06 1.06a.75.75 0 0 0 1.06 1.06l1.06-1.06ZM18 10a.75.75 0 0 1-.75.75h-1.5a.75.75 0 0 1 0-1.5h1.5A.75.75 0 0 1 18 10ZM5 10a.75.75 0 0 1-.75.75h-1.5a.75.75 0 0 1 0-1.5h1.5A.75.75 0 0 1 5 10ZM14.596 15.657a.75.75 0 0 0 1.06-1.06l-1.06-1.061a.75.75 0 1 0-1.06 1.06l1.06 1.06ZM5.404 6.464a.75.75 0 0 0 1.06-1.06l-1.06-1.06a.75.75 0 1 0-1.061 1.06l1.06 1.06Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M7.455 2.004a.75.75 0 0 1 .26.77 7 7 0 0 0 9.958 7.967.75.75 0 0 1 1.067.853A8.5 8.5 0 1 1 6.647 1.921a.75.75 0 0 1 .808.083Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { Renderer, Token } from "marked";
|
|||||||
import { markedHighlight } from "marked-highlight";
|
import { markedHighlight } from "marked-highlight";
|
||||||
import hljs from "highlight.js";
|
import hljs from "highlight.js";
|
||||||
import DOMPurify from "isomorphic-dompurify";
|
import DOMPurify from "isomorphic-dompurify";
|
||||||
import { applyAction, deserialize } from "$app/forms";
|
|
||||||
import type {
|
import type {
|
||||||
Website,
|
Website,
|
||||||
Settings,
|
Settings,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const actions: Actions = {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookies.set("session_token", response.data.token, { path: "/" });
|
cookies.set("session_token", response.data.token, { path: "/", maxAge: 86400 });
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const load: PageServerLoad = async ({ fetch, url, locals }) => {
|
|||||||
const baseFetchUrl = `${API_BASE_PREFIX}/website?order=last_modified_at.desc,created_at.desc`;
|
const baseFetchUrl = `${API_BASE_PREFIX}/website?order=last_modified_at.desc,created_at.desc`;
|
||||||
|
|
||||||
if (searchQuery) {
|
if (searchQuery) {
|
||||||
params.append("title_search", `wfts(english).${searchQuery}`);
|
params.append("title", `wfts.${searchQuery}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (filterBy) {
|
switch (filterBy) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const load: PageServerLoad = async ({ params, fetch, url, parent, locals
|
|||||||
const parameters = new URLSearchParams();
|
const parameters = new URLSearchParams();
|
||||||
|
|
||||||
if (searchQuery) {
|
if (searchQuery) {
|
||||||
parameters.append("title_description_search", `wfts(english).${searchQuery}`);
|
parameters.append("title", `wfts.${searchQuery}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (filterBy) {
|
switch (filterBy) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
import { tables } from "$lib/db-schema";
|
import { tables } from "$lib/db-schema";
|
||||||
import { previewContent } from "$lib/runes.svelte";
|
import { previewContent } from "$lib/runes.svelte";
|
||||||
import { sanitize } from "isomorphic-dompurify";
|
import DOMPurify from "isomorphic-dompurify";
|
||||||
|
|
||||||
const { data }: { data: PageServerData } = $props();
|
const { data }: { data: PageServerData } = $props();
|
||||||
|
|
||||||
@@ -156,9 +156,12 @@
|
|||||||
<p>{table_name} — {operation}</p>
|
<p>{table_name} — {operation}</p>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
|
|
||||||
<pre style="white-space: pre-wrap">{@html sanitize(htmlDiff(oldValue, newValue), {
|
<pre style="white-space: pre-wrap">{@html DOMPurify.sanitize(
|
||||||
ALLOWED_TAGS: ["ins", "del"]
|
htmlDiff(oldValue, newValue),
|
||||||
})}</pre>
|
{
|
||||||
|
ALLOWED_TAGS: ["ins", "del"]
|
||||||
|
}
|
||||||
|
)}</pre>
|
||||||
</Modal>
|
</Modal>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ nav {
|
|||||||
border-block-end: var(--border-primary);
|
border-block-end: var(--border-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nav > .container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2xs);
|
||||||
|
}
|
||||||
|
|
||||||
header > .container {
|
header > .container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -1,41 +1,4 @@
|
|||||||
@import url("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github.min.css")
|
html {
|
||||||
screen and (prefers-color-scheme: light);
|
|
||||||
@import url("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github-dark.min.css")
|
|
||||||
screen and (prefers-color-scheme: dark);
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "JetBrains Mono";
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 400;
|
|
||||||
src:
|
|
||||||
url(https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono@latest/latin-400-normal.woff2)
|
|
||||||
format("woff2"),
|
|
||||||
url(https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono@latest/latin-400-normal.woff)
|
|
||||||
format("woff");
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
|
|
||||||
U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
|
|
||||||
U+FFFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--bg-primary-h: /* BACKGROUND_COLOR_LIGHT_THEME_H */ 0;
|
|
||||||
--bg-primary-s: /* BACKGROUND_COLOR_LIGHT_THEME_S */ 0%;
|
|
||||||
--bg-primary-l: /* BACKGROUND_COLOR_LIGHT_THEME_L */ 100%;
|
|
||||||
--bg-primary: hsl(var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l));
|
|
||||||
--bg-secondary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 5%));
|
|
||||||
--bg-tertiary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 10%));
|
|
||||||
--bg-blurred: hsla(
|
|
||||||
var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l) / calc(var(--bg-primary-l) - 20%)
|
|
||||||
);
|
|
||||||
|
|
||||||
--color-text: hsl(var(--bg-primary-h) var(--bg-primary-s) 0%);
|
|
||||||
--color-text-invert: var(--bg-primary);
|
|
||||||
--color-border: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 50%));
|
|
||||||
--color-accent: /* ACCENT_COLOR_LIGHT_THEME */ hsl(210 100% 30%);
|
|
||||||
--color-success: hsl(105 100% 30%);
|
|
||||||
--color-error: hsl(0 100% 30%);
|
|
||||||
|
|
||||||
--border-primary: 0.0625rem solid var(--color-border);
|
--border-primary: 0.0625rem solid var(--color-border);
|
||||||
--border-radius: 0.125rem;
|
--border-radius: 0.125rem;
|
||||||
|
|
||||||
@@ -72,12 +35,92 @@
|
|||||||
--space-2xl: clamp(4rem, 3.7368rem + 1.3158cqi, 5rem);
|
--space-2xl: clamp(4rem, 3.7368rem + 1.3158cqi, 5rem);
|
||||||
/* Space 3xl: 96px → 120px */
|
/* Space 3xl: 96px → 120px */
|
||||||
--space-3xl: clamp(6rem, 5.6053rem + 1.9737cqi, 7.5rem);
|
--space-3xl: clamp(6rem, 5.6053rem + 1.9737cqi, 7.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
--bg-primary-h: /* BACKGROUND_COLOR_LIGHT_THEME_H */ 0;
|
||||||
|
--bg-primary-s: /* BACKGROUND_COLOR_LIGHT_THEME_S */ 0%;
|
||||||
|
--bg-primary-l: /* BACKGROUND_COLOR_LIGHT_THEME_L */ 100%;
|
||||||
|
--bg-primary: hsl(var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l));
|
||||||
|
--bg-secondary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 5%));
|
||||||
|
--bg-tertiary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 10%));
|
||||||
|
--bg-blurred: hsla(
|
||||||
|
var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l) / calc(var(--bg-primary-l) - 20%)
|
||||||
|
);
|
||||||
|
|
||||||
|
--color-text: hsl(var(--bg-primary-h) var(--bg-primary-s) 0%);
|
||||||
|
--color-text-invert: var(--bg-primary);
|
||||||
|
--color-border: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 50%));
|
||||||
|
--color-accent: /* ACCENT_COLOR_LIGHT_THEME */ hsl(210 100% 30%);
|
||||||
|
--color-success: hsl(105 100% 30%);
|
||||||
|
--color-error: hsl(0 100% 30%);
|
||||||
|
|
||||||
|
--display-light: none;
|
||||||
|
--display-dark: initial;
|
||||||
|
|
||||||
|
--hl-bg: #fff;
|
||||||
|
--hl-color: #24292e;
|
||||||
|
--hl-keyword: #d73a49;
|
||||||
|
--hl-title: #6f42c1;
|
||||||
|
--hl-attr: #005cc5;
|
||||||
|
--hl-string: #032f62;
|
||||||
|
--hl-built-in: #e36209;
|
||||||
|
--hl-comment: #6a737d;
|
||||||
|
--hl-tag: #22863a;
|
||||||
|
--hl-section: #005cc5;
|
||||||
|
--hl-bullet: #735c0f;
|
||||||
|
--hl-emphasis: #24292e;
|
||||||
|
--hl-addition-bg: #f0fff4;
|
||||||
|
--hl-addition-text: #22863a;
|
||||||
|
--hl-deletion-bg: #ffeef0;
|
||||||
|
--hl-deletion-text: #b31d28;
|
||||||
|
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html:has(#toggle-theme:checked) {
|
||||||
|
--bg-primary-h: /* BACKGROUND_COLOR_DARK_THEME_H */ 0;
|
||||||
|
--bg-primary-s: /* BACKGROUND_COLOR_DARK_THEME_S */ 0%;
|
||||||
|
--bg-primary-l: /* BACKGROUND_COLOR_DARK_THEME_L */ 15%;
|
||||||
|
--bg-primary: hsl(var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l));
|
||||||
|
--bg-secondary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) + 5%));
|
||||||
|
--bg-tertiary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) + 10%));
|
||||||
|
--bg-blurred: hsla(
|
||||||
|
var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l) / calc(var(--bg-primary-l) + 20%)
|
||||||
|
);
|
||||||
|
|
||||||
|
--color-text: hsl(var(--bg-primary-h) var(--bg-primary-s) 100%);
|
||||||
|
--color-text-invert: var(--bg-primary);
|
||||||
|
--color-border: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) + 50%));
|
||||||
|
--color-accent: /* ACCENT_COLOR_DARK_THEME */ hsl(210 100% 80%);
|
||||||
|
--color-success: hsl(105 100% 80%);
|
||||||
|
--color-error: hsl(0 100% 80%);
|
||||||
|
|
||||||
|
--display-light: initial;
|
||||||
|
--display-dark: none;
|
||||||
|
|
||||||
|
--hl-bg: #0d1117;
|
||||||
|
--hl-color: #c9d1d9;
|
||||||
|
--hl-keyword: #ff7b72;
|
||||||
|
--hl-title: #d2a8ff;
|
||||||
|
--hl-attr: #79c0ff;
|
||||||
|
--hl-string: #a5d6ff;
|
||||||
|
--hl-built-in: #ffa657;
|
||||||
|
--hl-comment: #8b949e;
|
||||||
|
--hl-tag: #7ee787;
|
||||||
|
--hl-section: #1f6feb;
|
||||||
|
--hl-bullet: #f2cc60;
|
||||||
|
--hl-emphasis: #c9d1d9;
|
||||||
|
--hl-addition-bg: #033a16;
|
||||||
|
--hl-addition-text: #aff5b4;
|
||||||
|
--hl-deletion-bg: #67060c;
|
||||||
|
--hl-deletion-text: #ffdcd7;
|
||||||
|
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root {
|
html {
|
||||||
--bg-primary-h: /* BACKGROUND_COLOR_DARK_THEME_H */ 0;
|
--bg-primary-h: /* BACKGROUND_COLOR_DARK_THEME_H */ 0;
|
||||||
--bg-primary-s: /* BACKGROUND_COLOR_DARK_THEME_S */ 0%;
|
--bg-primary-s: /* BACKGROUND_COLOR_DARK_THEME_S */ 0%;
|
||||||
--bg-primary-l: /* BACKGROUND_COLOR_DARK_THEME_L */ 15%;
|
--bg-primary-l: /* BACKGROUND_COLOR_DARK_THEME_L */ 15%;
|
||||||
@@ -95,8 +138,69 @@
|
|||||||
--color-success: hsl(105 100% 80%);
|
--color-success: hsl(105 100% 80%);
|
||||||
--color-error: hsl(0 100% 80%);
|
--color-error: hsl(0 100% 80%);
|
||||||
|
|
||||||
|
--display-light: initial;
|
||||||
|
--display-dark: none;
|
||||||
|
|
||||||
|
--hl-bg: #0d1117;
|
||||||
|
--hl-color: #c9d1d9;
|
||||||
|
--hl-keyword: #ff7b72;
|
||||||
|
--hl-title: #d2a8ff;
|
||||||
|
--hl-attr: #79c0ff;
|
||||||
|
--hl-string: #a5d6ff;
|
||||||
|
--hl-built-in: #ffa657;
|
||||||
|
--hl-comment: #8b949e;
|
||||||
|
--hl-tag: #7ee787;
|
||||||
|
--hl-section: #1f6feb;
|
||||||
|
--hl-bullet: #f2cc60;
|
||||||
|
--hl-emphasis: #c9d1d9;
|
||||||
|
--hl-addition-bg: #033a16;
|
||||||
|
--hl-addition-text: #aff5b4;
|
||||||
|
--hl-deletion-bg: #67060c;
|
||||||
|
--hl-deletion-text: #ffdcd7;
|
||||||
|
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html:has(#toggle-theme:checked) {
|
||||||
|
--bg-primary-h: /* BACKGROUND_COLOR_LIGHT_THEME_H */ 0;
|
||||||
|
--bg-primary-s: /* BACKGROUND_COLOR_LIGHT_THEME_S */ 0%;
|
||||||
|
--bg-primary-l: /* BACKGROUND_COLOR_LIGHT_THEME_L */ 100%;
|
||||||
|
--bg-primary: hsl(var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l));
|
||||||
|
--bg-secondary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 5%));
|
||||||
|
--bg-tertiary: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 10%));
|
||||||
|
--bg-blurred: hsla(
|
||||||
|
var(--bg-primary-h) var(--bg-primary-s) var(--bg-primary-l) / calc(var(--bg-primary-l) - 20%)
|
||||||
|
);
|
||||||
|
|
||||||
|
--color-text: hsl(var(--bg-primary-h) var(--bg-primary-s) 0%);
|
||||||
|
--color-text-invert: var(--bg-primary);
|
||||||
|
--color-border: hsl(var(--bg-primary-h) var(--bg-primary-s) calc(var(--bg-primary-l) - 50%));
|
||||||
|
--color-accent: /* ACCENT_COLOR_LIGHT_THEME */ hsl(210 100% 30%);
|
||||||
|
--color-success: hsl(105 100% 30%);
|
||||||
|
--color-error: hsl(0 100% 30%);
|
||||||
|
|
||||||
|
--display-light: none;
|
||||||
|
--display-dark: initial;
|
||||||
|
|
||||||
|
--hl-bg: #fff;
|
||||||
|
--hl-color: #24292e;
|
||||||
|
--hl-keyword: #d73a49;
|
||||||
|
--hl-title: #6f42c1;
|
||||||
|
--hl-attr: #005cc5;
|
||||||
|
--hl-string: #032f62;
|
||||||
|
--hl-built-in: #e36209;
|
||||||
|
--hl-comment: #6a737d;
|
||||||
|
--hl-tag: #22863a;
|
||||||
|
--hl-section: #005cc5;
|
||||||
|
--hl-bullet: #735c0f;
|
||||||
|
--hl-emphasis: #24292e;
|
||||||
|
--hl-addition-bg: #f0fff4;
|
||||||
|
--hl-addition-text: #22863a;
|
||||||
|
--hl-deletion-bg: #ffeef0;
|
||||||
|
--hl-deletion-text: #b31d28;
|
||||||
|
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*,
|
*,
|
||||||
@@ -109,11 +213,12 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-family: system-ui, sans-serif;
|
font-family: system-ui;
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-block-size: 100vh;
|
min-block-size: 100vh;
|
||||||
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
@@ -123,6 +228,7 @@ select,
|
|||||||
[role="option"],
|
[role="option"],
|
||||||
label[for="toggle-mobile-preview"],
|
label[for="toggle-mobile-preview"],
|
||||||
label[for="toggle-sidebar"],
|
label[for="toggle-sidebar"],
|
||||||
|
label[for="toggle-theme"],
|
||||||
summary {
|
summary {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@@ -134,6 +240,7 @@ select,
|
|||||||
a[role="button"],
|
a[role="button"],
|
||||||
label[for="toggle-mobile-preview"],
|
label[for="toggle-mobile-preview"],
|
||||||
label[for="toggle-sidebar"],
|
label[for="toggle-sidebar"],
|
||||||
|
label[for="toggle-theme"],
|
||||||
summary {
|
summary {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
@@ -174,15 +281,30 @@ button,
|
|||||||
a[role="button"],
|
a[role="button"],
|
||||||
label[for="toggle-mobile-preview"],
|
label[for="toggle-mobile-preview"],
|
||||||
label[for="toggle-sidebar"],
|
label[for="toggle-sidebar"],
|
||||||
|
label[for="toggle-theme"],
|
||||||
summary {
|
summary {
|
||||||
background-color: var(--bg-secondary);
|
background-color: var(--bg-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label:has(svg) {
|
||||||
|
display: inline-grid;
|
||||||
|
place-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
label[for="toggle-theme"] svg:first-of-type {
|
||||||
|
display: var(--display-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
label[for="toggle-theme"] svg:last-of-type {
|
||||||
|
display: var(--display-dark);
|
||||||
|
}
|
||||||
|
|
||||||
:is(
|
:is(
|
||||||
button,
|
button,
|
||||||
a[role="button"],
|
a[role="button"],
|
||||||
label[for="toggle-mobile-preview"],
|
label[for="toggle-mobile-preview"],
|
||||||
label[for="toggle-sidebar"],
|
label[for="toggle-sidebar"],
|
||||||
|
label[for="toggle-theme"],
|
||||||
summary
|
summary
|
||||||
):hover {
|
):hover {
|
||||||
background-color: var(--bg-tertiary);
|
background-color: var(--bg-tertiary);
|
||||||
@@ -304,7 +426,7 @@ pre {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: "JetBrains Mono", monospace;
|
font-family: monospace;
|
||||||
font-size: var(--font-size--1);
|
font-size: var(--font-size--1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,3 +476,95 @@ del {
|
|||||||
background-color: var(--color-error);
|
background-color: var(--color-error);
|
||||||
color: var(--color-text-invert);
|
color: var(--color-text-invert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
color: var(--hl-color);
|
||||||
|
background: var(--hl-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-meta .hljs-keyword,
|
||||||
|
.hljs-template-tag,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-variable.language_ {
|
||||||
|
color: var(--hl-keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-title.class_,
|
||||||
|
.hljs-title.class_.inherited__,
|
||||||
|
.hljs-title.function_ {
|
||||||
|
color: var(--hl-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-operator,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-variable {
|
||||||
|
color: var(--hl-attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-meta .hljs-string,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-string {
|
||||||
|
color: var(--hl-string);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-symbol {
|
||||||
|
color: var(--hl-built-in);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-code,
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-formula {
|
||||||
|
color: var(--hl-comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-selector-pseudo,
|
||||||
|
.hljs-selector-tag {
|
||||||
|
color: var(--hl-tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-subst {
|
||||||
|
color: var(--hl-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-section {
|
||||||
|
color: var(--hl-section);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-bullet {
|
||||||
|
color: var(--hl-bullet);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
color: var(--hl-emphasis);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
color: var(--hl-emphasis);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
color: var(--hl-addition-text);
|
||||||
|
background-color: var(--hl-addition-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
color: var(--hl-deletion-text);
|
||||||
|
background-color: var(--hl-deletion-bg);
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,11 +41,6 @@ section {
|
|||||||
scroll-margin-block-start: var(--space-xl);
|
scroll-margin-block-start: var(--space-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
label[for="toggle-sidebar"] {
|
|
||||||
display: inline-grid;
|
|
||||||
place-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.docs-navigation {
|
.docs-navigation {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
Reference in New Issue
Block a user