@@ 0,0 1,367 @@
+:root {
+ --b-font-main: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ --b-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
+ "Liberation Mono", "Courier New", monospace;
+ --b-txt: #2e3440;
+ --b-bg-1: #fff;
+ --b-bg-2: #eceff4;
+ --b-line: #eceff4;
+ --b-link: #bf616a;
+ --b-btn-bg: #242933;
+ --b-btn-txt: #fff;
+ --b-focus: #88c0d0;
+}
+@media (prefers-color-scheme: dark) {
+ :root {
+ --b-txt: #eceff4;
+ --b-bg-1: #2e3440;
+ --b-bg-2: #3b4252;
+ --b-line: #3b4252;
+ }
+}
+*,
+::before,
+::after {
+ box-sizing: border-box;
+}
+html:focus-within {
+ scroll-behavior: smooth;
+}
+body {
+ max-width: 70ch;
+ padding: 0 1rem;
+ margin: auto;
+ background: var(--b-bg-1);
+ font-family: var(--b-font-main);
+ text-rendering: optimizeSpeed;
+ line-height: 1.5;
+ color: var(--b-txt);
+ -moz-tab-size: 4;
+ tab-size: 4;
+ word-break: break-word;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-text-size-adjust: 100%;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+ul,
+ol,
+dl,
+dd,
+details,
+blockquote,
+pre,
+figure,
+table,
+address,
+hr,
+fieldset,
+iframe,
+audio,
+video {
+ margin: 0 0 1.5rem;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ line-height: 1.25;
+ margin-top: 2rem;
+}
+h1 {
+ font-size: 2rem;
+}
+h2 {
+ font-size: 1.5rem;
+}
+h3 {
+ font-size: 1.25rem;
+}
+h4 {
+ font-size: 1rem;
+}
+h5 {
+ font-size: 0.875rem;
+}
+h6 {
+ font-size: 0.75rem;
+}
+a {
+ color: var(--b-link);
+ text-decoration: none;
+}
+a:hover {
+ text-decoration: underline;
+}
+img,
+video,
+svg {
+ max-width: 100%;
+ height: auto;
+}
+embed,
+iframe,
+object {
+ max-width: 100%;
+}
+iframe {
+ border-style: none;
+}
+abbr[title] {
+ text-decoration: underline;
+ text-decoration: underline dotted;
+}
+blockquote {
+ margin-left: 0;
+ padding: 0.5rem 0 0.5rem 1.5rem;
+ border-left: 0.25rem solid var(--b-txt);
+}
+blockquote > :last-child {
+ margin-bottom: 0;
+}
+small {
+ font-size: 0.875rem;
+}
+sub,
+sup {
+ font-size: 0.75em;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+sub {
+ bottom: -0.25em;
+}
+sup {
+ top: -0.5em;
+}
+hr {
+ height: 0;
+ overflow: visible;
+ border: 0;
+ border-bottom: 1px solid var(--b-line);
+}
+pre,
+code,
+kbd,
+samp,
+tt,
+var {
+ background: var(--b-bg-2);
+ border-radius: 0.25rem;
+ padding: 0.125rem 0.25rem;
+ font-family: var(--b-font-mono);
+ font-size: 0.875rem;
+}
+pre {
+ padding: 1rem;
+ border-radius: 0;
+ overflow: auto;
+ white-space: pre;
+}
+pre code {
+ padding: 0;
+}
+details {
+ display: block;
+ padding: 0.5rem 1rem;
+ background: var(--b-bg-2);
+ border: 1px solid var(--b-line);
+ border-radius: 0.25rem;
+}
+details > :last-child {
+ margin-bottom: 0;
+}
+details[open] > summary {
+ margin-bottom: 1.5rem;
+}
+summary {
+ display: list-item;
+ cursor: pointer;
+ font-weight: bold;
+}
+summary:focus {
+ box-shadow: none;
+}
+table {
+ border-collapse: collapse;
+ width: 100%;
+ text-indent: 0;
+}
+table caption {
+ margin-bottom: 0.5rem;
+}
+tr {
+ border-bottom: 1px solid var(--b-line);
+}
+td,
+th {
+ padding: 0.5rem 0;
+}
+th {
+ text-align: left;
+}
+ul,
+ol,
+dd {
+ padding-left: 2rem;
+}
+li > ul,
+li > ol {
+ margin-bottom: 0;
+}
+fieldset {
+ padding: 0.5rem 0.75rem;
+ border: 1px solid var(--b-line);
+ border-radius: 0.25rem;
+}
+legend {
+ padding: 0 0.25rem;
+}
+label {
+ cursor: pointer;
+ display: block;
+ margin-bottom: 0.25rem;
+}
+button,
+input,
+select,
+textarea {
+ margin: 0;
+ padding: 0.5rem 0.75rem;
+ max-width: 100%;
+ background: var(--b-bg-2);
+ border: 0;
+ border-radius: 0.25rem;
+ font: inherit;
+ line-height: 1.125;
+ color: var(--b-txt);
+}
+select,
+input:not([size]):not([type="button" i]):not([type="submit" i]):not([type="reset" i]):not([type="checkbox" i]):not([type="radio" i]) {
+ width: 100%;
+}
+[type="color" i] {
+ min-height: 2.125rem;
+}
+select:not([multiple]):not([size]) {
+ padding-right: 1.5rem;
+ background-repeat: no-repeat;
+ background-position: right 0.5rem center;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+}
+textarea {
+ width: 100%;
+ resize: vertical;
+}
+textarea:not([rows]) {
+ height: 8rem;
+}
+button,
+[type="button" i],
+[type="submit" i],
+[type="reset" i] {
+ -webkit-appearance: button;
+ display: inline-block;
+ text-align: center;
+ white-space: nowrap;
+ background: var(--b-btn-bg);
+ color: var(--b-btn-txt);
+ border: 0;
+ cursor: pointer;
+ transition: opacity 0.25s;
+}
+button:hover,
+[type="button" i]:hover,
+[type="submit" i]:hover,
+[type="reset" i]:hover {
+ opacity: 0.75;
+}
+button[disabled],
+[type="button" i][disabled],
+[type="submit" i][disabled],
+[type="reset" i][disabled] {
+ opacity: 0.5;
+}
+progress {
+ vertical-align: middle;
+}
+[type="search" i] {
+ -webkit-appearance: textfield;
+ outline-offset: -2px;
+}
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+::-webkit-input-placeholder {
+ color: inherit;
+ opacity: 0.5;
+}
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit;
+}
+::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+[aria-busy="true" i] {
+ cursor: progress;
+}
+[aria-controls] {
+ cursor: pointer;
+}
+[aria-disabled="true" i],
+[disabled] {
+ cursor: not-allowed;
+}
+:focus,
+details:focus-within {
+ outline: none;
+ box-shadow: 0 0 0 2px var(--b-focus);
+}
+@media (prefers-reduced-motion: reduce) {
+ html:focus-within {
+ scroll-behavior: auto;
+ }
+ *,
+ ::before,
+ ::after {
+ animation-delay: -1ms !important;
+ animation-duration: 1ms !important;
+ animation-iteration-count: 1 !important;
+ background-attachment: initial !important;
+ scroll-behavior: auto !important;
+ transition-delay: 0 !important;
+ transition-duration: 0 !important;
+ }
+}
+select:not([multiple]):not([size]) {
+ background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%232e3440'%3E%3Cpath d='M5 6l5 5 5-5 2 1-7 7-7-7 2-1z'/%3E%3C/svg%3E");
+}
+@media (prefers-color-scheme: dark) {
+ select:not([multiple]):not([size]) {
+ background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23eceff4'%3E%3Cpath d='M5 6l5 5 5-5 2 1-7 7-7-7 2-1z'/%3E%3C/svg%3E");
+ }
+}
@@ 0,0 1,49 @@
+use std::path::{Path, PathBuf};
+
+#[derive(Debug)]
+pub struct BlogBuilder {
+ file: PathBuf,
+ site_url: String,
+ style: Option<PathBuf>,
+ title: String,
+}
+
+impl BlogBuilder {
+ pub fn file(self, source: PathBuf) -> Self {
+ Self {
+ file: source,
+ ..self
+ }
+ }
+
+ pub fn style(self, source: PathBuf) -> Self {
+ Self {
+ style: Some(source),
+ ..self
+ }
+ }
+
+ pub fn site_url(self, source: String) -> Self {
+ Self {
+ site_url: source,
+ ..self
+ }
+ }
+
+ pub fn build(&self) -> Result<(), Box<dyn std::error::Error>> {
+ if let Some(style) = self.style {
+ Path::new(style).exists()?
+ }
+ }
+}
+
+impl Default for BlogBuilder {
+ fn default() -> Self {
+ Self {
+ file: "entries.md".into(),
+ site_url: "/".into(),
+ style: None,
+ title: "blog".into(),
+ }
+ }
+}