Compare commits

..

No commits in common. "main" and "version-2" have entirely different histories.

41 changed files with 1236 additions and 1172 deletions

View file

@ -1,11 +0,0 @@
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false
max_line_length = 90
[*.md]
max_line_length = 0

6
.gitattributes vendored Normal file
View file

@ -0,0 +1,6 @@
*.ttf filter=lfs diff=lfs merge=lfs -text
*.otf filter=lfs diff=lfs merge=lfs -text
*.woff filter=lfs diff=lfs merge=lfs -text
*.woff2 filter=lfs diff=lfs merge=lfs -text
*.wasm filter=lfs diff=lfs merge=lfs -text
static/glow/glow.js filter=lfs diff=lfs merge=lfs -text

2
.gitignore vendored
View file

@ -1 +1 @@
/target
_site/

View file

245
Cargo.lock generated
View file

@ -1,245 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "argh"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb41d85d92dfab96cb95ab023c265c5e4261bb956c0fb49ca06d90c570f1958"
dependencies = [
"argh_derive",
"argh_shared",
]
[[package]]
name = "argh_derive"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be69f70ef5497dd6ab331a50bd95c6ac6b8f7f17a7967838332743fbd58dc3b5"
dependencies = [
"argh_shared",
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "argh_shared"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f8c380fa28aa1b36107cd97f0196474bb7241bb95a453c5c01a15ac74b2eac"
[[package]]
name = "ascii"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chunked_transfer"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
[[package]]
name = "faery-ring"
version = "0.2.0"
dependencies = [
"argh",
"ascii",
"tiny_http",
]
[[package]]
name = "form_urlencoded"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
"percent-encoding",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "libc"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "num_threads"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15"
dependencies = [
"libc",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "time"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
dependencies = [
"itoa",
"libc",
"num_threads",
"time-macros",
]
[[package]]
name = "time-macros"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
[[package]]
name = "tiny_http"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f8734c6d6943ad6df6b588d228a87b4af184998bcffa268ceddf05c2055a8c"
dependencies = [
"ascii",
"chunked_transfer",
"log",
"time",
"url",
]
[[package]]
name = "tinyvec"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "unicode-bidi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
"idna",
"matches",
"percent-encoding",
]

View file

@ -1,31 +0,0 @@
[package]
name = "faery-ring"
version = "0.2.0"
edition = "2021"
authors = ["Emi Simpson <emi@alchemi.dev>"]
description = "An ultra-lightweight js-free server-side webring implementation"
repository = "https://fem.mint.lgbt/Emi/faery-ring"
license-file = "LICENSE.md"
keywords = ["webring", "indieweb", "web", "discovery", "server"]
rust-version = "1.58"
readme = "README.md"
exclude = ["/Dockerfile", ".*"]
homepage = "https://fem.mint.lgbt/Emi/faery-ring"
[badges]
maintenance = { status = "passively-maintained" }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tiny_http = "0.10.0"
argh = "0.1.7"
ascii = "1.0.0"
[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
[badges]
maintenance = { status = "passively-maintained" }

View file

@ -1,10 +0,0 @@
FROM rust:1.58-alpine AS builder
RUN apk update
RUN apk add musl-dev
ADD . .
RUN cargo build --target=x86_64-unknown-linux-musl --release
FROM scratch
COPY --from=builder target/x86_64-unknown-linux-musl/release/faery-ring /
ENTRYPOINT ["/faery-ring"]
CMD ["/domains.txt"]

View file

@ -1,483 +0,0 @@
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
COOPERATIVE NON-VIOLENT PUBLIC LICENSE (\"LICENSE\"). THE WORK IS
PROTECTED BY COPYRIGHT AND ALL OTHER APPLICABLE LAWS. ANY USE OF THE
WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED IN THIS
LICENSE, YOU AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE.TO THE
EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR
GRANTS YOU THE RIGHTS CONTAINED HERE IN AS CONSIDERATION FOR ACCEPTING
THE TERMS AND CONDITIONS OF THIS LICENSE AND FOR AGREEING TO BE BOUND BY
THE TERMS AND CONDITIONS OF THIS LICENSE.
# Definitions
An Act of War is any action of one country against any group either with
an intention to provoke a conflict or an action that occurs during a
declared war or during armed conflict between military forces of any
origin. This includes but is not limited to enforcing sanctions or
sieges, supplying armed forces, or profiting from the manufacture of
tools or weaponry used in military conflict.
An Adaptation is a work based upon the Work, or upon the Work and other
pre-existing works, such as a translation, adaptation, derivative work,
arrangement of music or other alterations of a literary or artistic
work, or phonogram or performance and includes cinematographic
adaptations or any other form in which the Work may be recast,
transformed, or adapted including in any form recognizably derived from
the original, except that a work that constitutes a Collection will not
be considered an Adaptation for the purpose of this License. For the
avoidance of doubt, where the Work is a musical work, performance or
phonogram, the synchronization of the Work in timed-relation with a
moving image (\"synching\") will be considered an Adaptation for the
purpose of this License. In addition, where the Work is designed to
output a neural network the output of the neural network will be
considered an Adaptation for the purpose of this license.
Bodily Harm is any physical hurt or injury to a person that interferes
with the health or comfort of the person and that is more than merely
transient or trifling in nature.
Distribute is to make available to the public the original and copies of
the Work or Adaptation, as appropriate, through sale, gift or any other
transfer of possession or ownership.
Incarceration is Confinement in a jail, prison, or any other place where
individuals of any kind are held against either their will or (if their
will cannot be determined) the will of their legal guardian or
guardians. In the case of a conflict between the will of the individual
and the will of their legal guardian or guardians, the will of the
individual will take precedence.
Licensor is The individual, individuals, entity, or entities that
offer(s) the Work under the terms of this License
Original Author is in the case of a literary or artistic work, the
individual, individuals, entity or entities who created the Work or if
no individual or entity can be identified, the publisher; and in
addition
- in the case of a performance the actors, singers, musicians,
dancers, and other persons who act, sing, deliver, declaim, play in,
interpret or otherwise perform literary or artistic works or
expressions of folklore;
- in the case of a phonogram the producer being the person or legal
entity who first fixes the sounds of a performance or other sounds;
and,
- in the case of broadcasts, the organization that transmits the
broadcast.
Work is the literary and/or artistic work offered under the terms of
this License including without limitation any production in the
literary, scientific and artistic domain, whatever may be the mode or
form of its expression including digital form, such as a book, pamphlet
and other writing; a lecture, address, sermon or other work of the same
nature; a dramatic or dramatico-musical work; a choreographic work or
entertainment in dumb show; a musical composition with or without words;
a cinematographic work to which are assimilated works expressed by a
process analogous to cinematography; a work of drawing, painting,
architecture, sculpture, engraving or lithography; a photographic work
to which are assimilated works expressed by a process analogous to
photography; a work of applied art; an illustration, map, plan, sketch
or three-dimensional work relative to geography, topography,
architecture or science; a performance; a broadcast; a phonogram; a
compilation of data to the extent it is protected as a copyrightable
work; or a work performed by a variety or circus performer to the extent
it is not otherwise considered a literary or artistic work.
You means an individual or entity exercising rights under this License
who has not previously violated the terms of this License with respect
to the Work, or who has received express permission from the Licensor to
exercise rights under this License despite a previous violation.
Publicly Perform means to perform public recitations of the Work and to
communicate to the public those public recitations, by any means or
process, including by wire or wireless means or public digital
performances; to make available to the public Works in such a way that
members of the public may access these Works from a place and at a place
individually chosen by them; to perform the Work to the public by any
means or process and the communication to the public of the performances
of the Work, including by public digital performance; to broadcast and
rebroadcast the Work by any means including signs, sounds or images.
Reproduce is to make copies of the Work by any means including without
limitation by sound or visual recordings and the right of fixation and
reproducing fixations of the Work, including storage of a protected
performance or phonogram in digital form or other electronic medium.
Software is any digital Work which, through use of a third-party piece
of Software or through the direct usage of itself on a computer system,
the memory of the computer is modified dynamically or semi-dynamically.
\"Software\", secondly, processes or interprets information.
Source Code is Any digital Work which, through use of a third-party
piece of Software or through the direct usage of itself on a computer
system, the memory of the computer is modified dynamically or
semi-dynamically. \"Software\", secondly, processes or interprets
information.
Surveilling is the use of the Work to either overtly or covertly observe
and record persons and or their activities.
A Network Service is the use of a piece of Software to interpret or
modify information that is subsequently and directly served to users
over the Internet.
To Discriminate is the use of a piece of Software to interpret or modify
information that is subsequently and directly served to users over the
Internet.
Hate Speech is Communication or any form of expression which is solely
for the purpose of expressing hatred for some group or advocating a form
of Discrimination between humans.
Coercion is leveraging of the threat of force or use of force to
intimidate a person in order to gain compliance, or to offer large
incentives which aim to entice a person to act against their will.
# Fair Dealing Rights
Nothing in this License is intended to reduce, limit, or restrict any
uses free from copyright or rights arising from limitations or
exceptions that are provided for in connection with the copyright
protection under copyright law or other applicable laws.
# License Grant
Subject to the terms and conditions of this License, Licensor hereby
grants You a worldwide, royalty-free, non-exclusive, perpetual (for the
duration of the applicable copyright) license to exercise the rights in
the Work as stated below:
To Reproduce the Work, to incorporate the Work into one or more
Collections, and to Reproduce the Work as incorporated in the
Collections
To create and Reproduce Adaptations provided that any such Adaptation,
including any translation in any medium, takes reasonable steps to
clearly label, demarcate or otherwise identify that changes were made to
the original Work. For example, a translation could be marked \"The
original work was translated from English to Spanish,\" or a
modification could indicate \"The original work has been modified.\"
To Distribute and Publicly Perform the Work including as incorporated in
Collections.
To Distribute and Publicly Perform Adaptations. The above rights may be
exercised in all media and formats whether now known or hereafter
devised. The above rights include the right to make such modifications
as are technically necessary to exercise the rights in other media and
formats. This License constitutes the entire agreement between the
parties with respect to the Work licensed here. There are no
understandings, agreements or representations with respect to the Work
not specified here. Licensor shall not be bound by any additional
provisions that may appear in any communication from You. This License
may not be modified without the mutual written agreement of the Licensor
and You. All rights not expressly granted by Licensor are hereby
reserved, including but not limited to the rights set forth in
Non-waivable Compulsory License Schemes, Waivable Compulsory License
Schemes, and Voluntary License Schemes in the restrictions.
# Restrictions
The license granted in the license grant above is expressly made subject
to and limited by the following restrictions:
You may Distribute or Publicly Perform the Work only under the terms of
this License. You must include a copy of, or the Uniform Resource
Identifier (URI) for, this License with every copy of the Work You
Distribute or Publicly Perform. You may not offer or impose any terms on
the Work that restrict the terms of this License or the ability of the
recipient of the Work to exercise the rights granted to that recipient
under the terms of the License. You may not sublicense the Work. You
must keep intact all notices that refer to this License and to the
disclaimer of warranties with every copy of the Work You Distribute or
Publicly Perform. When You Distribute or Publicly Perform the Work, You
may not impose any effective technological measures on the Work that
restrict the ability of a recipient of the Work from You to exercise the
rights granted to that recipient under the terms of the License. This
Section applies to the Work as incorporated in a Collection, but this
does not require the Collection apart from the Work itself to be made
subject to the terms of this License. If You create a Collection, upon
notice from any Licensor You must, to the extent practicable, remove
from the Collection any credit as requested. If You create an
Adaptation, upon notice from any Licensor You must, to the extent
practicable, remove from the Adaptation any credit as requested.
## Commercial Restrictions
You may not exercise any of the rights granted to You in the above
section in any manner that is primarily intended for or directed toward
commercial advantage or private monetary compensation unless you meet
the following requirements.
i. You are a worker-owned business or worker-owned collective.
ii. after tax, all financial gain, surplus, profits and benefits
produced by the business or collective are distributed among the
worker-owners unless a set amount is to be allocated towards
community projects as decided by a previously-established consensus
agreement between the worker-owners where all worker-owners agreed.
iii. You are not using such rights on behalf of a business other than
those specified in (i) or (ii) above, nor are using such rights as
a proxy on behalf of a business with the intent to circumvent the
aforementioned restrictions on such a business.
The exchange of the Work for other copyrighted works by means of digital
file-sharing or otherwise shall not be considered to be intended for or
directed toward commercial advantage or private monetary compensation,
provided there is no payment of any monetary compensation in connection
with the exchange of copyrighted works.
If the Work meets the definition of Software, You may exercise the
rights granted in the license grant only if You provide a copy of the
corresponding Source Code from which the Work was derived in digital
form, or You provide a URI for the corresponding Source Code of the
Work, to any recipients upon request.
If the Work is used as or for a Network Service, You may exercise the
rights granted in the license grant only if You provide a copy of the
corresponding Source Code from which the Work was derived in digital
form, or You provide a URI for the corresponding Source Code to the
Work, to any recipients of the data served or modified by the Web
Service.
Any use by a business that is privately owned and managed, and that
seeks to generate profit from the labor of employees paid by salary or
other wages, is not permitted under this license.
##
You may exercise the rights granted in the license grant for any
purposes only if:
i. You do not use the Work for the purpose of inflicting Bodily Harm on
human beings (subject to criminal prosecution or otherwise) outside
of providing medical aid or undergoing a voluntary procedure under
no form of Coercion.
ii. You do not use the Work for the purpose of Surveilling or tracking
individuals for financial gain.
iii. You do not use the Work in an Act of War.
iv. You do not use the Work for the purpose of supporting or profiting
from an Act of War.
v. You do not use the Work for the purpose of Incarceration.
vi. You do not use the Work for the purpose of extracting, processing,
or refining, oil, gas, or coal. Or to in any other way to
deliberately pollute the environment as a byproduct of manufacturing
or irresponsible disposal of hazardous materials.
vii. You do not use the Work for the purpose of expediting,
coordinating, or facilitating paid work undertaken by individuals
under the age of 12 years.
viii. You do not use the Work to either Discriminate or spread Hate
Speech on the basis of sex, sexual orientation, gender identity,
race, age, disability, color, national origin, religion, caste, or
lower economic status.
##
If You Distribute, or Publicly Perform the Work or any Adaptations or
Collections, You must, unless a request has been made by any Licensor to
remove credit from a Collection or Adaptation, keep intact all copyright
notices for the Work and provide, reasonable to the medium or means You
are utilizing:
i. the name of the Original Author (or pseudonym, if applicable) if
supplied, and/or if the Original Author and/or Licensor designate
another party or parties (e.g., a sponsor institute, publishing
entity, journal) for attribution (\"Attribution Parties\") in
Licensor\'s copyright notice, terms of service or by other
reasonable means, the name of such party or parties;
ii. the title of the Work if supplied;
iii. to the extent reasonably practicable, the URI, if any, that
Licensor to be associated with the Work, unless such URI does not
refer to the copyright notice or licensing information for the
Work; and,
iv. in the case of an Adaptation, a credit identifying the use of the
Work in the Adaptation (e.g., \"French translation of the Work by
Original Author,\" or \"Screenplay based on original Work by
Original Author\").
If any Licensor has sent notice to request removing credit, You must, to
the extent practicable, remove any credit as requested. The credit
required by this Section may be implemented in any reasonable manner;
provided, however, that in the case of an Adaptation or Collection, at a
minimum such credit will appear, if a credit for all contributing
authors of the Adaptation or Collection appears, then as part of these
credits and in a manner at least as prominent as the credits for the
other contributing authors. For the avoidance of doubt, You may only use
the credit required by this Section for the purpose of attribution in
the manner set out above and, by exercising Your rights under this
License, You may not implicitly or explicitly assert or imply any
connection with, sponsorship or endorsement by the Original Author,
Licensor and/or Attribution Parties, as appropriate, of You or Your use
of the Work, without the separate, express prior written permission of
the Original Author, Licensor and/or Attribution Parties.
Non-waivable Compulsory License Schemes. In those jurisdictions in which
the right to collect royalties through any statutory or compulsory
licensing scheme cannot be waived, the Licensor reserves the exclusive
right to collect such royalties for any exercise by You of the rights
granted under this License
Waivable Compulsory License Schemes. In those jurisdictions in which the
right to collect royalties through any statutory or compulsory licensing
scheme can be waived, the Licensor reserves the exclusive right to
collect such royalties for any exercise by You of the rights granted
under this License if Your exercise of such rights is for a purpose or
use which is otherwise than noncommercial as permitted under Commercial
Restrictions and otherwise waives the right to collect royalties through
any statutory or compulsory licensing scheme.
Voluntary License Schemes. The Licensor reserves the right to collect
royalties, whether individually or, in the event that the Licensor is a
member of a collecting society that administers voluntary licensing
schemes, via that society, from any exercise by You of the rights
granted under this License that is for a purpose or use which is
otherwise than noncommercial as permitted under the license grant.
Except as otherwise agreed in writing by the Licensor or as may be
otherwise permitted by applicable law, if You Reproduce, Distribute or
Publicly Perform the Work either by itself or as part of any Adaptations
or Collections, You must not distort, mutilate, modify or take other
derogatory action in relation to the Work which would be prejudicial to
the Original Author\'s honor or reputation. Licensor agrees that in
those jurisdictions (e.g. Japan), in which any exercise of the right
granted in the license grant of this License (the right to make
Adaptations) would be deemed to be a distortion, mutilation,
modification or other derogatory action prejudicial to the Original
Author\'s honor and reputation, the Licensor will waive or not assert,
as appropriate, this Section, to the fullest extent permitted by the
applicable national law, to enable You to reasonably exercise Your right
under the license grant of this License (right to make Adaptations) but
not otherwise.
Do not make any legal claim against anyone accusing the Work, with or
without changes, alone or with other works, of infringing any patent
claim.
# Representations Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
# Limitation on Liability
EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF
THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED
OF THE POSSIBILITY OF SUCH DAMAGES.
# Termination
This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this License.
Individuals or entities who have received Adaptations or Collections
from You under this License, however, will not have their licenses
terminated provided such individuals or entities remain in full
compliance with those licenses. The Sections on definitions, fair
dealing rights, representations, warranties, and disclaimer, limitation
on liability, termination, and revised license versions will survive any
termination of this License.
Subject to the above terms and conditions, the license granted here is
perpetual (for the duration of the applicable copyright in the Work).
Notwithstanding the above, Licensor reserves the right to release the
Work under different license terms or to stop distributing the Work at
any time; provided, however that any such election will not serve to
withdraw this License (or any other license that has been, or is
required to be, granted under the terms of this License), and this
License will continue in full force and effect unless terminated as
stated above.
# Revised License Versions
This License may receive future revisions in the original spirit of the
license intended to strengthen This License. Each version of This
License has an incrementing version number.
Unless otherwise specified like in the below subsection The Licensor has
only granted this current version of This License for The Work. In this
case future revisions do not apply.
The Licensor may specify that the latest available revision of This
License be used for The Work by either explicitly writing so or by
suffixing the License URI with a \"+\" symbol.
The Licensor may specify that The Work is also available under the terms
of This License\'s current revision as well as specific future
revisions. The Licensor may do this by writing it explicitly or
suffixing the License URI with any additional version numbers each
separated by a comma.
# Miscellaneous
Each time You Distribute or Publicly Perform the Work or a Collection,
the Licensor offers to the recipient a license to the Work on the same
terms and conditions as the license granted to You under this License.
Each time You Distribute or Publicly Perform an Adaptation, Licensor
offers to the recipient a license to the original Work on the same terms
and conditions as the license granted to You under this License.
If the Work is classified as Software, each time You Distribute or
Publicly Perform an Adaptation, Licensor offers to the recipient a copy
and/or URI of the corresponding Source Code on the same terms and
conditions as the license granted to You under this License.
If the Work is used as a Network Service, each time You Distribute or
Publicly Perform an Adaptation, or serve data derived from the Software,
the Licensor offers to any recipients of the data a copy and/or URI of
the corresponding Source Code on the same terms and conditions as the
license granted to You under this License.
If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this License, and without further action
by the parties to this agreement, such provision shall be reformed to
the minimum extent necessary to make such provision valid and
enforceable.
No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in writing
and signed by the party to be charged with such waiver or consent.
This License constitutes the entire agreement between the parties with
respect to the Work licensed here. There are no understandings,
agreements or representations with respect to the Work not specified
here. Licensor shall not be bound by any additional provisions that may
appear in any communication from You. This License may not be modified
without the mutual written agreement of the Licensor and You.
The rights granted under, and the subject matter referenced, in this
License were drafted utilizing the terminology of the Berne Convention
for the Protection of Literary and Artistic Works (as amended on
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and
the Universal Copyright Convention (as revised on July 24, 1971). These
rights and subject matter take effect in the relevant jurisdiction in
which the License terms are sought to be enforced according to the
corresponding provisions of the implementation of those treaty
provisions in the applicable national law. If the standard suite of
rights granted under applicable copyright law includes additional rights
not granted under this License, such additional rights are deemed to be
included in the License; this License is not intended to restrict the
license of any rights under applicable law.

View file

@ -1,52 +0,0 @@
# The Fuck Around and Find Out License, version 0.2
## Purpose
This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability, and ensuring this software is used
ethically.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Ethics
This software must be used for Good, not Evil, as
determined by the primary contributors to the software.
## Excuse
If anyone notifies you in writing that you have not
complied with [Ethics](#ethics), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***

View file

@ -1,4 +0,0 @@
# Licensing
This project is dual licensed under the [CNPL v7+](LICENSE-CNPL.md) and
the [FAFOL v0.2](LICENSE-FAFOL.md) at your leisure.

View file

@ -1,88 +0,0 @@
[![Published on crates.io](https://img.shields.io/crates/v/faery-ring?style=flat-square)](https://crates.io/crates/faery-ring)
# Faery Ring
*An ultra-lightweight js-free server-side webring implementation*
Webrings are a **way of building a community** especially popular with **amateur websites**. Here's how it works: Each member of the webring includes a **link to a "next" website** and a **"previous" website**, creating something like a "ring", hence the name. Anyone who finds their way onto one website can **organically navigate to other pages** in the ring.
Although they were first used to drive traffic in the era before search engines, many folks now see webrings as a way of **building cozy communities** on the web, or as a way to bring back the exciting feeling of the web as **a place to be explored**.
Where does Faery Ring come in? To make it easier to maintain webrings as they grow and change, many people **employ simple scripts** to **coordinate member pages**. Faery Ring lets you do this **without needing JavaScript**
## Faery Ring might be right for you if...
* You want to start a webring, but you or someone in your ring really doesn't like JavaScript
* One of the member pages on your webring can't use JavaScript because of hosting limitations
* You want to make it as easy as possible for new members to join your webring
* You have your own dedicated server or virtual private server (VPS)
## Faery Ring might not be right for you if...
Faery Ring is made for a pretty particular usecase, which might not necessarily fit your own. If you don't think that Faery Ring will work for you, that's okay! We encourage you to check out other projects, like maybe [onionring.js](https://garlic.garden/onionring/), a similar project that works using static javascript files. If you know any other webring projects that we should list here, submit an issue and we can add them too!
**You want more features provided by default**
Faery Ring only provides a "next" link and a "previous" link by default. Features like an index page, premade widgets, and script integration is something you'll have to bring yourself.
**You don't have a place to host dynamic web content**
Faery Ring needs a place to run it's webserver, and many ringmasters (that's the person who runs a webring) might only have the ability to serve static files
**Your server isn't running Linux**
There is no reason why Faery Ring can't run on other operating systems, but unfortunately I have no way of testing this, so I can't guarantee that it will work, and you may need to build the binary yourself. If that's okay with you, go right ahead though!
**You or a ring member is a non-cooperative corporation, cop, or planning on doing bad things**
Faery Rings is dual-licensed under the CNPL and FAFOL, which forbids the use of Faery Ring for a number of distasteful purposes. If you're worried that your purposes might be considered distasteful, first, ask yourself why you think that might be, and if you should be doing that. Then, [check out the CNPL website](https://thufie.lain.haus/NPL.html) for more details. If that's all a bit much for you, you're welcome to use the license under the [FAFOL (Fuck Around and Find Out License)](LICENSE-FAFOL.md) - a license very similar to the MIT license. The FAFOL also restricts unethical use, but as long as your use is generally good (not evil) you're in the clear.
## How do I use it??
Running Faery Ring is pretty easy. First, make a `.txt` file somewhere, and fill it with all of the sites in your ring, one per line. Leave out the protocol (https://) and a trailing slash, so that it looks something like this:
```
www.dragoness.space
emii.gay
garlic.garden/onionring
queerings.gay
getonflop.xyz
```
Now, run the Faery Ring binary (or docker image) with the `.txt` file you just created as the first argument, like this:
```bash
# Run from the binary
faery-ring /path/to/domains.txt
# Or run using Docker
docker run -v /path/to/domains.txt:/domains.txt -p 3243:3243 alch0emi/faery-ring
```
You can also use the `-p <port>` flag to tell faery-ring what port you want to bind on. If you don't, it'll pick port `3243`. Anyway, now you can point your webserver at Faery Ring! The config below is for Caddy, but any webserver that supports reverse proxies will work!
```Caddyfile
your.web.site {
reverse_proxy /next/* localhost:3243
reverse_proxy /prev/* localhost:3243
}
```
Now your webring members can add links on their page to `https://your.web.site/next/<their_domain>` `https://your.web.site/prev/<their_domain>` in order to build the ring. For example, whoever runs the page at www.dragoness.space would add a link to `https://your.web.site/next/www.dragoness.space` and `https://your.web.site/prev/www.dragoness.space`. garlic.garden/onionring cen either use `/next/garlic.garden` or `/next/garlic.garden/onionring`. If more than one site were hosted on `garlic.garden`, then the second form would be required.
## Downloads
- Linux binaries are available from the [releases page](https://fem.mint.lgbt/Emi/faery-ring/releases)
- A docker image is available on Docker Hub under `alch0emi/faery-ring:latest`
- If you have cargo installed on your system, faery ring can be installed with `cargo install faery-ring`
## Webrings that use faery-ring
- [technomancers.gay](https://technomancers.gay/)
- that's it for now!
Do you run a webring that uses faery ring? I'd love to know, and add you to the list if you'd like! 💜
## Maintence
Due to the relatively small scope and size of faery-ring, it doesn't require much maintence, and I'm not interested in adding very many features. I'll respond to the any issues and feature requests that are opened, and stay on top of any bugs, but for the most part faery-ring is [passively maintained](https://doc.rust-lang.org/cargo/reference/manifest.html#the-badges-section).

31
_cobalt.yml Normal file
View file

@ -0,0 +1,31 @@
ignore:
- other-sources
site:
title: Ember's Homepage
description: A trans femby's tiny corner of the internet
base_url: /
data:
socials:
- type: mastodon
url: https://www.librepunk.club/Emi
icon: mastodon
handle: "@emi@www.librepunk.club"
- type: matrix
url: https://matrix.to/#/@emi:the-apothecary.club
icon: element
handle: "@emi:the-apothecary.club"
- type: discord
url: https://discord.gg/
icon: discord
handle: Emi#6025
concotions:
- name: Kochab
desc: A customizable and powerful Gemini library
url: https://fem.mint.lgbt/Emi/kochab
- name: pronouns.today
desc: Pronouns generated daily
url: https://pronouns.today
- name: faery-ring
desc: A feather-weight JS-free webring
url: https://fem.mint.lgbt/Emi/faery-ring/

25
_includes/icon.html Normal file
View file

@ -0,0 +1,25 @@
{% comment %}
Displays an inline icon from an svg. The icon must be an asset in the :/assets/images/icon/ directory of the project. The icon should be viewboxed to be 24x24px, and will be inserted into the page and take on the color of the text/element it occupies. Keep track of the icon's filename in the repository. This value should be present in two places.
1. The icon's name should also be an id applied to the main SVG element of the icon.
2. The icon's name should be passed using the name argument of the include.
Neither of these values should include the .svg extension.
Alt text support is included.
Arguments:
size: The width and height the icon should have on the page
alt: Alt text to make available to screenreaders
name: See above.
{% endcomment %}
<svg
height="{{size}}"
width="{{size}}"
viewBox="0 0 24 24"
aria-labelledby="{{alt}}">
<title id="{{alt}}">{{alt}}</title>
<use xlink:href={{name | prepend: "/static/icon/" | prepend: site.base_url | append: ".svg#"| append: name}} />
</svg>

23
_includes/picker.html Normal file
View file

@ -0,0 +1,23 @@
<div class="picker">
<a href="https://technomancers.gay/prev/corviform.gay">
<img
class="picker-prev"
src="{{site.base_url}}/static/picker/arrow.svg"
height="50px"
alt="Previous" />
</a>
<a href="https://technomancers.gay/">
<img
src="{{site.base_url}}/static/picker/body.svg"
height="50px"
alt="technomancers.gay index page" />
</a>
<a href="https://technomancers.gay/next/corviform.gay">
<img
class="picker-next"
src="{{site.base_url}}/static/picker/arrow.svg"
height="50px"
alt="Next"
style="transform: scaleX(-1)" />
</a>
</div>

View file

@ -0,0 +1,52 @@
<section>
<p>
<b>Short Answer:</b>
Dark reader messes with the formatting of my site, and I don't like that
</p>
</section>
<section>
<p>
<b>Long Answer:</b>
Philosophically, extensions like dark reader view websites as sources of
information to be consumed, and understands the <i>most efficient</i> way of
consuming that information as the <i>best</i> way of consuming that
information.
</p>
<p>
I think this is true for a lot of websites, especially websites that are
primarily tools or repositories of raw information. For sites like these, I
encourage you to customize the fuck out of them, and browse however makes
you feel comfortable.
</p>
<p>
But I think there's another category of website — expressive websites.
Websites that are artistic first, and communicate just as much, if not more,
through design as through words and images.
</p>
<p>
That's the category that I hope my website falls into. And maybe you don't
like my design choices, or you think my site sucks, and that's okay. But
it's still my art and I'm proud of it, and I'd really appreciate it if you
experienced it as it is.
</p>
</section>
<section>
<p>
<b>Accessibility Concerns:</b>
Some people may use tools like dark reader in order to accommodate for a
disability. To this end, reader mode is available for every
content-containing page on this site. After enabling reader mode from your
browser's UI, you will be able to change the font size, styling, and color.
</p>
<p>
The one exception to this rule is the site's homepage, due to the fact that a
site-root may never use reader mode. To circumvent this, I have made
<a href="{{site.base_url}}/home">a mirror of the homepage</a> available.
</p>
<p>
If this is a poor accommodation of your disability, or you need another
service, please reach out to me at
<a href="mailto:ember@corviform.gay">ember@corviform.gay</a>, and I will do my best
to try to meet your need.
</p>
</section>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=525">
<title>{{ site.title }}</title>
<link rel="stylesheet" href="{{ site.base_url }}/static/common-style.css"/>
<link rel="stylesheet" href="{{ site.base_url }}/static/hyper-accessible-style.css"/>
</head>
<body>
{% assign sections=page.content | split: "<p>. . .</p>" %}
<main style="--section-count: {{sections | size}}">
{% for section in sections %}
<section style="--section-number: {{ forloop.index }}">
{{ section }}
</section>
{% endfor %}
</main>
</body>
</html>

123
_layouts/landing.liquid Normal file
View file

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=525">
<title>{{ site.title }}</title>
<link rel="stylesheet" href="{{ site.base_url }}/static/landing-style.css?1"/>
<link rel="stylesheet" href="{{ site.base_url }}/static/common-style.css"/>
<meta property="twitter:card" content="summary_large_image" />
<meta property="og:site_name" content="Ember's Homepage" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://corviform.gay" />
<meta property="og:image:url" content="https://corviform.gay/static/card.webp" />
<meta property="og:image:type" content="image/webp" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="400" />
<meta property="og:image:alt" content="Ember: vi/vir pronouns, a beautiful affront to order and reason; website: emii.gay/bio" />
</head>
<body>
<div>
<canvas id="canvas"></canvas>
<script type="module">
import init, {create, cycle, check_resize} from '{{ site.base_url }}/static/glow/glow.js';
async function run() {
await init();
let dd = await create();
async function resize() {
let canvas = document.getElementById("canvas");
if(
canvas.width != canvas.clientWidth ||
canvas.height != canvas.clientHeight
) {
canvas.width = canvas.clientWidth
canvas.height = canvas.clientHeight
check_resize(dd)
}
}
resize();
setInterval(cycle, 33, dd);
setInterval(resize, 500);
}
run()
</script>
</div>
<header>
<p>Welcome to</p>
<h1>{{ site.title }}</h1>
<p>{{ site.description }}</p>
</header>
{% assign sections=page.content | split: "<p>. . .</p>" %}
<main style="--section-count: {{sections | size}}">
<div id="cards">
<section class="card">
<h2> Ember </h2>
<p class="pronouns">
they/she/fae/he/sea/xe/ne
</p>
<div style="text-align: center">
<p class="contact">
<a class="email" href="mailto:emi@alchemi.dev">email</a>
<span>✨︎</span>
<a class="matrix" href="https://matrix.to/#/@emi:the-apothecary.club">matrix</a>
</p>
<p>~ local affront to god ~</p>
<p>~ hobbyist trespasser ~</p>
<p>~ hot as hell ~</p>
<p>~ enjoyer of that which is cringe ~</p>
</div>
</section>
<section class="card">
<h2> Whereabouts </h2>
<ul id="socials" style="list-style-type: none">
{% for social in site.data.socials %}
<li><a href="{{social.url}}">
{% include "icon.html" size: 16, name: social.icon, alt: social.type %}
{{social.handle}}
</a></li>
{% endfor %}
</ul>
</section>
<section class="card">
<h2> Concoctions </h2>
{% for concotion in site.data.concotions %}
<p><b><a href="{{concotion.url}}">{{concotion.name}}</a></b> — {{concotion.desc}}</p>
{% endfor %}
</section>
</div>
{% for section in sections %}
<section style="--section-number: {{ forloop.index }}">
<div class="section-content-wrapper">
{{ section }}
</div>
</section>
{% endfor %}
<footer>
<div class="flag" style="margin-top: 50px">
<!-- Queer Villian Pride Baby!! -->
<div style="background-color: #f09"></div>
<div style="background-color: #f93"></div>
<div style="background-color: #9c3"></div>
<div style="background-color: #639"></div>
</div>
</footer>
</main>
<div id="disable-darkreader-popup">
<h2>Please disable darkreader</h2>
<details id="darkreader-why">
<summary>why?</summary>
<a class="dark-a11y" href="{{site.base_url}}/darkreader-a11y">
View an accessible version of this blurb
</a>
{% include "why-darkreader.html" %}
</details>
</div>
</body>
</html>

8
darkreader-a11y.md Normal file
View file

@ -0,0 +1,8 @@
---
layout: hyper-accessible.liquid
permalink: /darkreader-a11y
title: Why I Dislike Darkreader
---
# Why I Dislike Darkreader
{% include "why-darkreader.html" %}

308
gender/index.html Normal file
View file

@ -0,0 +1,308 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ember's Homepage - Gender</title>
<link rel="stylesheet" href="../style.css"/>
</head>
<body>
<div id="wrap">
<header><h1>What is gender?</h1></header>
<main>
<section>
<aside>
<h3>&nbsp; Warning &nbsp;</h3>
<p>
This is an article I wrote a while ago as a once off thing for
personal reasons. I never really meant for it to be read publicly,
and I'm really just using it as a sort of filler page. It's pretty
unedited, and might be rambly and nonsensical. Read at your own risk.
</p>
<p>
If you don't want to keep reading, head
<a href="../">back to the homepage</a>
</p>
</aside>
<p>
This is the best effort of a trans enby to explain their experience
with gender to people who might not be familiar with nonbinary
identities at all.
</p>
<p>
It's also an exploratory piece, an effort to make sense of the vague
and abstract concept that is gender, and maybe understand it a little
better by writing about it.
</p>
<p>
And maybe it's also a philosophical piece, and an attempt to make
sense of the complicated world we live in, not just physically, but
mentally.
</p>
<p>
I hope that this will be useful to people who want to learn not just
how they can respect nonbinary identities, but who want to understand
them. I also hope that it will still be an interesting exploration of
gender for those who already are familiar with it, and maybe are
nonbinary.
</p>
<p>
This will discuss gender on a introspective level, and a lot of the
things attached to it, like specific biology, as well as gender roles
and misgendering. It's written to an audience of people who are not
nonbinary, and assumes that the reader is either a man or a woman and
sometimes addresses them as such.
</p>
<p>
</section>
<section>
<h2>Step 1: Gender is not physical.</h2>
<p>
A lot of people think that gender is about something physical. Most
often, they think it's about what's between a person's legs. This is
definitely part of it, but it's certainly far from the whole thing.
Think about it: If you need to refer to someone you've never met, you
probably just throw a glance their way and say, "do you see that woman
over there", without needing to go up to her and ask what's between
her legs. Similarly, it's not just about what you wear or how you
act. A boy can wear a skirt and act feminine, but that doesn't make
him not a boy.
</p>
<p>
There's something harder to pin down, and very personal about gender.
Calling someone a gender that they aren't is often seen as an insult
("what are you, a woman?!") in a way that isn't true about saying
someone has a hair color that they don't, or is a height that they
aren't. This would suggest that it's a very important part of
people's identity. But we've also worked out that it's not a
descriptor of anything physical. So what is it?
</p>
<p>
I'm not going to be able to give a perfect answer, because this is
something that philosophers still talk about today, and will for a
very long time to come. But to give a working definition, gender is a
feeling about how you relate to specific, very fuzzy categories of
people.
</p>
</section>
<section>
<h2>Step 2: Gender isn't black and white.</h2>
<p>
Most people in most societies are introduced to two genders at birth:
boy and girl, man and woman, male and female. A lot of us feel
comfortable with one of these labels. Often, our bodies line up with
the stereotypical bodies for that group, and that's what everyone
tells us we are. As we come to identify with them, they also mold our
behavior. Boys might pick up on boy-ish behavior, because that's how
they see themselves portrayed and that's how many of their peers act.
Same goes for girls. And so it was that most people in the world end
up feeling pretty content either as a boy, or a girl.
</p>
<p>
However, it's important to remember that nothing outside of math is
absolute, and nowhere is this more true than ambiguously defined
social structures. There's a million exceptions to this perfect
story, from people whose bodies don't perfectly line up with one of
the stereotypes, to people who accept the label but reject all the
"acceptable" norms for that group. Today we're just going to focus on
the people who were told that they were one thing when they were
young, but grew up to find that that's not what worked best for them.
Oftentimes, these people call themselves trans, or transgender.
We're going to zoom in even further though, to all the people who not
only found themselves unhappy with the label they were given when they
were young, but also felt that neither of these two labels fit their
experience all of the time. These people typically call themselves
nonbinary.
</p>
<p>
What does that mean? How does that work? Well, because gender is so
personal, it's a little bit different for every person. There's some
people who just don't feel a connection to either of the two groups
(agender). Some people feel like they match well with one group some
of the times, and but match differently at another (genderfluid).
Others might feel a connection to both (bigender). Others still might
feel like a whole 'nother thing altogether (xenogenders). The list
goes on and on.
</p>
</section>
<section>
<h2>Step 3: Gender can't be measured.</h2>
<p>
It's important to remember that there's not a certain number of
genders, or even a spectrum of genders. Gender isn't something that
fits nicely into mathematical models. It's jagged and chaotic. It's
not a metric or a measurement, it's a story about something so
personal it could never be expressed completely through language. We
come up with words and labels that can describe bits and pieces of our
gender, but we could never completely express it.
</p>
<p>
This is even true for you, and for everyone who only identifies with
the gender people told them they were when they were born. Ask
yourself, "how does it feel to be a man/woman?", "how do I know that's
what I am", and "what does it mean to be a man/woman to me?".
</p>
<p>
I'll give you a second.
</p>
<p>
No one is going to have the same answers to these questions, and it's
likely that, as you were trying to come up with an answer, you found a
feeling that you couldn't quite explain. You know that this is what
you are, but not because of anything about your body, or because of
how you act, but just, a feeling that it's right. That's your gender.
You could never put it in words, you could never compare it to someone
else's, you probably couldn't even say what it means, but that's okay.
You don't need to do any of those things, only know that it's yours,
and respect that others' will be different.
</p>
</section>
<section>
<h2>Step 4: Gender isn't something you have the answer to.</h2>
<p>
A lot of our first instincts with this is to try to come up with some
model or some other explanation that neatly wraps up gender into a
tidy package. You might even have one right now. Human brains really
don't like things that are as open and ambiguous as gender is.
</p>
<p>
But I'd like to ask you to take whatever model of gender you have and
really test it. How does it handle people whose bodies don't fit the
norm? How does it handle people who don't act like the gender you say
they are? How does it handle people who might medically change
themselves, either by hormones, or surgery, to feel more like a
different gender? Can it explain why people who, by all observable
measures appear to be one gender, nevertheless feel so much like
another gender that they go through complicated, difficult, scary, and
sometimes dangerous means to better express themselves? Does it
explain why we associate certain non-biological things with certain
genders? Does it explain why we care so deeply about gender that
almost everything in our lives are touched by it?
</p>
<p>
You get the idea. Don't get me wrong, I don't claim to have the
answer either. I've done a lot of talking in this document, and
there's still a million reasons why what I've discussed is a "good
enough" explanation at best. If you really want to chat about it
though, please reach out to me, I'm more than happy to talk about
gender any day.
</p>
</section>
<section>
<h2>Step 5: People are something you can respect.</h2>
<p>
I'd be elated if everyone who read this was convinced of the validity
of nonbinary identities, but a lot of people will just be confused,
and some more might even disagree completely. That's okay, and I
encourage you to find other resource people have made to help you
understand better. One person's perspective will never be enough to
gain a complete understanding. In fact, nothing will.
</p>
<p>
But, if I've failed to explain to you why nonbinary identities exist,
I'd like to at least ask this of you: Respect when people say they
are nonbinary.
</p>
<p>
If not because you believe them, then because you want to be nice. If
you go up to someone you know is nonbinary, and you actively reject
their gender, use the wrong name and pronouns, and tell them they
don't exist, I promise you this will hurt them at worst, and drive
them away from you at best. It won't "make them less confused", or
"remind them what they really are". But if you respect their name,
you ask for their pronouns and try your best to use them, you might
just make their day.
</p>
<p>
This isn't an effort to take away your free speech. Nothing will stop
you from misgendering nonbinary people. But it is an effort to
encourage you not to be rude, and an effort to keep the people you
care about in your life.
</p>
</section>
<section>
<h2>Addendum: What can you do to support nonbinary people?</h2>
<p>
In brief, here's what you can do:
</p>
<ul>
<li>
Use the name that people give you, and don't ask for their
previous name
</li>
<li>
Ask for people's pronouns, even when you don't think you're
talking to someone whose nonbinary
</li>
<li>
Try to use people's pronouns when they give them to you, although
it's okay if you genuinely slip up.
</li>
<li>
Watch for gendered language that you use, and try to use language
that the person prefers. It's okay to check what's best with them
if you're not sure.
</li>
<li>
If someone asks you to make a small change to how you treat them,
try to humor it, even if it doesn't make sense to you. We all
experience gender differently, and that's undoubtedly true for the
two of you.
</li>
</ul>
</section>
<section>
<h2>Addendem: What are pronouns, and how do I use them?</h2>
<p>
Pronouns are short words we use in place of other words. This is
anything like, "it's", or "their", or "me", or "you". A lot of the
time when people say pronouns, though, they're referring to
third-person pronouns for people, like "he", "she", or "him". A lot
of these carry heavy gendered connotations, so some people rather that
certain pronouns are used for them.
</p>
<p>
We often give pronouns two or three forms at a time, like
"he/him/his". If you're confused as to how to use a certain pronoun,
try starting with he/him/his, and then swapping it out for the pronoun
in the set that the person prefers.
</p>
<p>
For example, if someone asks for "they/them/theirs" pronouns, start
with a pronoun set you understand, then find out what the pronouns
correspond to. Where you might normally use him, use them, because
him in he/him/his corresponds to them in they/them/theirs. This is
only a crutch to get you started though, so try to become familiar
with the words in context.
</p>
<p>
People might also ask for pronoun sets you've never heard of, or have
never seen used for a singular human. A lot of the time, people do
this because they feel it better expresses their gender. This might
not make sense to you, but that's okay. Gender is uniquely
individual. Try your best to use the pronouns that they give you. If
you have difficulty, and you want to help make them feel more
comfortable, you can try practicing their pronouns by using their name
and pronouns together in your head. You can also get help with this
from websites like pronouns.is, which lists many different pronouns
that people use.
</p>
<p>
Most importantly, as long as you're trying your best and you respect
their gender, people will appreciate you, even if you slip up from
time to time. The fact that you've even read this far means that you
care, and people will appreciate that.
</p>
<span class="divider"></span>
<p>
Thank you for sticking with me through this. I appreciate it, and I
hope you feel a little more comfortable not just with the idea of
nonbinary genders, but with your own as well &lt;3
</p>
</section>
</main>
<nav>
<a href="..">Back to homepage</a>
</nav>
</div>
</body>
</html>

0
home-a11y.md Normal file
View file

61
home.md Normal file
View file

@ -0,0 +1,61 @@
---
layout: hyper-accessible.liquid
permalink: /home
---
# A trans femby's tiny corner of the internet
## Ember
**they/she/fae/he/sea/xe/ne**
[email](mailto:ember@corviform.gay) or [matrix](https://matrix.to/#/@emi:the-apothecary.club)
- local affront to god
- hobbyist trespasser
- hot as hell
- enjoyer of that which is cringe
## Whereabouts
- [@emi@www.librepunk.club](https://www.librepunk.club/Emi)
- [@emi:the-apothecary.club](https://matrix.to/#/@emi:the-apothecary.club)
- Emi#6025 on Discord
. . .
<p style="text-align: center">This site is part of the technomancers.gay webring.</p>
{% include "picker.html" %}
. . .
## Who are you???
I'm Ember, just a dumb gay crow who loves niche communities and the software &
circumstances that form them. I've eaten your gender, and it's mine now. I
use your pronouns.
I do a whole bunch of work scattered across whatever hobbies have struck my
interest, but common themes are:
* Queer advocacy!
* Non-standard chat platforms & social networks!
* toki pona, and sometimes other neat language projects!
I will also be very excited if you try to talk to me about
* Gender!
* Neat open source protocols
* Ethics & software
* Sociology or Philosophy (although I might not understand)
* Sustainability
* Cartoons
* Video essays
* The intersection of any of the above
but will probably stop paying attention if you try to talk to me about:
* Unsolicited linux opinions
* Why software A is better than software B
* Something I don't understand but that you don't care to explain

40
index.md Normal file
View file

@ -0,0 +1,40 @@
---
layout: landing.liquid
permalink: /
---
<p style="text-align: center">This site is part of the technomancers.gay webring.</p>
{% include "picker.html" %}
. . .
## Who are you???
I'm Ember, just a dumb gay crow who loves niche communities and the software &
circumstances that form them. I've eaten your gender, and it's mine now. I
use your pronouns.
I do a whole bunch of work scattered across whatever hobbies have struck my
interest, but common themes are:
* Queer advocacy!
* Non-standard chat platforms & social networks!
* toki pona, and sometimes other neat language projects!
I will also be very excited if you try to talk to me about
* Gender!
* Neat open source protocols
* Ethics & software
* Sociology or Philosophy (although I might not understand)
* Sustainability
* Cartoons
* Video essays
* The intersection of any of the above
but will probably stop paying attention if you try to talk to me about:
* Unsolicited linux opinions
* Why software A is better than software B
* Something I don't understand but that you don't care to explain

178
other-sources/card.svg Normal file
View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="800"
height="400"
viewBox="0 0 211.66666 105.83334"
version="1.1"
id="svg5"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
sodipodi:docname="card.svg"
inkscape:export-filename="/home/emi/Desktop/card.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<title
id="title249200">Emi's Card</title>
<sodipodi:namedview
id="namedview7"
pagecolor="#17071a"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="1"
inkscape:pagecheckerboard="false"
inkscape:document-units="px"
showgrid="false"
units="px"
inkscape:zoom="1.0469406"
inkscape:cx="217.29981"
inkscape:cy="234.49276"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="34"
inkscape:window-maximized="0"
inkscape:current-layer="layer1"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:snap-page="true"
inkscape:bbox-nodes="true"
borderlayer="true" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#17071a;fill-opacity:1;stroke-width:12.904;stroke-linecap:round;paint-order:markers stroke fill"
id="rect3706"
width="211.66667"
height="105.83334"
x="-1.7529301e-06"
y="0" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:151.19px;line-height:1.25;font-family:Avara;-inkscape-font-specification:'Avara Ultra-Bold';fill:#bb89eb;fill-opacity:0.0505445;stroke:none;stroke-width:1.44991"
x="-17.08452"
y="105.83334"
id="text146193"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:151.19px;font-family:VG5000;-inkscape-font-specification:VG5000;fill:#bb89eb;fill-opacity:0.0505445;stroke-width:1.44991"
x="-17.08452"
y="105.83334"
id="tspan146191">☾</tspan></text>
<g
id="g3682"
transform="matrix(1.0865297,0,0,1.0865297,8.0768822,12.394256)"
style="fill:#bb89eb;fill-opacity:1">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:49.6373px;line-height:1.25;font-family:sans-serif;fill:#bb89eb;fill-opacity:1;stroke:none;stroke-width:1.24093"
x="2.7770081"
y="45.399502"
id="text1640"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Avara;-inkscape-font-specification:Avara;fill:#bb89eb;fill-opacity:1;stroke-width:1.24093"
x="2.7770081"
y="45.399502"
id="tspan8072">Emi</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:22.7559px;line-height:1.25;font-family:sans-serif;fill:#bb89eb;fill-opacity:1;stroke:none;stroke-width:0.568892"
x="5.4397645"
y="69.97612"
id="text3012"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Avara;-inkscape-font-specification:Avara;fill:#bb89eb;fill-opacity:1;stroke-width:0.568892"
x="5.4397645"
y="69.97612"
id="tspan3010">Simpson</tspan></text>
</g>
<g
id="g249167"
transform="translate(0,-0.77660334)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:9.74347px;line-height:1.25;font-family:Avara;-inkscape-font-specification:'Avara Ultra-Bold';fill:#bb89eb;fill-opacity:1;stroke:none;stroke-width:0.243584"
x="169.97375"
y="17.995163"
id="text3012-3"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:VG5000;-inkscape-font-specification:VG5000;fill:#bb89eb;fill-opacity:1;stroke-width:0.243584"
x="169.97375"
y="17.995163"
id="tspan3010-6">an<tspan
style="letter-spacing:1.2065px"
id="tspan24347">y</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:avara;-inkscape-font-specification:avara;letter-spacing:0px"
id="tspan14941">/</tspan>all<tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46667px;font-family:Avara;-inkscape-font-specification:Avara"
id="tspan270127">*</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:9.74347px;line-height:0.9;font-family:Avara;-inkscape-font-specification:'Avara Ultra-Bold';text-align:end;text-anchor:end;fill:#bb89eb;fill-opacity:1;stroke:none;stroke-width:0.243584"
x="203.28494"
y="43.945324"
id="text40390"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:VG5000;-inkscape-font-specification:VG5000;text-align:end;text-anchor:end;fill:#bb89eb;fill-opacity:1;stroke-width:0.243584"
x="203.28494"
y="43.945324"
id="tspan43648"
dy="0"
dx="0">a beautiful</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:VG5000;-inkscape-font-specification:VG5000;text-align:end;text-anchor:end;fill:#bb89eb;fill-opacity:1;stroke-width:0.243584"
x="203.28494"
y="53.237083"
id="tspan47556">affront to</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:VG5000;-inkscape-font-specification:VG5000;text-align:end;text-anchor:end;fill:#bb89eb;fill-opacity:1;stroke-width:0.243584"
x="203.28494"
y="62.528847"
id="tspan47558">order and</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:VG5000;-inkscape-font-specification:VG5000;text-align:end;text-anchor:end;fill:#bb89eb;fill-opacity:1;stroke-width:0.243584"
x="203.28494"
y="71.82061"
id="tspan86501">reason</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:9.74347px;line-height:1.25;font-family:Avara;-inkscape-font-specification:'Avara Ultra-Bold';letter-spacing:0.457729px;fill:#bb89eb;fill-opacity:1;stroke:none;stroke-width:0.243584"
x="148.334"
y="96.406677"
id="text92375"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:VG5000;-inkscape-font-specification:VG5000;letter-spacing:0.457729px;fill:#bb89eb;fill-opacity:1;stroke-width:0.243584"
x="148.334"
y="96.406677"
id="tspan92373"><tspan
style="letter-spacing:0px"
id="tspan198505">emii.ga</tspan><tspan
style="letter-spacing:0.740833px"
id="tspan233229">y</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Avara;-inkscape-font-specification:Avara;letter-spacing:0.457729px"
id="tspan183523">/</tspan><tspan
style="letter-spacing:0px"
id="tspan226541">bio</tspan></tspan></text>
</g>
</g>
<metadata
id="metadata249198">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>Emi's Card</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

2
robots.txt Normal file
View file

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

View file

@ -1,98 +0,0 @@
pub mod server;
pub mod util;
use std::io::Read;
use std::process::exit;
use std::fs::File;
use std::io::ErrorKind;
use std::path::PathBuf;
fn main() {
let args: CommandlineArgs = argh::from_env();
//
// Step 1: Read the file
//
let mut config = match File::open(&args.domains) {
Ok(file) => file,
Err(e) => {
match e.kind() {
ErrorKind::NotFound => {
eprintln!("Domains file not found: {}", args.domains.display());
exit(1001);
},
ErrorKind::PermissionDenied => {
eprintln!(
"Permission denied to read domain file: {}",
args.domains.display()
);
exit(1002);
},
_ => {
eprintln!(
"Unexepected error opening domain file: {}",
args.domains.display()
);
exit(1000);
}
}
}
};
let mut read_into = String::with_capacity(1_000);
match config.read_to_string(&mut read_into) {
Ok(_) => {},
Err(e) => {
match e.kind() {
ErrorKind::BrokenPipe => {
eprintln!("Broken pipe (filesystem error) while reading {}", args.domains.display());
exit(1000);
},
ErrorKind::InvalidData => {
eprintln!(
"Domain file {} contains non-UTF-8 data. Are you sure this is a domains file?",
args.domains.display()
);
exit(1003);
}
_ => {
eprintln!(
"Unexepected error opening domain file: {}",
args.domains.display()
);
exit(1000);
}
}
}
};
let domains: Vec<_> = read_into.split('\n')
.filter(|s| !s.is_empty())
.collect();
let domains = match util::to_ascii_list(&domains) {
Ok(d) => d,
Err((line, e)) => {
let line = domains[line]; // unwrap safe guaranteed by to_ascii_list()
let character = line.chars().nth(e.valid_up_to()).unwrap(); // unwrap safe
eprintln!(
"The domains file can only contain ASCII characters, but it looks like the domain {line} has a non-ASCII character ({character})"
);
exit(1005);
}
};
//
// Step 2: Run the server
//
server::go(&domains, args.port);
}
#[derive(argh::FromArgs)]
/// Run a basic webring hub
struct CommandlineArgs {
/// a text file listing all domains in the ring, one per line
#[argh(positional)]
domains: PathBuf,
/// the port to bind to (default: 3243)
#[argh(option, short='p', default="3243")]
port: u16,
}

View file

@ -1,127 +0,0 @@
use std::borrow::Cow;
use std::io::Cursor;
use std::process::exit;
use ascii::AsciiStr;
use tiny_http::Header;
use tiny_http::Request;
use tiny_http::Response;
use tiny_http::Server;
use tiny_http::StatusCode;
/// Start the server on a given port
///
/// Runs the server in a single thread, bound to 0.0.0.0 on the provided port. Requests are
/// handled first-come, first-serve
pub fn go(domains: &[&AsciiStr], port: u16) {
let server = match Server::http(("0.0.0.0", port)) {
Ok(s) => s,
Err(e) => {
eprintln!("Couldn't create server on 0.0.0.0:{port}\n{e}");
exit(1004);
}
};
println!("Running on 0.0.0.0:{port}");
for req in server.incoming_requests() {
let route = Route::parse_request(&req);
let resp = route.render(domains);
if let Err(e) = req.respond(resp) {
eprintln!("WARN: {}", e);
}
}
}
/// An endpoint and the associated data
///
/// Each route represents a set of logic that should be used to respond to the request,
/// and the necessary information from the request in order to do so
pub enum Route<'a> {
PrevOrNext(&'a str, isize),
NotFound,
}
impl<'a> Route<'a> {
/// Given a request, parse out the appropriate Route for that request
pub fn parse_request(r: &'a Request) -> Self {
let (first_segment, referrer_domain) = r.url()
.trim_matches('/')
.split_once('/')
.unwrap_or((r.url(), "missing_referrer_domain"));
match first_segment {
"next" => {
Route::PrevOrNext(referrer_domain, 1)
},
"prev" => {
Route::PrevOrNext(referrer_domain, -1)
},
_ => Route::NotFound,
}
}
/// Generate a Response for this route
pub fn render<'b>(&self, domains: &[&'b AsciiStr]) -> Response<Cursor<Cow<'b, [u8]>>> {
match self {
Self::PrevOrNext(this_domain, offset) => {
// The name of the domain at the index of the index of shortest matching
// domain from the list for which the requested domain is a substring,
// offset by the offset.
let destination = domains.iter()
.enumerate()
.filter(|(_, d)| d.as_str().starts_with(this_domain))
.min_by_key(|(_, d)| d.len())
.map(|(i, _)| (i as isize + offset).rem_euclid(domains.len() as isize))
.map(|i| domains[i as usize]); // safe to unwrap: we just did a rem_euclid
if let Some(url) = destination {
let destination = format!(
"https://{}",
url
);
Response::new(
StatusCode(303),
vec![
Header::from_bytes(
b"Location".to_owned(),
destination.as_bytes(),
).unwrap(), // safe to unwrap: both of these are guaranteed ASCII
Header::from_bytes(
b"Cache-Control".to_owned(),
b"max-age=86400,stale-while-revalidate=172800,stale-if-error=3155760000".to_owned(),
).unwrap(),// safe to unwrap: both of these are guaranteed ASCII
],
Cursor::new(Cow::Borrowed(b"")),
Some(0),
None,
)
} else {
let bytes = format!(
"Misconfigured server. Website {} not found in webring.",
this_domain,
);
let blen = bytes.len();
Response::new(
StatusCode(400),
Vec::new(),
Cursor::new(Cow::Owned(bytes.into_bytes())),
Some(blen),
None,
)
}
},
Self::NotFound => {
Response::new(
StatusCode(404),
Vec::new(),
Cursor::new(Cow::Borrowed(b"Page not found")),
Some(14),
None,
)
}
}
}
}

View file

@ -1,22 +0,0 @@
//! Several small utility methods
use ascii::AsAsciiStrError;
use ascii::AsciiStr;
/// Convert a series of [`&str`][]s into [`AsciiStr`][]s
///
/// Usually used for the domain list. The result is either a [`Vec`][] containing all
/// mapped strings, or else a touple containing the index of the string with the first
/// error and the error that occurred.
pub fn to_ascii_list<'a>(strs: &'a [&'a str]) -> Result<Vec<&'a AsciiStr>, (usize, AsAsciiStrError)> {
strs.iter()
.map(AsciiStr::from_ascii)
.enumerate()
.try_fold(Vec::with_capacity(strs.len()), |mut v, (i, s)| {
match s {
Ok(s) => v.push(s),
Err(e) => return Err((i, e)),
};
Ok(v)
})
}

BIN
static/avara.woff2 (Stored with Git LFS) Normal file

Binary file not shown.

BIN
static/card.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

91
static/common-style.css Normal file
View file

@ -0,0 +1,91 @@
/* General Styling */
body {
font-family: Fengardo Neue;
font-size: 1.2rem;
}
h1, h2, h3, h4, h5, h6 {
font-family: Avara Bold;
color: #f10385;
}
/* Fonts */
@font-face {
font-family: Avara Bold;
src: url(/static/avara.woff2) format("woff2");
}
@font-face {
font-family: Fengardo Neue;
src: url(/static/fengardo-neue.woff) format("woff");
}
/* Flag Styling */
.flag {
display: grid;
grid-auto-flow: column;
width: 200px;
height: 10px;
border-radius: 3px;
overflow: hidden;
}
.flag > div {
height: 10px;
}
footer {
display: grid;
justify-items: center;
align-items: center;
padding-bottom: 50px;
}
/*******************
* Fuck Darkreader *
*******************/
html[data-darkreader-mode] body > :not(#disable-darkreader-popup) {
display: none;
}
html:not([data-darkreader-mode]) #disable-darkreader-popup {
display: none;
}
html[data-darkreader-mode] #disable-darkreader-popup {
display: grid;
}
#disable-darkreader-popup {
font-family: Avara Bold;
position:absolute;
min-height: 100%;
width: 100%;
justify-items: center;
align-content: center;
background: radial-gradient(rgba(0,0,0,0) 50%, rgba(0,0,0,0.5));
}
#darkreader-why > summary{
list-style-type: none;
color: #AA89FD;
}
#darkreader-why > summary:hover {
text-decoration: underline;
}
#darkreader-why[open] > summary{
display: none;
}
#darkreader-why[open] {
font-family: Fengardo Neue;
max-width: 500px;
margin: 0 40px;
}
#darkreader-why > section {
margin: 50px 0;
}
.dark-a11y {
background-color: black;
padding: 10px;
font-weight: bold;
color: white;
text-align: center;
display: block;
font-size: 1.1em;
}
.dark-a11y:not(:hover) {
text-decoration: none;
}

BIN
static/fengardo-neue.woff (Stored with Git LFS) Executable file

Binary file not shown.

BIN
static/glow/glow.js (Stored with Git LFS) Normal file

Binary file not shown.

BIN
static/glow/glow_bg.wasm (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -0,0 +1,22 @@
body {
display: grid;
justify-content: center;
align-content: center;
background-color: #181a1b;
color: white;
margin: 80px 0;
}
main {
max-width: 500px;
margin: 20px;
}
h1 {
color: #f10385;
}
section {
margin: 60px 0;
}
a {
color: #a692dd;
font-weight: bold;
}

1
static/icon/discord.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" id="discord"><path fill="none" d="M0 0h24v24H0z"/><path d="M10.076 11c.6 0 1.086.45 1.075 1 0 .55-.474 1-1.075 1C9.486 13 9 12.55 9 12s.475-1 1.076-1zm3.848 0c.601 0 1.076.45 1.076 1s-.475 1-1.076 1c-.59 0-1.075-.45-1.075-1s.474-1 1.075-1zm4.967-9C20.054 2 21 2.966 21 4.163V23l-2.211-1.995-1.245-1.176-1.317-1.25.546 1.943H5.109C3.946 20.522 3 19.556 3 18.359V4.163C3 2.966 3.946 2 5.109 2H18.89zm-3.97 13.713c2.273-.073 3.148-1.596 3.148-1.596 0-3.381-1.482-6.122-1.482-6.122-1.48-1.133-2.89-1.102-2.89-1.102l-.144.168c1.749.546 2.561 1.334 2.561 1.334a8.263 8.263 0 0 0-3.096-1.008 8.527 8.527 0 0 0-2.077.02c-.062 0-.114.011-.175.021-.36.032-1.235.168-2.335.662-.38.178-.607.305-.607.305s.854-.83 2.705-1.376l-.103-.126s-1.409-.031-2.89 1.103c0 0-1.481 2.74-1.481 6.121 0 0 .864 1.522 3.137 1.596 0 0 .38-.472.69-.871-1.307-.4-1.8-1.24-1.8-1.24s.102.074.287.179c.01.01.02.021.041.031.031.022.062.032.093.053.257.147.514.262.75.357.422.168.926.336 1.513.452a7.06 7.06 0 0 0 2.664.01 6.666 6.666 0 0 0 1.491-.451c.36-.137.761-.337 1.183-.62 0 0-.514.861-1.862 1.25.309.399.68.85.68.85z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

1
static/icon/element.svg Normal file
View file

@ -0,0 +1 @@
<svg fill="none" version="1.1" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" id="element"><path d="m100 0c-55.23 0-100 44.77-100 100 0 55.23 44.77 100 100 100 55.23 0 100-44.77 100-100 0-55.23-44.77-100-100-100zm-12.54 30.51c31.38 0 56.82 25.38 56.82 56.7 0 4.62-3.754 8.365-8.383 8.365-4.63 0-8.383-3.745-8.383-8.365 0-22.07-17.93-39.97-40.05-39.97-4.63 0-8.383-3.745-8.383-8.365s3.753-8.365 8.383-8.365zm-0.1328 25.59c4.63 0 8.383 3.745 8.383 8.365s-3.753 8.365-8.383 8.365c-22.12 0-40.05 17.89-40.05 39.97 0 4.619-3.753 8.363-8.383 8.363s-8.383-3.744-8.383-8.363c0-31.31 25.44-56.7 56.82-56.7zm73.78 22.75c4.63 0 8.383 3.745 8.383 8.365 0 31.31-25.44 56.7-56.81 56.7-4.63 0-8.383-3.745-8.383-8.365 0-4.619 3.753-8.365 8.383-8.365 22.12 0 40.05-17.89 40.05-39.97 0-4.62 3.753-8.365 8.383-8.365zm-96.87 25.59c4.63 0 8.383 3.746 8.383 8.365 0 22.07 17.93 39.97 40.05 39.97 4.63 0 8.383 3.744 8.383 8.363 0 4.621-3.753 8.365-8.383 8.365-31.38 0-56.82-25.38-56.82-56.7 0-4.619 3.753-8.365 8.383-8.365z"/></svg>

After

Width:  |  Height:  |  Size: 1,020 B

1
static/icon/mastodon.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" id="mastodon"><path fill="none" d="M0 0h24v24H0z"/><path d="M21.258 13.99c-.274 1.41-2.456 2.955-4.962 3.254-1.306.156-2.593.3-3.965.236-2.243-.103-4.014-.535-4.014-.535 0 .218.014.426.04.62.292 2.215 2.196 2.347 4 2.41 1.82.062 3.44-.45 3.44-.45l.076 1.646s-1.274.684-3.542.81c-1.25.068-2.803-.032-4.612-.51-3.923-1.039-4.598-5.22-4.701-9.464-.031-1.26-.012-2.447-.012-3.44 0-4.34 2.843-5.611 2.843-5.611 1.433-.658 3.892-.935 6.45-.956h.062c2.557.02 5.018.298 6.451.956 0 0 2.843 1.272 2.843 5.61 0 0 .036 3.201-.397 5.424zm-2.956-5.087c0-1.074-.273-1.927-.822-2.558-.567-.631-1.308-.955-2.229-.955-1.065 0-1.871.41-2.405 1.228l-.518.87-.519-.87C11.276 5.8 10.47 5.39 9.405 5.39c-.921 0-1.663.324-2.229.955-.549.631-.822 1.484-.822 2.558v5.253h2.081V9.057c0-1.075.452-1.62 1.357-1.62 1 0 1.501.647 1.501 1.927v2.79h2.07v-2.79c0-1.28.5-1.927 1.5-1.927.905 0 1.358.545 1.358 1.62v5.1h2.08V8.902z"/></svg>

After

Width:  |  Height:  |  Size: 987 B

192
static/landing-style.css Normal file
View file

@ -0,0 +1,192 @@
/* Basic styling */
body {
margin: 0;
color: white;
background-color: #141016;
}
/* Setting up the centered content */
main > section {
display: grid;
justify-content: center;
padding: 50px 0;
}
main > section > .section-content-wrapper {
max-width: 700px;
width: 80vw;
}
/* Styles for the header */
header p:first-of-type {
font-size: 2em;
}
h1 {
font-size: min(5em, 14.413vw);
margin-top: 15px;
margin-bottom: 15px;
}
header {
font-family: Avara Bold;
text-align: center;
height: 70vh;
display: grid;
align-content: center;
}
header p {
margin: 0 20px;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100vh + 200px);
z-index: -1;
}
/* Styles for the cards */
#cards {
display: grid;
grid-template-columns: repeat(3, max(20vw, 350px));
justify-content: space-evenly;
padding: 40px 0;
}
.card {
color: #280C3F;
padding: 0 10px;
}
.card h2 {
color: #280C3F;
text-align: center;
}
.card a {
color: inherit;
text-decoration: none;
}
.card:nth-child(1) {
background-color: #ff2f94;
grid-area: 1/1/3/2;
}
.card:nth-child(2) {
background-color: #ff8153;
grid-area: 2/2/4/3;
}
.card:nth-child(3) {
background-color: #ff964a;
grid-area: 3/3/5/4;
}
@media (max-width: 1160px) {
#cards {
grid-template-columns: repeat(2, 350px);
gap: 50px;
justify-content: center;
}
.card:nth-child(3) {
grid-area: 3/1/6/2;
}
}
@media (max-width: 800px) {
#cards {
grid-template-columns: 350px;
row-gap: 50px
}
#cards .card {
grid-area: initial;
}
}
/* Card Specific Details */
.card:nth-child(1) > h2 {
margin-bottom: 0px;
}
.pronouns {
font-family: Avara Bold;
text-align: center;
margin-top: 10px;
}
.contact {
font-size: 0.9rem;
display: grid;
grid-template-columns: 1fr 0fr 1fr;
}
.matrix:hover,.email:hover {
font-size: 0;
}
.email:hover:after {
font-size: 0.9rem;
content: "emi@alchemi.dev"
}
.matrix:hover:after {
font-size: 0.9rem;
content: "@emi:the-apothecary.club"
}
#socials li {
margin: 5px 0;
}
#socials a {
display: grid;
grid-template-columns: 0fr 1fr;
gap: 4px;
align-items: center;
justify-content: start;
}
#socials a:hover {
text-decoration: underline;
font-weight: bold;
}
#socials {
display: grid;
justify-content: center;
padding: 0;
margin: 0;
margin-bottom: 20px;
}
#socials p {
margin: 8px;
}
.card:nth-child(3) {
padding: 0 30px;
}
/* General Markdown Styling */
code {
background-color: rgba(200, 200, 200, 0.1);
padding: 2px 5px;
border-radius: 5px;
}
/* Widgets & Components */
.horizontal {
display: grid;
grid-auto-flow: column;
justify-content: space-between;
}
.picker {
display: grid;
grid-auto-flow: column;
justify-content: center;
}
.picker-prev:hover,
.picker-next:hover {
padding-right: 20px;
padding-left: 0;
}
.picker-next, .picker-prev {
transition: padding 50ms ease-out;
padding-right: 0;
padding-left: 20px;
}
/* Color Scheme */
h1, a {
color: #AA89FD;
}
h2 {
color: #F10385;
}
svg {
fill: currentColor;
}

8
static/picker/arrow.svg Normal file
View file

@ -0,0 +1,8 @@
<svg width="56.08" height="55" version="1.1" viewBox="0 0 14.838 14.552" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-8.4449 -112.65)">
<g transform="matrix(-1 0 0 1 164.02 0)" fill="#ff0379">
<path d="m140.74 112.65 4.2008 7.276-4.2008 7.276h4.2871l4.2008-7.276-4.2008-7.276z"/>
<path d="m147.09 112.65 4.2008 7.276-4.2008 7.276h4.2871l4.2008-7.276-4.2008-7.276z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 412 B

30
static/picker/body.svg Normal file
View file

@ -0,0 +1,30 @@
<svg width="409.71" height="55" version="1.1" viewBox="0 0 108.4 14.552" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-25.98 -112.65)">
<g transform="translate(-3.3496)">
<g fill="#ff0379">
<path transform="matrix(.20405 0 0 .20405 72.967 58.467)" d="m296.81 336.88h-41.175l-20.588-35.659 20.588-35.659h41.175l20.588 35.659z"/>
<path transform="matrix(-.20405 0 0 .20405 94.094 58.467)" d="m296.81 336.88h-41.175l-20.588-35.659 20.588-35.659h41.175l20.588 35.659z"/>
<rect x="33.53" y="112.65" width="100" height="14.552"/>
</g>
<g transform="scale(.98858 1.0116)" stroke-width=".26156" aria-label="technomancers.gay">
<path d="m40.391 115.18h-0.88931v4.0385c0.01046 1.1404 0.94162 2.0611 2.0925 2.082h0.87885v-0.89977h-0.87885c-0.6696-0.0105-1.2032-0.55451-1.2032-1.2136v-2.0506h1.674v-0.89978h-1.674z"/>
<path d="m45.162 116.23c-1.1718 0-2.0925 0.94163-2.1134 2.082v0.89978c0.02092 1.13 0.94162 2.0611 2.082 2.082h2.1448v-0.89977h-2.1448c-0.64868-0.0105-1.1718-0.54405-1.1823-1.1823h3.3271v-0.86839c0-1.1718-0.94162-2.1134-2.1134-2.1134zm0 0.88932c0.6696 0 1.2032 0.53358 1.2136 1.1927h-2.4273c0.01046-0.65914 0.54405-1.1927 1.2136-1.1927z"/>
<path d="m50.257 116.23c-1.0776 0.0628-1.9879 0.93117-2.0088 2.1134v0.86839c0.02092 1.1404 0.95209 2.082 2.1134 2.082 1.1613 0 2.1134-0.95208 2.1134-2.1134l-0.03139-0.0314h-0.837l-0.03139 0.0314c0 0.6696-0.54405 1.2136-1.2136 1.2136-0.68006 0-1.2346-0.54405-1.2346-1.2136v-0.837c0-0.68006 0.55451-1.2241 1.2346-1.2241 0.6696 0 1.2136 0.54405 1.2136 1.2241l0.03139 0.0314h0.837l0.03139-0.0314c0-1.1718-0.95209-2.1134-2.1134-2.1134z"/>
<path d="m54.348 113.73h-0.89978v7.5644h0.89978v-2.9504c0-0.68006 0.53359-1.2241 1.2136-1.2241 0.6696 0 1.2032 0.53358 1.2136 1.2032 0.01046 0.0105 0 0.0105 0 0.0209v2.9504h0.89978v-2.9713c-0.02092-1.1613-0.95209-2.0925-2.1134-2.0925-0.44989 0-0.86839 0.14648-1.2136 0.38712z"/>
<path d="m59.704 116.23h-0.89978v5.0638h0.89978v-2.9504c0-0.68006 0.54405-1.2136 1.2136-1.2136s1.2136 0.52312 1.2346 1.1823v2.9818h0.87885v-2.9818c-0.02093-1.1509-0.95209-2.082-2.1134-2.082-0.44989 0-0.86839 0.14648-1.2136 0.38712z"/>
<path d="m66.233 116.23c-1.1509 0-2.103 0.94163-2.103 2.1134v0.86839c0.01046 1.1509 0.96255 2.082 2.103 2.082 1.1613 0 2.1134-0.93116 2.1344-2.082v-0.86839c0-1.1718-0.96255-2.1134-2.1344-2.1134zm1.2346 2.9818c-0.02092 0.64867-0.56498 1.1823-1.2346 1.1823-0.65914 0-1.2136-0.54405-1.2136-1.2136v-0.837c0-0.68006 0.55451-1.2136 1.2136-1.2136 0.68006 0 1.2346 0.53359 1.2346 1.2136z"/>
<path d="m70.355 116.23h-0.88931v5.0638h0.88931v-2.9504c0-0.68006 0.55451-1.2241 1.2346-1.2241 0.6696 0 1.2136 0.54405 1.2136 1.2241v2.9504h0.89978v-2.9818c0.01046-0.65914 0.54405-1.1927 1.2136-1.1927s1.2032 0.53358 1.2241 1.1927v2.9818h0.88931v-2.9818c-0.01046-1.1509-0.95209-2.082-2.1134-2.082-0.68006 0-1.2764 0.32434-1.6635 0.81608-0.38711-0.49174-0.99394-0.81608-1.6635-0.81608-0.46035 0-0.87885 0.14648-1.2346 0.39758z"/>
<path d="m80.996 116.23h-2.4168v0.88932h2.4168c0.64868 0 1.1823 0.53358 1.1823 1.1927v0.60683h-0.28249c-0.20925-0.81608-0.96255-1.4438-1.8519-1.4438-1.0462 0-1.9146 0.86839-1.9146 1.8937 0 1.0672 0.86839 1.9251 1.9146 1.9251 0.89978 0 1.6531-0.62775 1.8519-1.4857h0.28249v1.4857h0.89978v-2.9818c0-1.1509-0.94162-2.082-2.082-2.082zm-0.96255 4.185c-0.54405 0-1.0149-0.46035-1.0149-1.0462 0-0.53358 0.47081-1.0044 1.0149-1.0044 0.57544 0 1.0358 0.47082 1.0358 1.0044 0 0.5859-0.46035 1.0462-1.0358 1.0462z"/>
<path d="m85.233 116.23h-0.89978v5.0638h0.89978v-2.9504c0-0.68006 0.54405-1.2136 1.2136-1.2136s1.2136 0.52312 1.2346 1.1823v2.9818h0.87885v-2.9818c-0.02093-1.1509-0.95209-2.082-2.1134-2.082-0.44989 0-0.86839 0.14648-1.2136 0.38712z"/>
<path d="m91.667 116.23c-1.0776 0.0628-1.9879 0.93117-2.0088 2.1134v0.86839c0.02093 1.1404 0.95209 2.082 2.1134 2.082s2.1134-0.95208 2.1134-2.1134l-0.03139-0.0314h-0.837l-0.03139 0.0314c0 0.6696-0.54405 1.2136-1.2136 1.2136-0.68006 0-1.2346-0.54405-1.2346-1.2136v-0.837c0-0.68006 0.55451-1.2241 1.2346-1.2241 0.6696 0 1.2136 0.54405 1.2136 1.2241l0.03139 0.0314h0.837l0.03139-0.0314c0-1.1718-0.95209-2.1134-2.1134-2.1134z"/>
<path d="m96.94 116.23c-1.1718 0-2.0925 0.94163-2.1134 2.082v0.89978c0.02093 1.13 0.94162 2.0611 2.082 2.082h2.1448v-0.89977h-2.1448c-0.64868-0.0105-1.1718-0.54405-1.1823-1.1823h3.3271v-0.86839c0-1.1718-0.94162-2.1134-2.1134-2.1134zm0 0.88932c0.6696 0 1.2032 0.53358 1.2136 1.1927h-2.4273c0.01046-0.65914 0.54405-1.1927 1.2136-1.1927z"/>
<path d="m101.05 116.23h-0.88932v5.0638h0.88932v-2.9504c0-0.6696 0.52312-1.2032 1.1927-1.2136h0.88931v-0.89978h-0.88931c-0.44989 0.0105-0.85792 0.14648-1.1927 0.38712z"/>
<path d="m107.95 116.23h-2.103c-1.1509 0-2.082 0.95209-2.082 2.1134v0.86839h3.2852c-0.0209 0.63821-0.54405 1.1718-1.2032 1.1823h-2.082v0.89977h2.082c1.1613-0.0209 2.103-0.95208 2.103-2.1134v-0.86839h-3.2957c0.0209-0.64867 0.54405-1.1823 1.1927-1.1823h2.103z"/>
<path d="m110.95 118.42c-0.78469 0-1.4334 0.64867-1.4334 1.4438s0.64867 1.4334 1.4334 1.4334c0.79515 0 1.4438-0.63821 1.4438-1.4334s-0.64868-1.4438-1.4438-1.4438zm0 0.89977c0.29295 0 0.54405 0.2511 0.54405 0.54405s-0.2511 0.53359-0.54405 0.53359-0.54405-0.24064-0.54405-0.53359 0.2511-0.54405 0.54405-0.54405z"/>
<path d="m116.06 116.22c-1.3392 0-2.1134 0.96255-2.1134 2.1134v0.86838c0.0209 1.1404 0.95209 2.082 2.1134 2.082 0.44988 0 0.87885-0.14647 1.2136-0.38711v0.40804c-0.0105 0.64867-0.55452 1.1823-1.2136 1.1823-0.65914 0-1.2346-0.51266-1.2346-1.245h-0.87885c0 1.1927 0.94163 2.1448 2.1134 2.1448s2.1134-0.95208 2.1134-2.1134v-5.0429h-0.89977v0.37665c-0.3348-0.24063-0.76377-0.38711-1.2136-0.38711zm0 0.88931c0.6696 0 1.2136 0.54405 1.2136 1.2241v0.837c0 0.6696-0.54405 1.2136-1.2136 1.2136-0.68007 0-1.2346-0.54405-1.2346-1.2136v-0.86839c0.0209-0.65914 0.56498-1.1927 1.2346-1.1927z"/>
<path d="m122.01 116.23h-2.4168v0.88932h2.4168c0.64868 0 1.1823 0.53358 1.1823 1.1927v0.60683h-0.28248c-0.20925-0.81608-0.96255-1.4438-1.8519-1.4438-1.0462 0-1.9146 0.86839-1.9146 1.8937 0 1.0672 0.86838 1.9251 1.9146 1.9251 0.89978 0 1.6531-0.62775 1.8519-1.4857h0.28248v1.4857h0.89978v-2.9818c0-1.1509-0.94163-2.082-2.082-2.082zm-0.96255 4.185c-0.54405 0-1.0149-0.46035-1.0149-1.0462 0-0.53358 0.47081-1.0044 1.0149-1.0044 0.57544 0 1.0358 0.47082 1.0358 1.0044 0 0.5859-0.46035 1.0462-1.0358 1.0462z"/>
<path d="m128.52 116.23-1.2555 3.0237-1.4438-3.0237h-1.0149l1.9983 4.1327-1.2555 3.0132h0.97301l2.9714-7.1459z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB