diff --git a/ansible/deploy.yml b/ansible/deploy.yml index 9b4626a..19b848b 100644 --- a/ansible/deploy.yml +++ b/ansible/deploy.yml @@ -28,54 +28,13 @@ owner: "{{ app_user }}" group: "{{ app_user }}" - - name: Install Bun - shell: curl -fsSL https://bun.sh/install | bash - args: - creates: /home/{{ app_user }}/.bun/bin/bun - become_user: "{{ app_user }}" - - - name: Create source directory - file: - path: "{{ app_home }}/src" - state: directory - owner: "{{ app_user }}" - group: "{{ app_user }}" - - - name: Copy package.json + - name: Copy binary to target location copy: - src: ../package.json - dest: "{{ app_home }}/package.json" + src: ../target/sepiatones_xyz + dest: "{{ app_home }}/sepiatones_xyz" owner: "{{ app_user }}" group: "{{ app_user }}" - - - name: Copy bun.lockb - copy: - src: ../bun.lockb - dest: "{{ app_home }}/bun.lockb" - owner: "{{ app_user }}" - group: "{{ app_user }}" - - - name: Copy source files - synchronize: - src: ../src/ - dest: "{{ app_home }}/src/" - recursive: yes - owner: no - group: no - archive: yes - delete: yes - - - name: Install dependencies - shell: /home/{{ app_user }}/.bun/bin/bun install --frozen-lockfile - args: - chdir: "{{ app_home }}" - become_user: "{{ app_user }}" - - - name: Build binary - shell: /home/{{ app_user }}/.bun/bin/bun build --compile --minify --target bun --outfile ./sepiatones_xyz ./src/index.tsx - args: - chdir: "{{ app_home }}" - become_user: "{{ app_user }}" + mode: "0755" - name: Copy data directory synchronize: diff --git a/ansible/hosts.ini b/ansible/hosts.ini index 0270c5a..2a3e189 100644 --- a/ansible/hosts.ini +++ b/ansible/hosts.ini @@ -1,3 +1,3 @@ # It is expected that you have sepiatonesxyz defined in your .ssh/config [production] -sepiatonesxyz ansible_host=sepiatonesxyz ansible_python_interpreter=auto +sepiatonesxyz ansible_host=sepiatonesxyz ansible_python_interpreter=/usr/bin/python3.11 diff --git a/bun.lockb b/bun.lockb old mode 100755 new mode 100644 index 65b9760..8cd5f52 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/data/unposted_posts/things_ai_agents_should_be_able_to_do.html b/data/posts/things_ai_agents_should_be_able_to_do.html similarity index 100% rename from data/unposted_posts/things_ai_agents_should_be_able_to_do.html rename to data/posts/things_ai_agents_should_be_able_to_do.html diff --git a/data/public/dreccan-mono/dreccan-mono.css b/data/public/dreccan-mono/dreccan-mono.css deleted file mode 100644 index 561a425..0000000 --- a/data/public/dreccan-mono/dreccan-mono.css +++ /dev/null @@ -1,699 +0,0 @@ -/* ============================================================ - DENSE — a classless CSS sheet - Flat, squared, information-dense, general-purpose. - - Backbone: ress / resset v5.0.2 (inline below, MIT) - Font: Ioskeley Mono - Aesthetic: U.S. Graphics Co. (usgraphics.com) + the-monospace-web - - Swap the entire color scheme by editing the two :root token - blocks below (light / dark). Everything is driven by them. - ============================================================ */ - -/* ------- fonts ------------------------------------------------- */ - -@font-face { - font-family: "Ioskeley Mono"; - src: url("fonts/IoskeleyMono-Regular.woff2") format("woff2"); - font-weight: 400; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: "Ioskeley Mono"; - src: url("fonts/IoskeleyMono-Italic.woff2") format("woff2"); - font-weight: 400; - font-style: italic; - font-display: swap; -} -@font-face { - font-family: "Ioskeley Mono"; - src: url("fonts/IoskeleyMono-SemiBold.woff2") format("woff2"); - font-weight: 600; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: "Ioskeley Mono"; - src: url("fonts/IoskeleyMono-Bold.woff2") format("woff2"); - font-weight: 700; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: "Ioskeley Mono"; - src: url("fonts/IoskeleyMono-BoldItalic.woff2") format("woff2"); - font-weight: 700; - font-style: italic; - font-display: swap; -} -@font-face { - font-family: "Ioskeley Mono"; - src: url("fonts/IoskeleyMono-Black.woff2") format("woff2"); - font-weight: 900; - font-style: normal; - font-display: swap; -} - -/* ------- design tokens (LIGHT theme, default) ---------------- - EDIT THIS BLOCK (or the dark block below) to re-skin the sheet. - ------------------------------------------------------------ */ -:root { - /* base palette */ - --bg: #f4f4ef; /* page background */ - --bg-alt: #e9e9e1; /* raised / inset panels */ - --fg: #16160f; /* main text */ - --fg-muted: #5c5c52; /* secondary text */ - --border: #16160f; /* hard rules & outlines */ - --border-soft: #a6a69a; /* faint inner rules */ - - /* accent (used sparingly: focus, selection, marks) */ - --accent: #0047ff; - --accent-fg: #ffffff; - - /* type */ - --font-family: "Ioskeley Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace; - --font-weight-body: 400; - --font-weight-strong: 700; - --font-weight-heading: 700; - --line-height: 1.45; - --scale: 1rem; /* base font size */ - --measure: 92ch; /* page column width */ - --sides: 4ch; /* horizontal page padding */ - - /* spacing (1lh = one line of leaded text) */ - --space: 0.5lh; - --space-lg: 1lh; - - --border-thickness: 2px; - --border-heavy: var(--border-thickness); - --radius: 0; /* squared by design */ - - font-family: var(--font-family); - font-weight: var(--font-weight-body); - font-style: normal; - font-size: var(--scale); - line-height: var(--line-height); - font-variant-numeric: tabular-nums lining-nums; - font-feature-settings: "liga" 1, "calt" 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - color: var(--fg); - background-color: var(--bg); -} - -/* ------- design tokens (DARK theme) -------------------------- - Auto-applied via prefers-color-scheme, or force it by putting - data-theme="dark" / data-theme="light" on the element. - ------------------------------------------------------------ */ -@media (prefers-color-scheme: dark) { - :root:not([data-theme="light"]) { - --bg: #101010; - --bg-alt: #1b1b1b; - --fg: #ecece5; - --fg-muted: #8c8c82; - --border: #c6c6bb; - --border-soft: #3d3d37; - --accent: #7aa2ff; - --accent-fg: #0a0a12; - } -} -:root[data-theme="dark"] { - --bg: #101010; - --bg-alt: #1b1b1b; - --fg: #ecece5; - --fg-muted: #8c8c82; - --border: #c6c6bb; - --border-soft: #3d3d37; - --accent: #7aa2ff; - --accent-fg: #0a0a12; -} - -/* ============================================================ - BACKBONE — ress / resset v5.0.2 (MIT, inline) - ============================================================ */ - -/* resset.dev • v5.0.2 */ - -/* ---- Global selectors ---- */ -html { - box-sizing: border-box; - -webkit-text-size-adjust: 100%; - word-break: normal; - -moz-tab-size: 4; - tab-size: 4; -} -*, -::before, -::after { - background-repeat: no-repeat; - box-sizing: inherit; -} -::before, -::after { - text-decoration: inherit; - vertical-align: inherit; -} -* { - padding: 0; - margin: 0; -} - -/* ---- General elements ---- */ -hr { overflow: visible; height: 0; color: inherit; } -details, main { display: block; } -summary { display: list-item; } -small { font-size: 80%; } -[hidden] { display: none; } -abbr[title] { - border-bottom: none; - text-decoration: underline; - text-decoration: underline dotted; -} -a { background-color: transparent; } -a:active, a:hover { outline-width: 0; } -code, kbd, pre, samp { font-family: monospace, monospace; } -pre { font-size: 1em; } -b, strong { font-weight: bolder; } -sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } -sub { bottom: -0.25em; } -sup { top: -0.5em; } -table { border-color: inherit; text-indent: 0; } -iframe { border-style: none; } - -/* ---- Forms ---- */ -input { border-radius: 0; } -[type='number']::-webkit-inner-spin-button, [type='number']::-webkit-outer-spin-button { height: auto; } -[type='search'] { -webkit-appearance: textfield; outline-offset: -2px; } -[type='search']::-webkit-search-decoration { -webkit-appearance: none; } -textarea { overflow: auto; resize: vertical; } -button, input, optgroup, select, textarea { font: inherit; } -optgroup { font-weight: bold; } -button { overflow: visible; } -button, select { text-transform: none; } -button, [type='button'], [type='reset'], [type='submit'], [role='button'] { cursor: pointer; } -button::-moz-focus-inner, [type='button']::-moz-focus-inner, -[type='reset']::-moz-focus-inner, [type='submit']::-moz-focus-inner { border-style: none; padding: 0; } -button:-moz-focusring, [type='button']::-moz-focus-inner, -[type='reset']::-moz-focus-inner, [type='submit']::-moz-focus-inner { outline: 1px dotted ButtonText; } -button, html [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; } -button, input, select, textarea { background-color: transparent; border-style: none; } -a:focus, button:focus, input:focus, select:focus, textarea:focus { outline-width: 0; } -select { -moz-appearance: none; -webkit-appearance: none; } -select::-ms-expand { display: none; } -select::-ms-value { color: currentColor; } -legend { border: 0; color: inherit; display: table; white-space: normal; } -::-webkit-file-upload-button { -webkit-appearance: button; color: inherit; font: inherit; } -[disabled] { cursor: default; } - -/* ---- Media ---- */ -img { border-style: none; } -progress { vertical-align: baseline; } - -/* ---- Accessibility state ---- */ -[aria-busy='true'] { cursor: progress; } -[aria-controls] { cursor: pointer; } -[aria-disabled='true'] { cursor: default; } - -/* ============================================================ - LAYOUT - ============================================================ */ - -html { - display: flex; - flex-direction: column; - align-items: center; -} - -body { - width: 100%; - min-height: 100vh; - max-width: var(--measure); - padding: var(--space-lg) var(--sides); - margin: 0 auto; - display: flex; - flex-direction: column; -} - -main { flex: 1 1 auto; } - -/* ============================================================ - FLOW UTILITIES - Add one of these single classes to any wrapper to force how - its children are laid out. - - .flow-horizontal : children share a row, wrap when tight. - - .flow-vertical : explicit column flow. Default document - flow is already vertical, so this is a - no-op today; it exists as the symmetric - counterpart and marks intent. - The page column is governed by --measure / --sides; override - those tokens per-page to reclaim horizontal space, e.g. a - dashboard. - ============================================================ */ - -.flow-horizontal, -.flow-vertical { - display: flex; - margin: var(--space) 0; -} - -.flow-vertical { - flex-direction: column; -} - -.flow-horizontal { - flex-flow: row wrap; - align-items: stretch; - gap: var(--space); -} -.flow-horizontal > * { - flex: 1 1 0; - margin-block: 0; -} - -/* ============================================================ - HEADINGS - ============================================================ */ - -h1, h2, h3, h4, h5, h6 { - font-family: inherit; - font-weight: var(--font-weight-heading); - text-transform: uppercase; - letter-spacing: 0.04em; - line-height: 1.2; -} - -h1 { - font-size: clamp(1.7rem, 4.5vw, 2.4rem); - font-weight: 900; - letter-spacing: 0.02em; - margin: var(--space) 0; - padding: 0; - border-bottom: var(--border-heavy) solid var(--border); -} - -h2 { - font-size: 1em; - font-weight: 700; - margin: var(--space-lg) 0; - padding-top: var(--space); - border-top: var(--border-heavy) solid var(--border); -} - -h3 { - font-size: 0.85em; - font-weight: 600; - margin: var(--space) 0; -} - -h4, h5, h6 { - font-size: 1em; - font-weight: 700; - margin: var(--space) 0; -} - -/* ============================================================ - TEXT - ============================================================ */ - -p { margin: var(--space) 0; } - -strong { font-weight: var(--font-weight-strong); } -em { font-style: italic; } -small { font-size: 0.8em; color: var(--fg-muted); } - -a { - color: var(--fg); - text-decoration-thickness: var(--border-thickness); - text-underline-offset: 3px; -} -a:hover { color: var(--accent); } -a:visited { color: var(--fg); } - -mark { - background: var(--accent); - color: var(--accent-fg); - padding: 0 0.2ch; -} - -code { - background: var(--bg-alt); - padding: 0.05em 0.4ch; - font-weight: 500; -} -pre { - border: var(--border-heavy) solid var(--border); - background: var(--bg-alt); - padding: var(--space) 2ch; - margin: var(--space) 0; - overflow-x: auto; - font-size: 0.9em; - line-height: 1.5; -} -pre code { background: none; padding: 0; } - -kbd { - border: var(--border-heavy) solid var(--border); - border-bottom-width: 4px; - background: var(--bg-alt); - padding: 0.05em 0.6ch; - font-size: 0.85em; - font-weight: 500; -} - -blockquote { - border-left: 4px solid var(--border); - padding: 0 var(--space) 0 2ch; - margin: var(--space) 0; -} -blockquote p { margin: var(--space) 0; } -blockquote footer { color: var(--fg-muted); font-size: 0.85em; } - -hr { - border: none; - border-top: 4px double var(--border); - margin: var(--space-lg) 0; -} - -address { font-style: normal; color: var(--fg-muted); margin: var(--space) 0; } - -/* ============================================================ - LISTS - ============================================================ */ - -ul, ol { - margin: var(--space) 0; - padding-left: 3ch; -} -li { margin: 0.15lh 0; } -li::marker { font-weight: 700; } - -ol { - list-style: none; - counter-reset: item; - padding-left: 0; -} -ol > li { - counter-increment: item; -} -ol > li::before { - content: counters(item, ".") ". "; - font-weight: 700; - margin-right: 0.5ch; -} -ol ol, ol ul, ul ol, ul ul { - margin: 0.15lh 0; - padding-left: 3ch; -} - -dl { margin: var(--space) 0; } -dt { font-weight: 700; text-transform: uppercase; font-size: 0.85em; letter-spacing: 0.05em; } -dd { margin: var(--space) 2ch; } - -/* ============================================================ - NAVIGATION - ============================================================ */ - -header { - margin: 0 0 var(--space); -} - -nav { - margin-top: var(--space); - padding-top: var(--space); - border-top: var(--border-heavy) solid var(--border); -} -nav ul { - list-style: none; - display: flex; - flex-wrap: wrap; - gap: 0.4lh 2.5ch; - margin: 0; - padding: 0; -} -nav a { - text-decoration: none; - font-weight: 600; - text-transform: uppercase; - font-size: 0.85em; - letter-spacing: 0.05em; -} -nav a:hover { text-decoration: underline; text-underline-offset: 3px; } - -/* ============================================================ - TABLES - ============================================================ */ - -table { - width: 100%; - border-collapse: collapse; - margin: var(--space) 0; -} -th, td { - border: var(--border-heavy) solid var(--border); - padding: 0.3lh 1ch; - text-align: left; - vertical-align: top; -} -th { - font-weight: 700; - text-transform: uppercase; - font-size: 0.8em; - letter-spacing: 0.06em; -} -caption { - caption-side: bottom; - color: var(--fg-muted); - font-size: 0.8em; - text-align: left; - padding-top: var(--space); -} - -/* ============================================================ - FORMS - ============================================================ */ - -label { - display: block; - font-weight: 600; - text-transform: uppercase; - font-size: 0.8em; - letter-spacing: 0.05em; - margin: var(--space) 0; -} - -fieldset { - border: var(--border-heavy) solid var(--border); - padding: var(--space) 2ch; - margin: var(--space) 0; -} -legend { - background: var(--bg); - padding: 0 1ch; - font-weight: 700; - text-transform: uppercase; - font-size: 0.8em; - letter-spacing: 0.06em; -} - -input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="range"]):not([type="file"]):not([type="color"]), -select, -textarea { - display: block; - width: 100%; - border: var(--border-heavy) solid var(--border); - border-radius: var(--radius); - background: var(--bg); - color: var(--fg); - padding: 0.4lh 1ch; - margin: var(--space) 0; - font: inherit; - -webkit-appearance: none; - appearance: none; -} -:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 2px; -} -input:not([type="checkbox"]):not([type="radio"]):focus, -select:focus, -textarea:focus { - border-color: var(--accent); - outline: none; -} - -select { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23808080'/%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-position: right 1ch center; - background-size: 0.8em; - padding-right: 3ch; -} - -textarea { resize: vertical; min-height: 4lh; } - -::placeholder { color: var(--fg-muted); opacity: 1; } - -button, -input[type="submit"], -input[type="button"], -input[type="reset"], -[role="button"] { - display: inline-block; - border: var(--border-heavy) solid var(--border); - border-radius: var(--radius); - background: var(--bg); - color: var(--fg); - padding: 0.4lh 1.4em; - margin: 0 var(--space) var(--space) 0; - font: inherit; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - line-height: 1; - cursor: pointer; - -webkit-appearance: none; - appearance: none; -} -button:hover, -input[type="submit"]:hover, -input[type="button"]:hover, -input[type="reset"]:hover { - background: var(--fg); - color: var(--bg); -} -button:active, -input[type="submit"]:active, -input[type="button"]:active, -input[type="reset"]:active { - transform: translate(1px, 1px); -} -button:disabled, -input[disabled] { - opacity: 0.5; - cursor: default; -} - -/* flat, squared checkboxes & radios */ -input[type="checkbox"], -input[type="radio"] { - -webkit-appearance: none; - appearance: none; - width: 1.05em; - height: 1.05em; - border: var(--border-heavy) solid var(--border); - border-radius: var(--radius); - background: var(--bg); - display: inline-block; - vertical-align: -0.2em; - margin: 0 0.6ch 0 0; - cursor: pointer; - position: relative; -} -input[type="checkbox"]:checked::before, -input[type="radio"]:checked::before { - content: ""; - position: absolute; - inset: 0; - background: var(--accent); -} -input[type="checkbox"]:focus, -input[type="radio"]:focus { outline: none; border-color: var(--accent); } - -/* ============================================================ - DISCLOSURE (details / summary) - ============================================================ */ - -details { - border: var(--border-heavy) solid var(--border); - margin: var(--space) 0; -} -summary { - cursor: pointer; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.04em; - font-size: 0.85em; - padding: 0.7lh 1.5ch; - list-style: none; - display: flex; - align-items: center; - gap: 1ch; -} -summary::-webkit-details-marker { display: none; } -summary::before { - content: "\25B8"; /* ▸ */ - color: var(--accent); -} -details[open] summary::before { content: "\25BE"; } /* ▾ */ -details[open] summary { border-bottom: var(--border-heavy) solid var(--border); } -details :is(p, pre, ul, ol, table, blockquote):last-child { margin-bottom: calc(0.7 * var(--space)); } -details > :not(summary) { padding-left: 1.5ch; padding-right: 1.5ch; } - -/* ============================================================ - MEDIA / MISC - ============================================================ */ - -figure { margin: var(--space) 0; } -figcaption { - color: var(--fg-muted); - font-size: 0.8em; - margin-top: 0.35lh; -} - -img, video, iframe { - display: block; - max-width: 100%; - height: auto; - border: var(--border-heavy) solid var(--border); -} - -progress { - -webkit-appearance: none; - appearance: none; - width: 100%; - height: 1.2em; - border: var(--border-heavy) solid var(--border); - background: var(--bg); - margin: var(--space) 0; -} -progress::-webkit-progress-bar { background: var(--bg); } -progress::-webkit-progress-value { background: var(--accent); } -progress::-moz-progress-bar { background: var(--accent); } - -footer { - margin-top: var(--space-lg); - padding-top: var(--space); - border-top: var(--border-heavy) solid var(--border); - color: var(--fg-muted); - font-size: 0.85em; -} - -::selection { - background: var(--accent); - color: var(--accent-fg); -} - -/* plain, squared scrollbars */ -* { scrollbar-width: thin; scrollbar-color: var(--border-soft) transparent; } -*::-webkit-scrollbar { width: 12px; height: 12px; background: var(--bg); } -*::-webkit-scrollbar-thumb { - border: var(--border-thickness) solid var(--border); - background: var(--border-soft); -} - -/* accessibility: no animations/transforms on demand */ -@media (prefers-reduced-motion: reduce) { - *, *::before, *::after { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - transform: none !important; - } -} - -/* responsive: tighten the column on small screens */ -@media screen and (max-width: 540px) { - :root { font-size: 0.92rem; } - body { padding: var(--space-lg) 2ch; } -} diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-Black.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-Black.woff2 deleted file mode 100644 index 4491d3c..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-Black.woff2 and /dev/null differ diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-Bold.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-Bold.woff2 deleted file mode 100644 index 98140c0..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-Bold.woff2 and /dev/null differ diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-BoldItalic.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-BoldItalic.woff2 deleted file mode 100644 index 0a48b01..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-BoldItalic.woff2 and /dev/null differ diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-Italic.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-Italic.woff2 deleted file mode 100644 index b46abf1..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-Italic.woff2 and /dev/null differ diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-Medium.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-Medium.woff2 deleted file mode 100644 index 5eee8cb..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-Medium.woff2 and /dev/null differ diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-Regular.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-Regular.woff2 deleted file mode 100644 index a9351a9..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-Regular.woff2 and /dev/null differ diff --git a/data/public/dreccan-mono/fonts/IoskeleyMono-SemiBold.woff2 b/data/public/dreccan-mono/fonts/IoskeleyMono-SemiBold.woff2 deleted file mode 100644 index 4f9816b..0000000 Binary files a/data/public/dreccan-mono/fonts/IoskeleyMono-SemiBold.woff2 and /dev/null differ diff --git a/justfile b/justfile index 531b930..9c24bd9 100644 --- a/justfile +++ b/justfile @@ -7,7 +7,7 @@ dev: build: bun build --compile --minify --target bun --outfile ./target/sepiatones_xyz ./src/index.tsx -deploy: +deploy: build ansible-playbook -i ansible/hosts.ini ansible/deploy.yml test: