aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortdro <tdro@users.noreply.github.com>2022-04-03 03:19:40 -0400
committertdro <tdro@users.noreply.github.com>2022-04-03 03:19:40 -0400
commit6740a622d5c4afd0b007c8ff09511ba129f53e18 (patch)
tree7ca2a3147c7db7bb238aa65a65eab9feb2549467
downloadhugo-theme-opulene-6740a622d5c4afd0b007c8ff09511ba129f53e18.tar.gz
hugo-theme-opulene-6740a622d5c4afd0b007c8ff09511ba129f53e18.tar.bz2
hugo-theme-opulene-6740a622d5c4afd0b007c8ff09511ba129f53e18.zip
First commit
-rw-r--r--.gitignore2
-rw-r--r--LICENSE674
-rw-r--r--Makefile12
-rw-r--r--README.md7
-rw-r--r--config.json88
-rw-r--r--config.toml68
-rw-r--r--config.yaml68
-rw-r--r--content/archives/_index.md7
-rw-r--r--content/data/default.md239
-rw-r--r--content/data/first.md14
-rw-r--r--content/data/second.md14
-rw-r--r--content/data/third.md14
-rw-r--r--shell.nix27
-rw-r--r--static/css/default.css663
-rw-r--r--static/images/hugo.pngbin0 -> 54981 bytes
-rw-r--r--static/images/placeholder.pngbin0 -> 5751 bytes
-rw-r--r--themes/opulene/layouts/_default/_markup/render-codeblock-goat.html18
-rw-r--r--themes/opulene/layouts/_default/_markup/render-heading.html6
-rw-r--r--themes/opulene/layouts/_default/_markup/render-image.html16
-rw-r--r--themes/opulene/layouts/_default/_markup/render-link.html22
-rw-r--r--themes/opulene/layouts/_default/archive.html24
-rw-r--r--themes/opulene/layouts/_default/baseof.html18
-rw-r--r--themes/opulene/layouts/_default/index.json40
-rw-r--r--themes/opulene/layouts/_default/list.html9
-rw-r--r--themes/opulene/layouts/_default/rss.xml35
-rw-r--r--themes/opulene/layouts/_default/section.html17
-rw-r--r--themes/opulene/layouts/_default/single.html20
-rw-r--r--themes/opulene/layouts/_default/sitemap.xml22
-rw-r--r--themes/opulene/layouts/_default/subsection.html8
-rw-r--r--themes/opulene/layouts/_default/summary.html28
-rw-r--r--themes/opulene/layouts/_default/taxonomy.html60
-rw-r--r--themes/opulene/layouts/_default/taxonomy_archive.html28
-rw-r--r--themes/opulene/layouts/partials/archive-link.html2
-rw-r--r--themes/opulene/layouts/partials/article-image.html1
-rw-r--r--themes/opulene/layouts/partials/footer.html0
-rw-r--r--themes/opulene/layouts/partials/header.html31
-rw-r--r--themes/opulene/layouts/partials/navigator.html9
-rw-r--r--themes/opulene/layouts/partials/page-categories.html2
-rw-r--r--themes/opulene/layouts/partials/page-date.html5
-rw-r--r--themes/opulene/layouts/partials/page-meta.html3
-rw-r--r--themes/opulene/layouts/partials/page-status.html1
-rw-r--r--themes/opulene/layouts/partials/page-tags.html6
-rw-r--r--themes/opulene/layouts/partials/pagination.html154
-rw-r--r--themes/opulene/layouts/partials/read-time.html6
-rw-r--r--themes/opulene/layouts/partials/thumbnail-image.html29
-rw-r--r--themes/opulene/layouts/partials/title.html2
-rw-r--r--themes/opulene/layouts/shortcodes/audio.html18
-rw-r--r--themes/opulene/layouts/shortcodes/gist.html10
-rw-r--r--themes/opulene/layouts/shortcodes/imgur-image.html13
-rw-r--r--themes/opulene/layouts/shortcodes/imgur-video.html13
-rw-r--r--themes/opulene/layouts/shortcodes/reddit.html29
-rw-r--r--themes/opulene/layouts/shortcodes/tweet.html15
-rw-r--r--themes/opulene/layouts/shortcodes/video.html26
-rw-r--r--themes/opulene/layouts/shortcodes/vimeo.html12
-rw-r--r--themes/opulene/layouts/shortcodes/youtube.html14
55 files changed, 2669 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3eec6c0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+resources
+public
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2961c0d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+config:
+ yj -yj -i < config.yaml > config.json
+ yj -yt -i < config.yaml > config.toml
+
+hugo:
+ make config
+ rm -rf public
+ hugo
+ rm -f .hugo_build.lock
+
+server:
+ php -S 127.0.0.1:9294 -t public
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ed1eed0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# Hugo Theme Opulene
+
+This theme is a playground for `hugo` shortcode experimentation with semantic
+`HTML`.
+
+This theme is based on [Alexander Sanberg's](https://alexandersandberg.com/)
+Universalize `CSS`.
diff --git a/config.json b/config.json
new file mode 100644
index 0000000..622b432
--- /dev/null
+++ b/config.json
@@ -0,0 +1,88 @@
+{
+ "baseURL": null,
+ "theme": "opulene",
+ "title": "Opulene",
+ "languageCode": "en-us",
+ "author": {
+ "name": "Opulene"
+ },
+ "menu": {
+ "main": [
+ {
+ "name": "Home",
+ "url": "/",
+ "weight": 1
+ },
+ {
+ "name": "Data",
+ "url": "/data/",
+ "weight": 2
+ },
+ {
+ "name": "Tags",
+ "url": "/tags/",
+ "weight": 3
+ },
+ {
+ "name": "Archives",
+ "url": "/archives/",
+ "weight": 4
+ },
+ {
+ "name": "JSON Feed",
+ "url": "/index.json",
+ "weight": 5
+ },
+ {
+ "name": "RSS",
+ "url": "/rss.xml",
+ "weight": 6
+ }
+ ]
+ },
+ "paginate": 1,
+ "summaryLength": 20,
+ "pygmentsUseClassic": false,
+ "pygmentsCodeFences": true,
+ "pygmentsUseClasses": true,
+ "pygmentsCodeFencesGuessSyntax": true,
+ "taxonomies": {
+ "tag": "tags"
+ },
+ "outputFormats": {
+ "html": {
+ "baseName": "index",
+ "mediaType": "text/html"
+ },
+ "json": {
+ "baseName": "index",
+ "mediaType": "application/json"
+ },
+ "rss": {
+ "baseName": "rss",
+ "mediaType": "application/xml"
+ }
+ },
+ "outputs": {
+ "home": [
+ "html",
+ "rss",
+ "json"
+ ],
+ "section": [
+ "html",
+ "rss"
+ ],
+ "taxonomy": [
+ "html",
+ "rss"
+ ],
+ "term": [
+ "html",
+ "rss"
+ ],
+ "page": [
+ "html"
+ ]
+ }
+}
diff --git a/config.toml b/config.toml
new file mode 100644
index 0000000..e8ea31f
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,68 @@
+theme = "opulene"
+title = "Opulene"
+languageCode = "en-us"
+paginate = 1
+summaryLength = 20
+pygmentsUseClassic = false
+pygmentsCodeFences = true
+pygmentsUseClasses = true
+pygmentsCodeFencesGuessSyntax = true
+
+[author]
+ name = "Opulene"
+
+[menu]
+
+ [[menu.main]]
+ name = "Home"
+ url = "/"
+ weight = 1
+
+ [[menu.main]]
+ name = "Data"
+ url = "/data/"
+ weight = 2
+
+ [[menu.main]]
+ name = "Tags"
+ url = "/tags/"
+ weight = 3
+
+ [[menu.main]]
+ name = "Archives"
+ url = "/archives/"
+ weight = 4
+
+ [[menu.main]]
+ name = "JSON Feed"
+ url = "/index.json"
+ weight = 5
+
+ [[menu.main]]
+ name = "RSS"
+ url = "/rss.xml"
+ weight = 6
+
+[taxonomies]
+ tag = "tags"
+
+[outputFormats]
+
+ [outputFormats.html]
+ baseName = "index"
+ mediaType = "text/html"
+
+ [outputFormats.json]
+ baseName = "index"
+ mediaType = "application/json"
+
+ [outputFormats.rss]
+ baseName = "rss"
+ mediaType = "application/xml"
+
+[outputs]
+ home = ["html", "rss", "json"]
+ section = ["html", "rss"]
+ taxonomy = ["html", "rss"]
+ term = ["html", "rss"]
+ page = ["html"]
diff --git a/config.yaml b/config.yaml
new file mode 100644
index 0000000..c410746
--- /dev/null
+++ b/config.yaml
@@ -0,0 +1,68 @@
+---
+baseURL:
+theme: opulene
+title: Opulene
+languageCode: en-us
+
+author:
+ name: Opulene
+
+menu:
+ main:
+ - name: Home
+ url: /
+ weight: 1
+ - name: Data
+ url: /data/
+ weight: 2
+ - name: Tags
+ url: /tags/
+ weight: 3
+ - name: Archives
+ url: /archives/
+ weight: 4
+ - name: JSON Feed
+ url: /index.json
+ weight: 5
+ - name: RSS
+ url: /rss.xml
+ weight: 6
+
+paginate: 1
+summaryLength: 20
+
+pygmentsUseClassic: false
+pygmentsCodeFences: true
+pygmentsUseClasses: true
+pygmentsCodeFencesGuessSyntax: true
+
+taxonomies:
+ tag: tags
+
+outputFormats:
+ html:
+ baseName: index
+ mediaType: text/html
+ json:
+ baseName: index
+ mediaType: application/json
+ rss:
+ baseName: rss
+ mediaType: application/xml
+
+outputs:
+ home:
+ - html
+ - rss
+ - json
+ section:
+ - html
+ - rss
+ taxonomy:
+ - html
+ - rss
+ term:
+ - html
+ - rss
+ page:
+ - html
diff --git a/content/archives/_index.md b/content/archives/_index.md
new file mode 100644
index 0000000..39269e1
--- /dev/null
+++ b/content/archives/_index.md
@@ -0,0 +1,7 @@
+---
+title: "Data Archive"
+layout: archive
+hidden: true
+type: data
+summary: This page contains an archive of all data.
+---
diff --git a/content/data/default.md b/content/data/default.md
new file mode 100644
index 0000000..aa1f87c
--- /dev/null
+++ b/content/data/default.md
@@ -0,0 +1,239 @@
++++
+date = "2021-03-29T22:55:17+00:00"
+publishdate = "2022-03-22T04:45:51+00:00"
+title = "Default"
+slug = "default"
+author = "Opulene"
+tags = ["default", "opulene"]
+type = "data"
+summary = "This is a default summary."
+draft = ""
+syntax = "1"
+toc = ""
+updated = ""
++++
+
+## GoAT Diagram
+
+```goat
+ . .
+ / \ |
+ / \ .---+---.
+ + + | |
+ / \ / \ .-+-. .-+-.
+ / \ / \ | | | |
+ 1 2 3 4 1 2 3 4
+
+```
+
+
+
+## Audio
+
+### Default
+
+{{< audio >}}
+
+### Specified
+
+{{< audio "https://www.archive.org/download/pride_and_prejudice_librivox/prideandprejudice_01-03_austen_64kb.mp3"
+ "Pride and Prejudice by Jane Austen" "muted" >}}
+
+<!--
+{{< audio
+ src="https://www.archive.org/download/pride_and_prejudice_librivox/prideandprejudice_01-03_austen_64kb.mp3"
+ caption="Pride and Prejudice by Jane Austen"
+ controls="muted"
+>}}
+-->
+
+
+## Figure
+
+![Hugo's landing page](/images/hugo.png "
+ Hugo's [homepage](https://gohugo.io/)."
+)
+
+
+
+## Video
+
+### Default
+
+{{< video >}}
+{{< /video >}}
+
+### Specified
+
+{{< video
+ "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream"
+ "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg"
+ ""
+ "382"
+ "none"
+ "muted"
+>}}
+Elephants Dream
+{{< /video >}}
+
+<!--
+{{< video
+ source="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream"
+ poster="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg"
+ width=""
+ height="382"
+ preload="none"
+ controls="muted"
+>}}
+Elephants Dream
+{{< /video >}}
+-->
+
+
+
+## GitHub Gist
+
+### Default
+
+{{< gist >}}
+
+### Specified
+
+{{< gist spf13 7896402 >}}
+
+<!--
+{{< gist
+ user="laustdeleuran"
+ gist="1948627"
+ file="two.js"
+>}}
+-->
+
+
+
+## Twitter Embed
+
+### Default
+
+{{< tweet >}}
+
+### Specified
+
+{{< tweet GoHugoIO 1502708062477553667 >}}
+
+<!--
+{{< tweet
+ user="GoHugoIO"
+ status=1502708062477553667
+>}}
+-->
+
+
+
+## YouTube Embed
+
+### Default
+
+{{< youtube >}}
+
+### Specified
+
+{{< youtube w7Ft2ymGmfc "A New Hugo Site" >}}
+
+<!--
+{{< youtube
+ id=w7Ft2ymGmfc
+ title="A New Hugo Site"
+>}}
+-->
+
+
+
+## Vimeo Embed
+
+### Default
+
+{{< vimeo >}}
+
+### Specified
+
+{{< vimeo 146022717 "The Clock of The Long Now" >}}
+
+<!--
+{{< vimeo
+ id=146022717
+ title="The Clock of The Long Now"
+>}}
+-->
+
+
+
+## Imgur Image Embed
+
+
+### Default
+
+{{< imgur-image >}}
+
+### Specified
+
+{{< imgur-image V2YXdDO >}}
+
+<!--
+{{< imgur-image
+ id=V2YXdDO
+>}}
+-->
+
+
+
+## Imgur Video Embed
+
+
+### Default
+
+{{< imgur-video >}}
+
+### Specified
+
+{{< imgur-video rQIb4Vw >}}
+
+<!--
+{{< imgur-video
+ id=rQIb4Vw
+>}}
+-->
+
+
+
+## Reddit Comment Embed
+
+### Default
+
+{{< reddit >}}
+
+### Specified
+
+{{< reddit
+ "/linux/comments/6bo0kw/man_loses_will_to_live_during_gentoo_install/dhot8bi/"
+ 1
+ 0
+ dark
+ false
+ true
+ true
+ true
+>}}
+
+<!--
+{{< reddit
+ path="/linux/comments/6bo0kw/man_loses_will_to_live_during_gentoo_install/dhot8bi/"
+ depth=1
+ context=0
+ theme=dark
+ showtitle=false
+ showedits=true
+ showmedia=true
+ showmore=true
+>}}
+-->
diff --git a/content/data/first.md b/content/data/first.md
new file mode 100644
index 0000000..aeac070
--- /dev/null
+++ b/content/data/first.md
@@ -0,0 +1,14 @@
++++
+date = "2021-03-29T22:55:17+00:00"
+publishdate = "2022-03-22T04:45:51+00:00"
+title = "First"
+slug = "first"
+author = "Opulene"
+tags = ["default", "first", "opulene"]
+type = "data"
+summary = "This is a first summary."
+draft = ""
+syntax = "1"
+toc = ""
+updated = ""
++++
diff --git a/content/data/second.md b/content/data/second.md
new file mode 100644
index 0000000..4505b92
--- /dev/null
+++ b/content/data/second.md
@@ -0,0 +1,14 @@
++++
+date = "2021-03-29T22:55:17+00:00"
+publishdate = "2022-03-22T04:45:51+00:00"
+title = "Second"
+slug = "second"
+author = "Opulene"
+tags = ["default", "second", "opulene"]
+type = "data"
+summary = "This is a second summary."
+draft = ""
+syntax = "1"
+toc = ""
+updated = ""
++++
diff --git a/content/data/third.md b/content/data/third.md
new file mode 100644
index 0000000..85cfd05
--- /dev/null
+++ b/content/data/third.md
@@ -0,0 +1,14 @@
++++
+date = "2021-03-29T22:55:17+00:00"
+publishdate = "2022-03-22T04:45:51+00:00"
+title = "Third"
+slug = "third"
+author = "Opulene"
+tags = ["default", "third", "opulene"]
+type = "data"
+summary = "This is a third summary."
+draft = ""
+syntax = "1"
+toc = ""
+updated = ""
++++
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000..1115457
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,27 @@
+let
+
+ pkgs = import <nixpkgs> { };
+ name = "nix-shell.hugo-theme-opulene";
+
+ hugo = pkgs.callPackage (builtins.fetchurl {
+ url = "https://raw.githubusercontent.com/tdro/dotfiles/73b1c675285e67c623f2c4514602500c6f2cfab7/.config/nixpkgs/packages/hugo/default.nix";
+ sha256 = "07jk987zh7kxynjj21038j0qnd996bl949x1wm3g1iggjz0shgb4";
+ }) { };
+
+ mkShellPure = pkgs.callPackage (builtins.fetchurl {
+ url = "https://raw.githubusercontent.com/tdro/dotfiles/b710281b132056105709c03dda1899a6afc68a93/.config/nixpkgs/helpers/mkShellPure.nix";
+ sha256 = "1ciwifsx2hrp0ymm077zfb5q8ravrk545bda1q249y2spw9np4ms";
+ }) { };
+
+in mkShellPure {
+ packages = [
+ hugo
+ pkgs.busybox
+ pkgs.gnumake
+ pkgs.php
+ pkgs.yj
+ ];
+ shellHook = ''
+ export PS1='\h (${name}) \W \$ '
+ '';
+}
diff --git a/static/css/default.css b/static/css/default.css
new file mode 100644
index 0000000..1d5abc3
--- /dev/null
+++ b/static/css/default.css
@@ -0,0 +1,663 @@
+/*
+ universalize.css (v1.0.2) — by Alexander Sandberg (https://alexandersandberg.com)
+ ------------------------------------------------------------------------------
+
+ Based on Sanitize.css (https://github.com/csstools/sanitize.css).
+
+ (all) = Used for all browsers.
+ x lines = Applies to x lines down, including current line.
+
+ ------------------------------------------------------------------------------
+*/
+
+/*
+ Prevent padding and border from affecting width (all)
+*/
+*,
+::before,
+::after {
+ box-sizing: border-box;
+}
+
+/*
+ 1. Inherit text decoration (all)
+ 2. Inherit vertical alignment (all)
+ */
+::before,
+::after {
+ text-decoration: inherit; /* 1 */
+ vertical-align: inherit; /* 2 */
+}
+
+/*
+ 1. Use default UI font (all)
+ 2. Make font size more accessible to everyone (all)
+ 3. Make line height consistent (all)
+ 4. Prevent font size adjustment after orientation changes (IE, iOS)
+ 5. Prevent overflow from long words (all)
+*/
+html {
+ font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell,
+ Noto Sans, sans-serif; /* 1 */
+ font-size: 125%; /* 2 */
+ line-height: 1.6; /* 3 */
+ -webkit-text-size-adjust: 100%; /* 4 */
+ word-break: break-word; /* 5 */
+}
+
+/*
+ Whitespace between content and viewport edge (all)
+*/
+body {
+ padding: 1em;
+}
+
+/*
+ Remove inconsistent and unnecessary margins
+*/
+body, /* (all) */
+dl dl, /* (Chrome, Edge, IE, Safari) 5 lines */
+dl ol,
+dl ul,
+ol dl,
+ul dl,
+ol ol, /* (Edge 18-, IE) 4 lines */
+ol ul,
+ul ol,
+ul ul,
+button, /* (Safari) 3 lines */
+input,
+select,
+textarea {
+ /* (Firefox, Safari) */
+ margin: 0;
+}
+
+/*
+ 1. Show overflow (IE18-, IE)
+ 2. Correct sizing (Firefox)
+*/
+hr {
+ overflow: visible;
+ height: 0;
+}
+
+/*
+ Add correct display
+*/
+main, /* (IE11) */
+details {
+ /* (Edge 18-, IE) */
+ display: block;
+}
+
+summary {
+ /* (all) */
+ display: list-item;
+}
+
+/*
+ Remove style on navigation lists (all)
+*/
+nav ol,
+nav ul {
+ list-style: none;
+ padding: 0;
+}
+
+/*
+ 1. Use default monospace UI font (all)
+ 2. Correct font sizing (all)
+*/
+pre,
+code,
+kbd,
+samp {
+ font-family:
+ /* macOS 10.10+ */ "Menlo", /* Windows 6+ */ "Consolas",
+ /* Android 4+ */ "Roboto Mono", /* Ubuntu 10.10+ */ "Ubuntu Monospace",
+ /* KDE Plasma 5+ */ "Noto Mono", /* KDE Plasma 4+ */ "Oxygen Mono",
+ /* Linux/OpenOffice fallback */ "Liberation Mono", /* fallback */ monospace,
+ /* macOS emoji */ "Apple Color Emoji", /* Windows emoji */ "Segoe UI Emoji",
+ /* Windows emoji */ "Segoe UI Symbol", /* Linux emoji */ "Noto Color Emoji"; /* 1 */
+
+ font-size: 1em; /* 2 */
+}
+
+/*
+ 1. Change cursor for <abbr> elements (all)
+ 2. Add correct text decoration (Edge 18-, IE, Safari)
+*/
+abbr[title] {
+ cursor: help; /* 1 */
+ text-decoration: underline; /* 2 */
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted; /* 2 */
+}
+
+/*
+ Add correct font weight (Chrome, Edge, Safari)
+*/
+b,
+strong {
+ font-weight: bolder;
+}
+
+/*
+ Add correct font size (all)
+*/
+small {
+ font-size: 80%;
+}
+
+/*
+ Change alignment on media elements (all)
+*/
+audio,
+canvas,
+iframe,
+img,
+svg,
+video {
+ vertical-align: middle;
+}
+
+video,
+iframe,
+audio {
+ width: 100%;
+}
+
+audio {
+ margin: 0.75rem 0;
+}
+
+/*
+ Remove border on iframes (all)
+*/
+iframe {
+ border-style: none;
+}
+
+/*
+ Change fill color to match text (all)
+*/
+svg:not([fill]) {
+ fill: currentColor;
+}
+
+/*
+ Hide overflow (IE11)
+*/
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/*
+ Show overflow (Edge 18-, IE)
+*/
+button,
+input {
+ overflow: visible;
+}
+
+/*
+ Remove inheritance of text transform (Edge 18-, Firefox, IE)
+*/
+button,
+select {
+ text-transform: none;
+}
+
+/*
+ Correct inability to style buttons (iOS, Safari)
+*/
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+/*
+ 1. Fix inconsistent appearance (all)
+ 2. Correct padding (Firefox)
+*/
+fieldset {
+ border: 1px solid #666; /* 1 */
+ padding: 0.35em 0.75em 0.625em; /* 2 */
+}
+
+/*
+ 1. Correct color inheritance from <fieldset> (IE)
+ 2. Correct text wrapping (Edge 18-, IE)
+*/
+legend {
+ color: inherit; /* 1 */
+ display: table; /* 2 */
+ max-width: 100%; /* 2 */
+ white-space: normal; /* 2 */
+}
+
+/*
+ 1. Add correct display (Edge 18-, IE)
+ 2. Add correct vertical alignment (Chrome, Edge, Firefox)
+*/
+progress {
+ display: inline-block; /* 1 */
+ vertical-align: baseline; /* 2 */
+}
+
+/*
+ 1. Remove default vertical scrollbar (IE)
+ 2. Change resize direction (all)
+*/
+textarea {
+ overflow: auto; /* 1 */
+ resize: vertical; /* 2 */
+}
+
+/*
+ 1. Correct outline style (Safari)
+ 2. Correct odd appearance (Chrome, Edge, Safari)
+*/
+[type="search"] {
+ outline-offset: -2px; /* 1 */
+ -webkit-appearance: textfield; /* 2 */
+}
+
+/*
+ Correct cursor style of increment and decrement buttons (Safari)
+*/
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/*
+ Correct text style (Chrome, Edge, Safari)
+*/
+::-webkit-input-placeholder {
+ color: inherit;
+ opacity: 0.54;
+}
+
+/*
+ Remove inner padding (Chrome, Edge, Safari on macOS)
+*/
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/*
+ 1. Inherit font properties (Safari)
+ 2. Correct inability to style upload buttons (iOS, Safari)
+*/
+::-webkit-file-upload-button {
+ font: inherit; /* 1 */
+ -webkit-appearance: button; /* 2 */
+}
+
+/*
+ Remove inner border and padding of focus outlines (Firefox)
+*/
+::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/*
+ Restore focus outline style (Firefox)
+*/
+:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/*
+ Remove :invalid styles (Firefox)
+*/
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+/*
+ Change cursor on busy elements (all)
+*/
+[aria-busy="true"] {
+ cursor: progress;
+}
+
+/*
+ Change cursor on control elements (all)
+*/
+[aria-controls] {
+ cursor: pointer;
+}
+
+/*
+ Change cursor on disabled, non-editable, or inoperable elements (all)
+*/
+[aria-disabled="true"],
+[disabled] {
+ cursor: not-allowed;
+}
+
+/*
+ Change display on visually hidden accessible elements (all)
+*/
+[aria-hidden="false"][hidden] {
+ display: inline;
+ display: initial;
+}
+
+[aria-hidden="false"][hidden]:not(:focus) {
+ clip: rect(0, 0, 0, 0);
+ position: absolute;
+}
+
+/*
+ Print out URLs after links (all)
+*/
+@media print {
+ a[href^="http"]::after {
+ content: " (" attr(href) ")";
+ }
+}
+/* ----- Variables ----- */
+
+/* Light mode default, dark mode if recognized as preferred */
+:root {
+ --background-main: #fefefe;
+ --background-element: #eee;
+ --background-inverted: #282a36;
+ --text-main: #1f1f1f;
+ --text-alt: #333;
+ --text-inverted: #fefefe;
+ --border-element: #282a36;
+ --theme: #7a283a;
+ --theme-light: hsl(0, 25%, 65%);
+ --theme-dark: hsl(0, 25%, 45%);
+}
+
+/* @media (prefers-color-scheme: dark) {
+ :root {
+ --background-main: #282a36;
+ --text-main: #fefefe;
+ }
+} */
+/* ----- Base ----- */
+
+body {
+ margin: auto;
+ max-width: 36rem;
+ min-height: 100%;
+ overflow-x: hidden;
+}
+/* ----- Typography ----- */
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin: 3.2rem 0 0.8em;
+}
+
+/*
+ Heading sizes based on a modular scale of 1.25 (all)
+*/
+h1 {
+ font-size: 2.441rem;
+ line-height: 1.1;
+}
+
+h2 {
+ font-size: 1.953rem;
+ line-height: 1.15;
+}
+
+h3 {
+ font-size: 1.563rem;
+ line-height: 1.2;
+}
+
+h4 {
+ font-size: 1.25rem;
+ line-height: 1.3;
+}
+
+h5 {
+ font-size: 1rem;
+ line-height: 1.4;
+}
+
+h6 {
+ font-size: 1rem;
+ line-height: 1.4;
+
+ /* differentiate from h5, somehow. color or style? */
+}
+
+p,
+ul,
+ol,
+figure {
+ margin: 0.6rem 0 1.2rem;
+}
+
+figure {
+ text-align: center;
+}
+
+figcaption {
+ text-align: center;
+ margin: 0.5rem 0;
+}
+
+/*
+ Subtitles
+ - Change to header h* + span instead?
+ - Add support for taglines (small title above main) as well? Needs <header>:
+ header > span:first-child
+*/
+h1 span,
+h2 span,
+h3 span,
+h4 span,
+h5 span,
+h6 span {
+ display: block;
+ font-size: 1em;
+ font-style: italic;
+ font-weight: normal;
+ line-height: 1.3;
+ margin-top: 0.3em;
+}
+
+h1 span {
+ font-size: 0.6em;
+}
+
+h2 span {
+ font-size: 0.7em;
+}
+
+h3 span {
+ font-size: 0.8em;
+}
+
+h4 span {
+ font-size: 0.9em;
+}
+
+small {
+ font-size: 1em;
+ opacity: 0.8; /* or some other way of differentiating it from body text */
+}
+
+mark {
+ background: pink; /* change to proper color, based on theme */
+}
+
+/*
+ Define a custom tab-size in browsers that support it.
+*/
+pre {
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+}
+
+/*
+ Long underlined text can be hard to read for dyslexics. Replace with bold.
+*/
+ins {
+ text-decoration: none;
+ font-weight: bolder;
+}
+
+blockquote {
+ border-left: 0.3rem solid #7a283a;
+ border-left: 0.3rem solid var(--theme);
+ margin: 0.6rem 0 1.2rem 0;
+ padding-left: 2rem;
+}
+
+blockquote p {
+ font-size: 1.2em;
+ font-style: italic;
+}
+
+img {
+ height: auto;
+ max-width: 100%;
+}
+
+/* ----- Layout ----- */
+
+body {
+ background: #fefefe;
+ background: var(--background-main);
+ color: #1f1f1f;
+ color: var(--text-main);
+}
+
+a {
+ color: #7a283a;
+ color: var(--theme);
+ text-decoration: underline;
+}
+
+a:hover {
+ color: hsl(0, 25%, 65%);
+ color: var(--theme-light);
+}
+
+a:active {
+ color: hsl(0, 25%, 45%);
+ color: var(--theme-dark);
+}
+
+:focus {
+ outline: 3px solid hsl(0, 25%, 65%);
+ outline: 3px solid var(--theme-light);
+ outline-offset: 3px;
+}
+
+::-moz-selection {
+ background: hsl(0, 25%, 65%);
+ background: var(--theme-light);
+ color: #fefefe;
+ color: var(--text-inverted);
+}
+
+::selection {
+ background: hsl(0, 25%, 65%);
+ background: var(--theme-light);
+ color: #fefefe;
+ color: var(--text-inverted);
+}
+
+input {
+ background: #eee;
+ background: var(--background-element);
+ padding: 0.5rem 0.65rem;
+ border-radius: 0.5rem;
+ border: 2px solid #282a36;
+ border: 2px solid var(--border-element);
+ font-size: 1rem;
+}
+
+mark {
+ background: pink; /* change to proper color, based on theme */
+ padding: 0.1em 0.15em;
+}
+
+kbd, /* different style for kbd? */
+code {
+ background: #eee;
+ padding: 0.1em 0.25em;
+ border-radius: 0.2rem;
+ -webkit-box-decoration-break: clone;
+ box-decoration-break: clone;
+}
+
+kbd > kbd {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+pre {
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+}
+
+pre code {
+ display: block;
+ padding: 0.3em 0.7em;
+ word-break: normal;
+ overflow-x: auto;
+}
+/* ----- Forms ----- */
+/* ----- Misc ----- */
+
+[tabindex="-1"]:focus {
+ outline: none;
+}
+
+[hidden] {
+ display: none;
+}
+
+[aria-disabled],
+[disabled] {
+ cursor: not-allowed !important;
+ pointer-events: none !important;
+}
+
+/*
+ Style anchor links only
+*/
+a[href^="#"]::after {
+ content: "";
+}
+
+/*
+ Skip link
+*/
+body > a:first-child {
+ background: #7a283a;
+ background: var(--theme);
+ border-radius: 0.2rem;
+ color: #fefefe;
+ color: var(--text-inverted);
+ padding: 0.3em 0.5em;
+ position: absolute;
+ top: -10rem;
+}
+
+body > a:first-child:focus {
+ top: 1rem;
+}
diff --git a/static/images/hugo.png b/static/images/hugo.png
new file mode 100644
index 0000000..656d8aa
--- /dev/null
+++ b/static/images/hugo.png
Binary files differ
diff --git a/static/images/placeholder.png b/static/images/placeholder.png
new file mode 100644
index 0000000..f25801e
--- /dev/null
+++ b/static/images/placeholder.png
Binary files differ
diff --git a/themes/opulene/layouts/_default/_markup/render-codeblock-goat.html b/themes/opulene/layouts/_default/_markup/render-codeblock-goat.html
new file mode 100644
index 0000000..e48a3b2
--- /dev/null
+++ b/themes/opulene/layouts/_default/_markup/render-codeblock-goat.html
@@ -0,0 +1,18 @@
+{{ $width := .Attributes.width }}
+{{ $height := .Attributes.height }}
+{{ $caption := .Attributes.caption }}
+<diagram-container>
+ {{ with diagrams.Goat .Inner }}
+ <svg font-family="'Fira Code', 'Lucida Console', 'Andale Mono', monospace"
+ xmlns="http://www.w3.org/2000/svg"
+ {{ if or $width $height }}
+ {{ with $width }}width="{{ . }}"{{ end }}
+ {{ with $height }}height="{{ . }}"{{ end }}
+ {{ else }}
+ viewBox="0 0 {{ .Width }} {{ .Height }}"
+ {{ end }}>
+ {{ .Inner }}
+ </svg>
+ {{ end }}
+ <figcaption>{{ $caption }}</figcaption>
+</diagram-container>
diff --git a/themes/opulene/layouts/_default/_markup/render-heading.html b/themes/opulene/layouts/_default/_markup/render-heading.html
new file mode 100644
index 0000000..37eddb2
--- /dev/null
+++ b/themes/opulene/layouts/_default/_markup/render-heading.html
@@ -0,0 +1,6 @@
+<h{{ .Level }} id="{{ .Anchor | safeURL }}">
+ <a
+ title="{{ .Text | safeHTML }}"
+ href="#{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}
+ </a>
+</h{{ .Level }}>
diff --git a/themes/opulene/layouts/_default/_markup/render-image.html b/themes/opulene/layouts/_default/_markup/render-image.html
new file mode 100644
index 0000000..ae5d53e
--- /dev/null
+++ b/themes/opulene/layouts/_default/_markup/render-image.html
@@ -0,0 +1,16 @@
+{{ $imageFile := print "public" (.Destination | safeURL) }}
+{{ $image := imageConfig $imageFile }}
+{{- /* This comment removes trailing newlines. */ -}}
+<figure>
+ <a href="{{ .Destination | safeURL }}">
+ <img
+ src="{{ .Destination | safeURL }}"
+ alt="{{ $.Text }}"
+ title="{{ $.Text | htmlUnescape | safeHTML }}"
+ width="{{ $image.Width }}"
+ height="{{ $image.Height }}"
+ />
+ </a>
+ <figcaption>{{ $.Title | markdownify }}</figcaption>
+</figure>
+{{- /* This comment removes trailing newlines. */ -}}
diff --git a/themes/opulene/layouts/_default/_markup/render-link.html b/themes/opulene/layouts/_default/_markup/render-link.html
new file mode 100644
index 0000000..b6574a2
--- /dev/null
+++ b/themes/opulene/layouts/_default/_markup/render-link.html
@@ -0,0 +1,22 @@
+{{- $link := .Destination -}}
+{{ $isRemote := strings.HasPrefix $link "http" }}
+{{- if not $isRemote -}}
+{{ $url := urls.Parse .Destination }}
+{{- if $url.Path -}}
+{{ $fragment := "" }}
+{{- with $url.Fragment }}{{ $fragment = printf "#%s" . }}{{ end -}}
+{{- with .Page.GetPage $url.Path }}{{ $link = printf "%s%s" .RelPermalink $fragment }}{{ end }}{{ end -}}
+{{- end -}}
+<a
+ title="{{ $link | safeURL }}"
+ rel="noopener"
+ href="{{ $link | safeURL }}"
+ {{ with .Title }}
+ title="{{ . }}"
+ {{ end }}
+ {{- if $isRemote -}}
+ target="_blank"
+ {{ end }}>
+ {{- .Text | safeHTML -}}
+</a>
+{{- /* This comment removes trailing newlines. */ -}}
diff --git a/themes/opulene/layouts/_default/archive.html b/themes/opulene/layouts/_default/archive.html
new file mode 100644
index 0000000..f0f0661
--- /dev/null
+++ b/themes/opulene/layouts/_default/archive.html
@@ -0,0 +1,24 @@
+{{ define "main" }}
+<section >
+{{ $type := .Type }}
+{{ range (.Site.RegularPages.GroupByDate "2006") }}
+ {{ $articles := (where .Pages "Type" $type) }}
+ {{ if and (gt .Key 1) (gt (where .Pages "Type" $type) 0) }}
+ {{ range (first 1 $articles) }}
+ <h1>{{ .Date.Format "2006" }}</h1>
+ {{ end }}
+ <ul>
+ {{ range $articles }}
+ {{ if (ne .Params.hidden true) }}
+ <li>
+ <a title="{{ .Title }}" href="{{ .RelPermalink }}">
+ {{ .Date.Format "02 Jan" }} &mdash; {{ .Title | markdownify }}
+ </a>
+ </li>
+ {{ end }}
+ {{ end }}
+ </ul>
+ {{ end }}
+{{ end }}
+</section>
+{{ end }}
diff --git a/themes/opulene/layouts/_default/baseof.html b/themes/opulene/layouts/_default/baseof.html
new file mode 100644
index 0000000..3d5143c
--- /dev/null
+++ b/themes/opulene/layouts/_default/baseof.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ {{- partial "header.html" . -}}
+ </head>
+
+ <body>
+ {{- partial "navigator.html" . -}}
+
+ {{- block "main" . -}}
+ <p>
+ If you are seeing this, your page content hasn't been created.
+ </p>
+ {{- end -}}
+
+ {{- partial "footer.html" . -}}
+ </body>
+</html>
diff --git a/themes/opulene/layouts/_default/index.json b/themes/opulene/layouts/_default/index.json
new file mode 100644
index 0000000..af03997
--- /dev/null
+++ b/themes/opulene/layouts/_default/index.json
@@ -0,0 +1,40 @@
+{
+ "version": "https://jsonfeed.org/version/1.1",
+ "title": "{{ .Site.Title }}",
+ "home_page_url": "{{ .Site.BaseURL }}",
+ "feed_url": "{{ .Site.BaseURL }}/index.json",
+ "items": [
+ {{- range $index, $data := .Site.Pages -}}
+ {{- if ne $data.Type "json" -}}
+ {{- if and $index (gt $index 0) -}},{{- end }}
+ {
+ "id": "{{ md5 $data.Permalink }}",
+ "url": "{{ $data.Permalink }}",
+ "title": "{{ htmlEscape $data.Title}}",
+ "content_text": {{ $data.Plain | jsonify }},
+ "content_html": {{ $data.Content | jsonify }},
+ "summary": "{{ $data.Summary }}",
+ "date_modified": "{{ $data.Date | time.Format "2006-01-02T15:04:05Z" }}",
+ "date_published": "{{ $data.PublishDate | time.Format "2006-01-02T15:04:05Z" }}",
+ "_metadata": {
+ "slug": "{{ $data.Slug }}",
+ "type": "{{ $data.Type }}"
+ },
+ "author": {
+ "name": "{{ .Site.Author.name }}"
+ },
+ "tags": [
+ {{- range $tags, $tag := $data.Params.tags -}}
+ {{- if $tags -}}
+ ,
+ {{- end -}}
+ "
+ {{- $tag | htmlEscape -}}
+ "
+ {{- end -}}
+ ]
+ }
+ {{- end -}}
+ {{ end }}
+ ]
+}
diff --git a/themes/opulene/layouts/_default/list.html b/themes/opulene/layouts/_default/list.html
new file mode 100644
index 0000000..d565b84
--- /dev/null
+++ b/themes/opulene/layouts/_default/list.html
@@ -0,0 +1,9 @@
+{{ define "main" }}
+<section>
+ <article>
+ <h2>{{ .Title | markdownify }}</h2>
+ {{ range .Paginator.Pages }} {{ .Render "summary" }} {{ end }}
+ </article>
+ {{ partial "pagination.html" . }}
+</section>
+{{ end }}
diff --git a/themes/opulene/layouts/_default/rss.xml b/themes/opulene/layouts/_default/rss.xml
new file mode 100644
index 0000000..3c1583a
--- /dev/null
+++ b/themes/opulene/layouts/_default/rss.xml
@@ -0,0 +1,35 @@
+{{- $pctx := . -}}
+{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
+{{- $pages := $pctx.RegularPages -}}
+{{- $limit := .Site.Config.Services.RSS.Limit -}}
+{{- if ge $limit 1 -}}
+{{- $pages = $pages | first $limit -}}
+{{- end -}}
+{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} from {{ end }}{{ .Site.Title }}{{ end }}</title>
+ <link>{{ .Permalink }}</link>
+ <description>Recent {{ if ne .Title .Site.Title }}{{ with .Title }}{{ . }} {{ end }}{{ end }}from {{ .Site.Title }}</description>
+ <language>{{ .Site.LanguageCode }}</language>
+ <managingEditor>{{ $.Site.Author.name }}</managingEditor>
+ <webMaster>{{ $.Site.Author.name }}</webMaster>
+ <copyright>{{ $.Site.Author.name }}</copyright>{{ if not .Date.IsZero }}
+ <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
+ {{ with .OutputFormats.Get "RSS" }}
+ {{- printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML -}}
+ {{ end }}
+ {{ range $pages }}
+ {{ if (ne .Params.hidden true) }}
+ <item>
+ <title>{{ .Title }}</title>
+ <link>{{ .Permalink }}</link>
+ <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+ <author>{{ $.Site.Author.name }}</author>
+ <guid>{{ .Permalink }}</guid>
+ <description>{{ .Content | html }}</description>
+ </item>
+ {{ end }}
+ {{ end }}
+ </channel>
+</rss>
diff --git a/themes/opulene/layouts/_default/section.html b/themes/opulene/layouts/_default/section.html
new file mode 100644
index 0000000..08d4765
--- /dev/null
+++ b/themes/opulene/layouts/_default/section.html
@@ -0,0 +1,17 @@
+{{ define "main" }}
+<section>
+ <article>
+ <span>
+ See an archive of all {{ .Type }}
+ <a href="{{ partial "archive-link.html" . }}">here.</a>
+ </span>
+ {{ range where .Paginator.Pages ".Params.hidden" "ne" "true" }}
+ {{ .Render "summary" }}
+ {{ end }}
+ </article>
+ {{ partial "pagination.html" . }}
+ <a href="{{ partial "archive-link.html" . }}">
+ <span>Archive of all {{ .Type }}</span>
+ </a>
+</section>
+{{ end }}
diff --git a/themes/opulene/layouts/_default/single.html b/themes/opulene/layouts/_default/single.html
new file mode 100644
index 0000000..7fffede
--- /dev/null
+++ b/themes/opulene/layouts/_default/single.html
@@ -0,0 +1,20 @@
+{{ define "main" }}
+<main>
+ <article>
+ <h1>{{ .Title | markdownify }}</h1>
+ {{ if .Params.toc }}
+ <section>
+ {{ .TableOfContents }}
+ </section>
+ {{ end }}
+ <aside>
+ {{- partial "page-meta.html" . -}}
+ {{- partial "read-time.html" . -}}
+ &middot;
+ {{ .FuzzyWordCount }} words
+ {{- partial "page-status.html" . -}}
+ </aside>
+ {{- .Content | safeHTML -}}
+ </article>
+</main>
+{{ end }}
diff --git a/themes/opulene/layouts/_default/sitemap.xml b/themes/opulene/layouts/_default/sitemap.xml
new file mode 100644
index 0000000..63f5119
--- /dev/null
+++ b/themes/opulene/layouts/_default/sitemap.xml
@@ -0,0 +1,22 @@
+{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml">
+ {{ range .Data.Pages }}
+ <url>
+ <loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
+ <lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
+ <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
+ <priority>{{ .Sitemap.Priority }}</priority>{{ end }}{{ if .IsTranslated }}{{ range .Translations }}
+ <xhtml:link
+ rel="alternate"
+ hreflang="{{ .Language.Lang }}"
+ href="{{ .Permalink }}"
+ />{{ end }}
+ <xhtml:link
+ rel="alternate"
+ hreflang="{{ .Language.Lang }}"
+ href="{{ .Permalink }}"
+ />{{ end }}
+ </url>
+ {{ end }}
+</urlset>
diff --git a/themes/opulene/layouts/_default/subsection.html b/themes/opulene/layouts/_default/subsection.html
new file mode 100644
index 0000000..50ffed0
--- /dev/null
+++ b/themes/opulene/layouts/_default/subsection.html
@@ -0,0 +1,8 @@
+{{ define "main" }}
+<section>
+ <article>
+ <h1>{{ .Title | markdownify }}</h1>
+ {{- partial "page-status.html" . -}} {{- .Content | safeHTML }}
+ </article>
+</section>
+{{ end }}
diff --git a/themes/opulene/layouts/_default/summary.html b/themes/opulene/layouts/_default/summary.html
new file mode 100644
index 0000000..8111138
--- /dev/null
+++ b/themes/opulene/layouts/_default/summary.html
@@ -0,0 +1,28 @@
+<section>
+{{ partial "thumbnail-image.html" . }}
+ <article>
+ <header>
+ <h2>
+ <a
+ href="{{ .Permalink }}"
+ title="{{ .Title }}">
+ {{ .Title | markdownify }}
+ </a>
+ </h2>
+ <p>
+ {{ partial "page-date.html" . }}{{ partial "page-status.html" . }} &middot; {{ partial "read-time.html" . }}
+ </p>
+ </header>
+ <p>
+ {{ if .Params.summary }}
+ {{ truncate 75 "..." .Params.summary }}
+ {{ else }}
+ {{ truncate 75 "..." .Summary}}
+ {{ end }}</p>
+ <p>
+ <a href='{{ .Permalink }}'>
+ Continue reading ({{ .FuzzyWordCount }} words)
+ </a>
+ </p>
+ </article>
+</section>
diff --git a/themes/opulene/layouts/_default/taxonomy.html b/themes/opulene/layouts/_default/taxonomy.html
new file mode 100644
index 0000000..378aad4
--- /dev/null
+++ b/themes/opulene/layouts/_default/taxonomy.html
@@ -0,0 +1,60 @@
+{{ define "main" }}
+ {{ $title := .Title }}
+ <section>
+ {{ if eq $title "Tags" }}
+ <article>
+ <h1>Taxonomies</h1>
+ <span>
+ See the <a href="/archives/tags/">archive of all taxonomies</a>.
+ </span>
+ {{ range .Paginator.Pages }}
+ {{ $title := .Title }}
+ <h1>{{ .Title | title }}</h1>
+ {{ range $taxonomy := .Site.Taxonomies }}
+ {{ range $tag, $article := $taxonomy }}
+ {{ if eq $tag $title }}
+ <ul>
+ {{ range $article.Pages }}
+ <li>
+ <a title="{{ .Title }}" href="{{ .RelPermalink }}">
+ {{ .Date.Format "02 Jan 2006" }} &mdash; {{ .Title }}
+ </a>
+ </li>
+ {{ end }}
+ </ul>
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ </article>
+ {{ partial "pagination.html" . }}
+ {{ end }}
+
+ {{ if ne $title "Tags" }}
+ <article>
+ <h1>
+ <a href="/{{ .Data.Plural }}/">Tags</a>
+ </h1>
+ <h2>{{ .Title | title }}</h2>
+ <p>
+ See the <a href="/archives/tags/">archive of all taxonomies</a>.
+ </p>
+ {{ range $taxonomy := .Site.Taxonomies }}
+ {{ range $tag, $article := $taxonomy }}
+ {{ if eq $tag $title }}
+ <ul>
+ {{ range $article.Pages }}
+ <li>
+ <a title="{{ .Title }}" href="{{ .RelPermalink }}">
+ {{- .Date.Format "02 Jan 2006" }} &mdash; {{ .Title | markdownify -}}
+ </a>
+ </li>
+ {{ end }}
+ </ul>
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ </article>
+ {{ end }}
+ </section>
+{{ end }}
diff --git a/themes/opulene/layouts/_default/taxonomy_archive.html b/themes/opulene/layouts/_default/taxonomy_archive.html
new file mode 100644
index 0000000..5f96f85
--- /dev/null
+++ b/themes/opulene/layouts/_default/taxonomy_archive.html
@@ -0,0 +1,28 @@
+{{ define "main" }}
+<section>
+{{ $title := .Title }}
+<article >
+ <h1 >{{ .Title | markdownify }}</h1>
+ {{ range $taxonomy := .Site.Taxonomies }}
+ {{ $title := .Title }}
+ {{ range $tag, $article := $taxonomy }}
+ {{ if ne $tag $title }}
+ <h1 >{{ $tag }}</h1>
+ <ul >
+ {{ range $article.Pages }}
+ <li>
+ <a title="{{ .Title }}" >
+ <span >
+ {{- .Date.Format "02 Jan 2006" -}}
+ </span>
+ {{- .Title | markdownify -}}
+ </a>
+ </li>
+ {{ end }}
+ </ul>
+ {{ end }}
+ {{ end }}
+ {{ end }}
+</article>
+</section>
+{{ end }}
diff --git a/themes/opulene/layouts/partials/archive-link.html b/themes/opulene/layouts/partials/archive-link.html
new file mode 100644
index 0000000..8b08ba3
--- /dev/null
+++ b/themes/opulene/layouts/partials/archive-link.html
@@ -0,0 +1,2 @@
+/archives/{{ .Type }}/
+{{- /* Strip newline. */ -}}
diff --git a/themes/opulene/layouts/partials/article-image.html b/themes/opulene/layouts/partials/article-image.html
new file mode 100644
index 0000000..fbda825
--- /dev/null
+++ b/themes/opulene/layouts/partials/article-image.html
@@ -0,0 +1 @@
+{{- or .Slug "placeholder" -}}
diff --git a/themes/opulene/layouts/partials/footer.html b/themes/opulene/layouts/partials/footer.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/themes/opulene/layouts/partials/footer.html
diff --git a/themes/opulene/layouts/partials/header.html b/themes/opulene/layouts/partials/header.html
new file mode 100644
index 0000000..b8b2cd1
--- /dev/null
+++ b/themes/opulene/layouts/partials/header.html
@@ -0,0 +1,31 @@
+<!-- HTML Meta Tags -->
+<title>{{ partial "title.html" . -}}</title>
+<meta name="description" content="{{ if .Params.summary }}{{ .Params.summary }}{{ else }}{{ .Summary }}{{ end }}">
+<meta name="keywords" content="{{ partial "title.html" . -}}">
+<meta name="author" content="{{ .Site.Author.name }}">
+
+<meta charset="utf-8">
+<meta name="robots" content="index,follow">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
+<!-- Search Engine Tags -->
+<meta itemprop="name" content="{{ partial "title.html" . -}}">
+<meta itemprop="description" content="{{ if .Params.summary }}{{ .Params.summary }}{{ else }}{{ .Summary }}{{ end }}">
+<meta itemprop="image" content="{{ .Site.BaseURL }}/images/{{ partial "article-image.html" . }}.png">
+
+<!-- Open Graph Meta Tags -->
+<meta property="og:title" content="{{ partial "title.html" . -}}">
+<meta property="og:description" content="{{ if .Params.summary }}{{ .Params.summary }}{{ else }}{{ .Summary }}{{ end }}">
+<meta property="og:url" content="{{ .Permalink }}">
+<meta property="og:image" content="{{ .Site.BaseURL }}/images/{{ partial "article-image.html" . }}.png">
+<meta property="og:type" content="website">
+<meta property="article:published_time" content="{{ .Params.date }}">
+<meta property="article:modified_time " content="{{ if .Params.updated }}{{ .Params.updated }}{{ else }}{{ .Params.date }}{{ end }}">
+
+<!-- Twitter Meta Tags -->
+<meta name="twitter:card" content="summary_large_image">
+<meta name="twitter:title" content="{{ partial "title.html" . -}}">
+<meta name="twitter:description" content="{{ if .Params.summary }}{{ .Params.summary }}{{ else }}{{ .Summary }}{{ end }}">
+<meta name="twitter:image" content="{{ .Site.BaseURL }}/images/{{ partial "article-image.html" . }}.png">
+
+<link rel="stylesheet" href="/css/default.css">
diff --git a/themes/opulene/layouts/partials/navigator.html b/themes/opulene/layouts/partials/navigator.html
new file mode 100644
index 0000000..4cd4aa8
--- /dev/null
+++ b/themes/opulene/layouts/partials/navigator.html
@@ -0,0 +1,9 @@
+{{ if .Site.Menus.main }}
+<ul>
+ {{ range sort .Site.Menus.main }}
+ <li>
+ <a href="{{ .URL }}">{{ .Name }}</a>
+ </li>
+ {{ end }}
+</ul>
+{{ end }}
diff --git a/themes/opulene/layouts/partials/page-categories.html b/themes/opulene/layouts/partials/page-categories.html
new file mode 100644
index 0000000..efd6cb7
--- /dev/null
+++ b/themes/opulene/layouts/partials/page-categories.html
@@ -0,0 +1,2 @@
+{{- range $i, $value := sort . -}}{{ if $i }}, {{ end -}}
+<a href="{{ "categories/" | absLangURL }}{{ $value | urlize }}/">{{ $value }}</a>{{- end -}}
diff --git a/themes/opulene/layouts/partials/page-date.html b/themes/opulene/layouts/partials/page-date.html
new file mode 100644
index 0000000..e53e222
--- /dev/null
+++ b/themes/opulene/layouts/partials/page-date.html
@@ -0,0 +1,5 @@
+{{ if .Params.date }}
+<time datetime="{{ dateFormat "2006-01-02" .Params.date }}">{{ dateFormat "2 January 2006" .Params.date }}</time>
+{{else}}
+<time datetime="{{ .Date.Format "2006-01-02"}}">{{ .Date.Format "2 January 2006" }}</time>
+{{- end -}}
diff --git a/themes/opulene/layouts/partials/page-meta.html b/themes/opulene/layouts/partials/page-meta.html
new file mode 100644
index 0000000..44cc4fb
--- /dev/null
+++ b/themes/opulene/layouts/partials/page-meta.html
@@ -0,0 +1,3 @@
+{{ partial "page-date.html" . -}}
+{{- with .Params.categories }} in {{ partial "page-categories.html" . }}{{ end }}
+{{- with .Params.tags }} {{ partial "page-tags.html" . }}{{ end }}
diff --git a/themes/opulene/layouts/partials/page-status.html b/themes/opulene/layouts/partials/page-status.html
new file mode 100644
index 0000000..de7c94f
--- /dev/null
+++ b/themes/opulene/layouts/partials/page-status.html
@@ -0,0 +1 @@
+{{ if .Draft }}<span>&middot;<strong> DRAFT</strong></span>{{ end }}
diff --git a/themes/opulene/layouts/partials/page-tags.html b/themes/opulene/layouts/partials/page-tags.html
new file mode 100644
index 0000000..fbf3ee8
--- /dev/null
+++ b/themes/opulene/layouts/partials/page-tags.html
@@ -0,0 +1,6 @@
+&middot;
+{{- range $i, $value := sort . }}{{ if $i }} {{ end }}
+<a href="{{ "tags/" | relURL }}{{ $value | urlize }}/">
+ {{ $value }}</a>
+&middot;
+{{ end }}
diff --git a/themes/opulene/layouts/partials/pagination.html b/themes/opulene/layouts/partials/pagination.html
new file mode 100644
index 0000000..d1483e4
--- /dev/null
+++ b/themes/opulene/layouts/partials/pagination.html
@@ -0,0 +1,154 @@
+{{- $validFormats := slice "default" "terse" }}
+
+{{- $msg1 := "When passing a map to the internal pagination template, one of the elements must be named 'page', and it must be set to the context of the current page." }}
+{{- $msg2 := "The 'format' specified in the map passed to the internal pagination template is invalid. Valid choices are: %s." }}
+
+{{- $page := . }}
+{{- $format := "default" }}
+
+{{- if reflect.IsMap . }}
+ {{- with .page }}
+ {{- $page = . }}
+ {{- else }}
+ {{- errorf $msg1 }}
+ {{- end }}
+ {{- with .format }}
+ {{- $format = lower . }}
+ {{- end }}
+{{- end }}
+
+{{- if in $validFormats $format }}
+ {{- if gt $page.Paginator.TotalPages 1 }}
+ <ul >
+ {{- partial (printf "partials/inline/pagination/%s" $format) $page }}
+ </ul>
+ {{- end }}
+{{- else }}
+ {{- errorf $msg2 (delimit $validFormats ", ") }}
+{{- end -}}
+
+{{/* Format: default
+{{/* --------------------------------------------------------------------- */}}
+{{- define "partials/inline/pagination/default" }}
+ {{- with .Paginator }}
+ {{- $currentPageNumber := .PageNumber }}
+
+ {{- with .First }}
+ {{- if ne $currentPageNumber .PageNumber }}
+ <li >
+ <a href="{{ .URL }}" aria-label="First" role="button"><span aria-hidden="true">&laquo;&laquo;</span></a>
+ </li>
+ {{- else }}
+ <li >
+ <a aria-disabled="true" aria-label="First" tabindex="-1"><span aria-hidden="true">&laquo;&laquo;</span></a>
+ </li>
+ {{- end }}
+ {{- end }}
+
+ {{- with .Prev }}
+ <li >
+ <a href="{{ .URL }}" aria-label="Previous" role="button"><span aria-hidden="true">&laquo;</span></a>
+ </li>
+ {{- else }}
+ <li >
+ <a aria-disabled="true" aria-label="Previous" tabindex="-1"><span aria-hidden="true">&laquo;</span></a>
+ </li>
+ {{- end }}
+
+ {{- $slots := 5 }}
+ {{- $start := math.Max 1 (sub .PageNumber (math.Floor (div $slots 2))) }}
+ {{- $end := math.Min .TotalPages (sub (add $start $slots) 1) }}
+ {{- if lt (add (sub $end $start) 1) $slots }}
+ {{- $start = math.Max 1 (add (sub $end $slots) 1) }}
+ {{- end }}
+
+ {{- range $k := seq $start $end }}
+ {{- if eq $.Paginator.PageNumber $k }}
+ <li >
+ <a aria-label="Page {{ $k }}" role="button">{{ $k }}</a>
+ </li>
+ {{- else }}
+ <li >
+ <a href="{{ (index $.Paginator.Pagers (sub $k 1)).URL }}" aria-label="Page {{ $k }}" role="button">{{ $k }}</a>
+ </li>
+ {{- end }}
+ {{- end }}
+
+ {{- with .Next }}
+ <li >
+ <a href="{{ .URL }}" aria-label="Next" role="button"><span aria-hidden="true">&raquo;</span></a>
+ </li>
+ {{- else }}
+ <li >
+ <a aria-disabled="true" aria-label="Next" tabindex="-1"><span aria-hidden="true">&raquo;</span></a>
+ </li>
+ {{- end }}
+
+ {{- with .Last }}
+ {{- if ne $currentPageNumber .PageNumber }}
+ <li >
+ <a href="{{ .URL }}" aria-label="Last" role="button"><span aria-hidden="true">&raquo;&raquo;</span></a>
+ </li>
+ {{- else }}
+ <li >
+ <a aria-disabled="true" aria-label="Last" tabindex="-1"><span aria-hidden="true">&raquo;&raquo;</span></a>
+ </li>
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end -}}
+
+{{/* Format: terse
+{{/* --------------------------------------------------------------------- */}}
+{{- define "partials/inline/pagination/terse" }}
+ {{- with .Paginator }}
+ {{- $currentPageNumber := .PageNumber }}
+
+ {{- with .First }}
+ {{- if ne $currentPageNumber .PageNumber }}
+ <li >
+ <a href="{{ .URL }}" aria-label="First" role="button"><span aria-hidden="true">&laquo;&laquo;</span></a>
+ </li>
+ {{- end }}
+ {{- end }}
+
+ {{- with .Prev }}
+ <li >
+ <a href="{{ .URL }}" aria-label="Previous" role="button"><span aria-hidden="true">&laquo;</span></a>
+ </li>
+ {{- end }}
+
+ {{- $slots := 3 }}
+ {{- $start := math.Max 1 (sub .PageNumber (math.Floor (div $slots 2))) }}
+ {{- $end := math.Min .TotalPages (sub (add $start $slots) 1) }}
+ {{- if lt (add (sub $end $start) 1) $slots }}
+ {{- $start = math.Max 1 (add (sub $end $slots) 1) }}
+ {{- end }}
+
+ {{- range $k := seq $start $end }}
+ {{- if eq $.Paginator.PageNumber $k }}
+ <li >
+ <a aria-label="Page {{ $k }}" role="button">{{ $k }}</a>
+ </li>
+ {{- else }}
+ <li >
+ <a href="{{ (index $.Paginator.Pagers (sub $k 1)).URL }}" aria-label="Page {{ $k }}" role="button">{{ $k }}</a>
+ </li>
+ {{- end }}
+ {{- end }}
+
+ {{- with .Next }}
+ <li >
+ <a href="{{ .URL }}" aria-label="Next" role="button"><span aria-hidden="true">&raquo;</span></a>
+ </li>
+ {{- end }}
+
+ {{- with .Last }}
+ {{- if ne $currentPageNumber .PageNumber }}
+ <li >
+ <a href="{{ .URL }}" aria-label="Last" role="button"><span aria-hidden="true">&raquo;&raquo;</span></a>
+ </li>
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end -}}
diff --git a/themes/opulene/layouts/partials/read-time.html b/themes/opulene/layouts/partials/read-time.html
new file mode 100644
index 0000000..6eb634c
--- /dev/null
+++ b/themes/opulene/layouts/partials/read-time.html
@@ -0,0 +1,6 @@
+{{ $minutes := div .WordCount 150 }}
+{{ if lt $minutes 1 }}
+ 1 minute read
+{{ else }}
+ {{ $minutes }} minute read
+{{ end }}
diff --git a/themes/opulene/layouts/partials/thumbnail-image.html b/themes/opulene/layouts/partials/thumbnail-image.html
new file mode 100644
index 0000000..bf033eb
--- /dev/null
+++ b/themes/opulene/layouts/partials/thumbnail-image.html
@@ -0,0 +1,29 @@
+{{ $imageFile := print "public/images/thumbnails/" (partial "article-image.html" .) ".png" }}
+{{ if fileExists $imageFile }}
+{{ $image := imageConfig $imageFile }}
+<a title="{{ .Title }}" href="{{ .Permalink }}">
+ <picture>
+ <source srcset="/images/thumbnails/{{ partial "article-image.html" . }}.png" type="image/png">
+ <source srcset="/images/thumbnails/{{ partial "article-image.html" . }}.jpg" type="image/jpeg">
+ <source srcset="/images/thumbnails/{{ partial "article-image.html" . }}.webp" type="image/webp">
+ <img
+ alt="{{ .Title }}"
+ src="/images/thumbnails/{{ partial "article-image.html" . }}.png"
+ width="{{ $image.Width }}"
+ height="{{ $image.Height }}"
+ />
+ </picture>
+</a>
+{{ else }}
+{{ $image := imageConfig "/static/images/placeholder.png" }}
+<a href="{{ .Permalink }}">
+ <figure>
+ <img
+ alt="{{ .Title }}"
+ src="/images/placeholder.png"
+ height="{{ $image.Height }}"
+ width="{{ $image.Width }}"
+ />
+ </figure>
+</a>
+{{ end }}
diff --git a/themes/opulene/layouts/partials/title.html b/themes/opulene/layouts/partials/title.html
new file mode 100644
index 0000000..874d944
--- /dev/null
+++ b/themes/opulene/layouts/partials/title.html
@@ -0,0 +1,2 @@
+{{ with .Title }}{{ . }}{{ end }}
+{{- with $.Site.Title }} - {{ . }}{{ end -}}
diff --git a/themes/opulene/layouts/shortcodes/audio.html b/themes/opulene/layouts/shortcodes/audio.html
new file mode 100644
index 0000000..4df2f51
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/audio.html
@@ -0,0 +1,18 @@
+{{- $src := default
+ "https://ia600701.us.archive.org/12/items/firstchaptercollection001_1109_librivox/firstchapter001_02_taletwocities_dickens_law.mp3"
+ (.Get "src" | default (.Get 0))
+-}}
+{{- $caption := default "A Tale of Two Cities by Charles Dickens" (.Get "caption" | default (.Get 1)) -}}
+{{- $controls := default "" (.Get "controls" | default (.Get 2)) -}}
+
+<audio-player>
+ <figure>
+ <figcaption>{{ $caption }}</figcaption>
+ <audio controls {{ $controls | safeHTMLAttr }} src="{{ $src }}">
+ <p>
+ Your browser doesn't support HTML5 <code>audio</code>. Here is a
+ <a href="{{ $src }}">link to the audio file</a> instead.
+ </p>
+ </audio>
+ </figure>
+</audio-player>
diff --git a/themes/opulene/layouts/shortcodes/gist.html b/themes/opulene/layouts/shortcodes/gist.html
new file mode 100644
index 0000000..3d61a82
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/gist.html
@@ -0,0 +1,10 @@
+{{- $user := default "gdb" (.Get "user" | default (.Get 0)) -}}
+{{- $gist := default "b6365e79be6052e7531e7ba6ea8caf23" (.Get "gist" | default (.Get 1)) -}}
+{{- $file := default "" (.Get "file" | default (.Get 2)) -}}
+
+<github-gist>
+ <script
+ type="application/javascript"
+ src="https://gist.github.com/{{ $user }}/{{ $gist }}.js?file={{ $file }}">
+ </script>
+</github-gist>
diff --git a/themes/opulene/layouts/shortcodes/imgur-image.html b/themes/opulene/layouts/shortcodes/imgur-image.html
new file mode 100644
index 0000000..f51bcef
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/imgur-image.html
@@ -0,0 +1,13 @@
+{{- $id := default "mkVcxUi" (.Get "id" | default (.Get 0)) -}}
+
+<imgur-image>
+ <blockquote
+ class="imgur-embed-pub"
+ lang="en"
+ data-id="a/{{ $id }}"
+ data-context="false"
+ >
+ <a href="//imgur.com/a/{{ $id }}"></a>
+ </blockquote>
+ <script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
+</imgur-image>
diff --git a/themes/opulene/layouts/shortcodes/imgur-video.html b/themes/opulene/layouts/shortcodes/imgur-video.html
new file mode 100644
index 0000000..8e45dfc
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/imgur-video.html
@@ -0,0 +1,13 @@
+{{- $id := default "uVrh84e" (.Get "id" | default (.Get 0)) -}}
+
+<imgur-video>
+ <blockquote
+ class="imgur-embed-pub"
+ lang="en"
+ data-id="{{ $id }}"
+ data-context="false"
+ >
+ <a href="//imgur.com/{{ $id }}"></a>
+ </blockquote>
+ <script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
+</imgur-video>
diff --git a/themes/opulene/layouts/shortcodes/reddit.html b/themes/opulene/layouts/shortcodes/reddit.html
new file mode 100644
index 0000000..cb057cf
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/reddit.html
@@ -0,0 +1,29 @@
+{{- $path := default "linux/comments/aeufh6/vlc_has_now_reached_3_billions_downloads_and/edsvibz" (.Get "path" | default (.Get 0)) -}}
+{{- $depth := default "2" (.Get "depth" | default (.Get 1)) -}}
+{{- $context := default "1" (.Get "context" | default (.Get 2)) -}}
+{{- $theme := default "light" (.Get "theme" | default (.Get 3)) -}}
+{{- $showtitle := default "true" (.Get "showtitle" | default (.Get 4)) -}}
+{{- $showedits := default "false" (.Get "showedits" | default (.Get 5)) -}}
+{{- $showmedia := default "false" (.Get "showmedia" | default (.Get 6)) -}}
+{{- $showmore := default "false" (.Get "showmore" | default (.Get 7)) -}}
+
+<reddit-comment>
+ <iframe
+ id="reddit-embed"
+ src="https://www.redditmedia.com/r/{{ trim $path "/" }}/
+?depth={{ $depth }}
+&amp;embed=true
+&amp;showmore={{ $showmore }}
+&amp;showtitle={{ $showtitle }}
+&amp;context={{ $context }}
+&amp;showmedia={{ $showmedia }}
+&amp;theme={{ $theme }}
+&amp;showedits={{ $showedits }}
+&amp;created={{ now.Format "2006-01-02T15:04:05Z" }}"
+ sandbox="allow-scripts allow-same-origin allow-popups"
+ style="border: none;"
+ height="452"
+ width="640"
+ scrolling="no"
+ ></iframe>
+</reddit-comment>
diff --git a/themes/opulene/layouts/shortcodes/tweet.html b/themes/opulene/layouts/shortcodes/tweet.html
new file mode 100644
index 0000000..6883966
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/tweet.html
@@ -0,0 +1,15 @@
+{{- $user := default "jack" (.Get "user" | default (.Get 0)) -}}
+{{- $status := default "20" (.Get "status" | default (.Get 1)) -}}
+
+<twitter-tweet>
+ <blockquote class="twitter-tweet">
+ <a href="https://twitter.com/{{ $user }}/status/{{ $status }}">
+ https://twitter.com/{{ $user }}/status/{{ $status }}
+ </a>
+ </blockquote>
+ <script
+ async
+ src="https://platform.twitter.com/widgets.js"
+ charset="utf-8">
+ </script>
+</twitter-tweet>
diff --git a/themes/opulene/layouts/shortcodes/video.html b/themes/opulene/layouts/shortcodes/video.html
new file mode 100644
index 0000000..7bc4405
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/video.html
@@ -0,0 +1,26 @@
+{{-
+ $source := default
+ "https://raw.githubusercontent.com/benhosmer/HTML5-Test-Videos/9a6c2db46472454c634963cbeb0900fd37901fac/big_buck_bunny"
+ (.Get "source" | default (.Get 0))
+-}}
+{{- $poster := default "" (.Get "poster" | default (.Get 1)) -}}
+{{- $width := default "" (.Get "width" | default (.Get 2)) -}}
+{{- $height := default "" (.Get "height" | default (.Get 3)) -}}
+{{- $preload := default "metadata" (.Get "preload" | default (.Get 4)) -}}
+{{- $controls := default "" (.Get "controls" | default (.Get 5)) -}}
+
+<video-container>
+ <video
+ preload="{{ $preload }}"
+ poster="{{ $poster }}"
+ width="{{ $width }}"
+ height="{{ $height }}"
+ controls {{ $controls | safeHTMLAttr }}>
+ <source src="{{ $source }}.mp4" type="video/mp4">
+ <source src="{{ $source }}.webm" type="video/webm">
+ <source src="{{ $source }}.flv" type="video/flv">
+ <source src="{{ $source }}.ogv" type="video/ogv">
+ <p>Sorry, your browser doesn't support embedded videos.</p>
+ </video>
+ <figcaption class="has-text-grey-dark">{{ .Inner | markdownify }}</figcaption>
+</video-container>
diff --git a/themes/opulene/layouts/shortcodes/vimeo.html b/themes/opulene/layouts/shortcodes/vimeo.html
new file mode 100644
index 0000000..972d31d
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/vimeo.html
@@ -0,0 +1,12 @@
+{{- $id := default "1084537" (.Get "id" | default (.Get 0)) -}}
+{{- $title := default "Vimeo Video" (.Get "title" | default (.Get 1)) -}}
+
+<vimeo-video>
+ <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
+ <iframe
+ src="https://player.vimeo.com/video/{{ $id }}?dnt=1"
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"
+ title="{{ $title }}" webkitallowfullscreen mozallowfullscreen allowfullscreen>
+ </iframe>
+ </div>
+</vimeo-video>
diff --git a/themes/opulene/layouts/shortcodes/youtube.html b/themes/opulene/layouts/shortcodes/youtube.html
new file mode 100644
index 0000000..27c21a9
--- /dev/null
+++ b/themes/opulene/layouts/shortcodes/youtube.html
@@ -0,0 +1,14 @@
+{{- $url := "www.youtube-nocookie.com" -}}
+{{- $id := default "aqz-KE-bpKQ" (.Get "id" | default (.Get 0)) -}}
+{{- $title := default "YouTube Video" (.Get "title" | default (.Get 1)) }}
+
+<youtube-video>
+ <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
+ <iframe
+ src="https://{{ $url }}/embed/{{ $id }}{{ with .Get "autoplay" }}{{ if eq . "true" }}?autoplay=1{{ end }}{{ end }}"
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"
+ allowfullscreen title="{{ $title }}">
+ </iframe>
+ </div>
+</youtube-video>
+