brutcss/bb/brut/site.clj

504 lines
21 KiB
Clojure
Raw Normal View History

2022-10-09 18:44:41 +00:00
(ns brut.site
2022-10-06 20:35:31 +00:00
(:require [hiccup2.core :as h]
2022-10-09 21:12:58 +00:00
[babashka.fs :as fs]
2022-10-23 10:10:27 +00:00
[clojure.string :as string]
2022-10-09 21:12:58 +00:00
[babashka.process :refer [process]]))
(defn html-pp [html-str]
2022-10-10 11:51:07 +00:00
(let [xhtml (:out @(process ["tidy" "-i" "-asxhtml" "-quiet" "-utf8"]
{:in html-str
:out :string}))]
(:out @(process ["hxselect" "-c" "body"]
{:in xhtml
:out :string}))))
2022-10-06 20:35:31 +00:00
(def brutalism-img
"h/img/brutalism.webp")
2022-10-03 14:53:52 +00:00
2022-10-06 11:16:25 +00:00
(defn nav [rel-pref]
(let [to (fn [path] (str rel-pref path))]
[:div
[:nav.nav {:tabindex "-1" :onclick "this.focus()"}
[:div.container
[:a.pagename {:href (to "index.html")} "BRUT"]
[:a {:href (to "h/docs.html")} "Docs"]
[:a {:href (to "h/download.html")} "Download"]
[:a {:href "https://gitea.esy.fun/yogsototh/brutcss"} "Code"]]]
[:button.btn.sn.btn-close "×"]]))
2022-10-03 14:53:52 +00:00
(defn footer []
2022-10-07 17:14:08 +00:00
[:footer
[:div.container
[:p "By "
2022-10-03 14:53:52 +00:00
[:a {:href "https://yannesposito.com"}
"Yann Esposito"]]]])
2022-10-06 16:42:43 +00:00
(defn mk-page [rel-pref metas content]
2022-10-06 17:19:14 +00:00
(let [{:keys [title footer? gapless?]
:or {footer? true
gapless? false}} metas]
2022-10-06 16:42:43 +00:00
(h/html
[:head
[:meta {:http-equiv "Content-Type" :content "text/html; charset=UTF-8"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"}]
[:title title]
2022-10-09 09:03:15 +00:00
[:link {:href (str rel-pref "brut.min.css") :rel "stylesheet" :type "text/css"}]]
2022-10-06 17:19:14 +00:00
[(if gapless?
:body.col.gapless
:body.col)
2022-10-06 16:42:43 +00:00
(nav rel-pref)
content
(when footer?
(footer))])))
2022-10-03 14:53:52 +00:00
2022-10-06 11:16:25 +00:00
(defn gen-page [file-path metas content-fn]
2022-10-10 11:51:07 +00:00
(let [depth (or (some-> file-path
2022-10-06 11:16:25 +00:00
fs/parent
fs/components
count)
0)
rel-pref (apply str (repeat depth "../"))
html (mk-page rel-pref metas (content-fn rel-pref metas))]
(println "Generates: " file-path)
(spit file-path html)))
2022-10-06 16:42:43 +00:00
(defn mk-index [rel-pref _metas]
2022-10-06 11:16:25 +00:00
(let [to (fn [path] (str rel-pref path))
hero [:div.hero.bg-neutral
2022-10-06 17:19:14 +00:00
[:div.row.middle
2022-10-06 20:35:31 +00:00
[:img.c3.no-grow {:src (to brutalism-img) :alt "brutalism"}]
2022-10-06 17:19:14 +00:00
[:div.col.block.c6
2022-10-03 21:28:51 +00:00
[:h1.title "BRUT"]
[:h4 "A Brutalist and Minimalist CSS Framework"]
[:p (str "This CSS framework is ideal to be used for admin interface where you"
"want to make it clear, this is not for any kind of end user but only"
"advanced technical people.")]]
2022-10-06 20:35:31 +00:00
[:img.c3.no-grow {:src (to brutalism-img) :alt "brutalism"}]
2022-10-06 17:19:14 +00:00
]]
2022-10-03 21:28:51 +00:00
cards [:div.row
2022-10-06 17:19:14 +00:00
[:div.col.card
[:h3 "Docs"]
[:p "Docs"]
[:p "Docs"]
2022-10-23 10:10:27 +00:00
[:a.btn.big.push {:href (to "h/docs.html")}
2022-10-06 17:19:14 +00:00
"Docs"]]
[:div.col.card
[:h3 "Download"]
[:div.block
[:p "Download BRUT"]]
2022-10-23 10:10:27 +00:00
[:a.btn.warn.big.push {:href (to "h/download.html")}
2022-10-06 17:19:14 +00:00
"Download"]]]]
[:div.container.col
hero
cards]))
2022-10-06 11:16:25 +00:00
2022-10-06 16:42:43 +00:00
(defn mk-download [rel-pref _metas]
2022-10-06 11:16:25 +00:00
(let [to (fn [path] (str rel-pref path))]
[:div.central.fill
2022-10-06 20:35:31 +00:00
{:style (str "background:url('" (to brutalism-img) "')")}
2022-10-06 11:16:25 +00:00
[:a.btn.warn.huge {:href (to "brut.min.css")}
2022-10-06 20:35:31 +00:00
"Download BRUT"]]))
2022-10-08 14:19:40 +00:00
(defn to-pre [hc]
(h/html {:escape-strings? true}
[:pre (-> (str (h/html hc))
2022-10-09 21:12:58 +00:00
html-pp)]))
2022-10-08 14:19:40 +00:00
2022-10-06 20:35:31 +00:00
(defn mk-docs [rel-pref _metas]
(let [to (fn [path] (str rel-pref path))
2022-10-10 11:51:07 +00:00
txt [:div {:id "text"}
[:h1 "title in h1"]
[:p "Some text in <p> with different styles; "
[:b "bold"]
", " [:strong "strong"]
", " [:i "italic"]
", " [:em "emphasis"]
2022-10-23 11:04:33 +00:00
", " [:code "code"] ". "
"If you really want something to be extremly visible, "
[:strong.hl "use the class "[:code.hl "hl"]]
"."]
[:p "Links will looks like this into text: "
[:a {:href "#"} "This is a link inside a paragraph."]]
2022-10-10 11:51:07 +00:00
[:p "The text should be " [:strong.hl "very dense"] " on purpose."
" Forget your lessons about nice space in design here."
" The goal of this design is to produce " [:em "professional"] " UI applications."
" So no time to make it breathes."
" We want to make it compact and efficient."]
[:p "Note we still try to keep a coherent and nice vertical rythm."]
[:blockquote
[:p "Here is some blockquote."
" This can give you an idea about the look and feel for them."]]]
doc [:div {:id "doc"}
[:p "Remark if you need to present a long text to read you can still use the class " [:code "doc"] "."
" Take a look at the next paragraph for example: "]
[:div.doc
[:p
"Lorem ipsum with pretty Lorem ipsum dolor sit amet consectetur adipiscing elit,"
" urna consequat felis vehicula class ultricies mollis dictumst, aenean non a in donec nulla."
" Phasellus ante pellentesque erat cum risus consequat imperdiet aliquam, integer"
" placerat et turpis mi eros nec lobortis taciti, vehicula nisl litora tellus ligula porttitor metus."]
[:p
"Vivamus integer non suscipit taciti mus etiam at primis tempor sagittis sit,"
" euismod libero facilisi aptent elementum felis blandit cursus gravida sociis"
" erat ante, eleifend lectus nullam dapibus netus feugiat curae curabitur est ad."
" Massa curae fringilla porttitor quam sollicitudin iaculis aptent leo ligula"
" euismod dictumst, orci penatibus mauris eros etiam praesent erat volutpat"
" posuere hac."
" Metus fringilla nec ullamcorper odio aliquam lacinia conubia mauris tempor,"
" etiam ultricies proin quisque lectus sociis id tristique, integer phasellus"
2022-10-10 12:43:47 +00:00
" taciti pretium adipiscing tortor sagittis ligula."]]
[:p "The " [:code "doc"] " class ensure the width of the text is not too wide and use a very legible font."]]
2022-10-10 11:51:07 +00:00
itemize [:div {:id "itemize"}
[:h2 "itemization"]
[:h3 "ul"]
[:ul
[:li "item 1"]
[:li "item 2"]
[:li "item 3; with a very long text that should wrap to the next line in any browser."
" We'll see that the wrapped text should be aligned with the text of the other items."
" This is due to the " [:code "list-style-position: outside"] "."
]
[:li "item 4"]]
[:h3 "ol"]
[:ol
[:li "item 1"]
[:li "item 2"]
[:li "item 3"]
[:li "item 4"]]]
2022-10-10 12:43:47 +00:00
headings [:div
[:h3 "headings"]
[:p "By default there is some space before and after any heading:"]
[:h1 "h1"]
[:h2 "h2"]
[:h3 "h3"]
[:h4 "h4"]
[:h5 "h5"]
[:h6 "h6"]
[:h3 "tight headings"]
[:p "You can remove the space by using the class "
[:code "tight"]" to the heading:"]
[:h1 {:class "tight"} "h1 tight"]
[:h2 {:class "tight"} "h2 tight"]
[:h3 {:class "tight"} "h3 tight"]
[:h4 {:class "tight"} "h4 tight"]
[:h5 {:class "tight"} "h5 tight"]
[:h6 {:class "tight"} "h6 tight"]]
2022-10-10 11:51:07 +00:00
textual-section {:title "Textual content"
2022-10-10 12:43:47 +00:00
:cards [txt doc headings itemize]}
2022-10-08 14:19:40 +00:00
2022-10-06 20:35:31 +00:00
images [:div {:id "images"}
[:h1 "Images"]
[:h2 "Inside a grid"]
[:div.row
[:div.card
[:p "Inside a card"]
[:img {:src (to brutalism-img)}]]
[:div.block
[:p "In a block"]
2022-10-23 10:10:27 +00:00
[:img {:src (to brutalism-img)}]]
[:div
[:span "Directly in the column"]
[:img {:src (to brutalism-img)}]]
]]
2022-10-10 11:51:07 +00:00
images-section {:title "Images"
:cards [images]}
2022-10-10 15:03:30 +00:00
text-buttons [:div#text-buttons
2022-10-24 11:11:47 +00:00
[:h3 "Textual buttons"]
2022-10-10 15:03:30 +00:00
[:a.tb "tb"]
[:a.tb.info "tb info"]
[:a.tb.ok "tb ok"]
[:a.tb.warn "tb warn"]
[:a.tb.err "tb err"]
[:a.tb.fatal "tb fatal"]]
text-buttons-sizes [:div#text-buttons-sizes
2022-10-24 11:11:47 +00:00
[:h3 "Textual Buttons Sizes"]
[:div.block
"Some text: " [:a {:class "tb sm info"} "small button"] [:br]
"Some text: " [:a {:class "tb ok"} "normal ok"] [:br]
"Some text: " [:a {:class "tb big warn"} "big warn"] [:br]
"Some text: " [:a {:class "tb huge err"} "huge err"]]]
2022-10-09 09:03:15 +00:00
buttons [:div {:id "buttons"}
[:h2 "Classic"]
[:a {:class "btn"} "btn"]
[:a {:class "btn info"} "btn info"]
[:a {:class "btn ok"} "btn ok"]
[:a {:class "btn warn"} "btn warn"]
[:a {:class "btn err"} "btn err"]
[:a {:class "btn fatal"} "btn fatal"]
[:pre {:class "block"} "&lt;a class=&quot;btn btn-b&quot;&gt;btn-b&lt;/a&gt;"]
[:h2 "Sizes"]
[:a {:class "btn sm"} "btn sm"]
[:a {:class "btn info"} "btn info"]
[:a {:class "btn big warn"} "btn big warn"]
[:a {:class "btn huge err"} "btn huge err"]
[:pre {:class "block"} "&lt;a class=&quot;btn sm info&quot;&gt;btn sm info&lt;/a&gt;"]
[:div {:class "row"}
[:div {:class "col c4 card"}
[:h3 "Standardized Width "
[:code "btn std"]]
[:div {:class "col"}
[:a {:class "btn std"} "btn std"]
[:a {:class "btn std info"} "btn std info"]
[:a {:class "btn std ok"} "btn std ok"]
[:a {:class "btn std warn"} "btn std warn"]
[:a {:class "btn std err"} "btn std err"]
[:a {:class "btn std fatal"} "btn std fatal"]]]
[:div {:class "col c4 card"}
[:h3 "Big"]
[:div {:class "col"}
[:a {:class "btn std big "} "btn std"]
[:a {:class "btn std big info"} "btn std info"]
[:a {:class "btn std big ok"} "btn std ok"]
[:a {:class "btn std big warn"} "btn std warn"]]]
[:div {:class "col c4 card"}
[:h3 "Huge"]
[:div {:class "col"}
[:a {:class "btn std huge"} "btn std"]
[:a {:class "btn std huge info"} "btn std info"]
[:a {:class "btn std huge ok"} "btn std ok"]]]]]
2022-10-24 11:11:47 +00:00
tags [:div {:id "tags"}
[:h2 "Tags"]
[:ul
[:li "item-1" [:span.tag "tag"]]
[:li "item-2" [:span.tag.info "info"]]
[:li "item-3" [:span.tag.ok "ok"]]
[:li "item-4" [:span.tag.warn "warn"]]
[:li "item-5" [:span.tag.err "err"]]
[:li "item-6" [:span.tag.fatal "fatal"]]]]
tags-listed [:div {:id "tags-inline"}
[:h2 "Inline Tags"]
[:span.tag "tag"]
[:span.tag.hl "tag hl"]
[:span.tag.info "info"]
[:span.tag.ok "ok"]
[:span.tag.warn "warn"]
[:span.tag.err "err"]
[:span.tag.fatal "fatal"]
]
2022-10-10 11:51:07 +00:00
buttons-section {:title "Buttons"
2022-10-24 11:11:47 +00:00
:cards [tags tags-listed
text-buttons text-buttons-sizes buttons]}
2022-10-10 12:43:47 +00:00
messages [:div {:class "row"}
[:div {:class "col c6 gapless"}
[:h2 "Basic Messages"]
[:br]
[:div {:class "msg"}
[:strong "Normal Message"]
" This is a normal message with " [:code "msg"] "."]
[:div {:class "msg info"}
[:strong
2022-10-23 10:10:27 +00:00
[:i.ico.big "☞"]" Info"]
2022-10-10 12:43:47 +00:00
" This is done by adding "
[:code "info"]" to the class.\n"]
[:div {:class "msg ok"}
[:strong
2022-10-23 10:10:27 +00:00
[:i.ico.big "☑"]" OK"]
2022-10-10 12:43:47 +00:00
" This is done by adding "
[:code "ok"]" to the class.\n"]
[:div {:class "msg warn"}
[:strong
2022-10-23 10:10:27 +00:00
[:i.ico.big "☣"]" Warning"]
2022-10-10 12:43:47 +00:00
" This is done by adding "
[:code "warn"]" to the class.\n"]
[:div {:class "msg err"}
[:strong
2022-10-23 10:10:27 +00:00
[:i.ico.big "☒"]" Error"]
2022-10-10 12:43:47 +00:00
" This is done by adding "
[:code "err"]" to the class.\n"]
[:div {:class "msg fatal"}
[:strong
2022-10-23 10:10:27 +00:00
[:i.ico.big "☠"]" Fatal"]
2022-10-10 12:43:47 +00:00
" This is done by adding "
[:code "fatal"]" to the class.\n"]
[:div {:class "msg hl"}
2022-10-10 12:43:47 +00:00
[:strong
[:i.ico.big "☞"] "Highlighted"]
2022-10-11 12:50:00 +00:00
" This is done by adding "
[:code "hl"]" to the class.\n"]]]
2022-10-10 12:43:47 +00:00
messages-section {:title "Messages"
:cards [messages]}
forms [:div
2022-10-24 15:05:36 +00:00
[:label {:for "example1"}]
[:input#example1 {:type "text" :placeholder "text input"}]
[:br]
[:br]
[:label {:for "textarea1"}]
[:textarea#textarea1 {:cols "30" :rows "3", :placeholder "textarea"}]
[:br]
[:br]
[:div.form-block
[:span {:class "addon info"} "$"]
[:input {:type "text" :placeholder "with addon"}]]
2022-10-07 17:14:08 +00:00
[:br]
[:br]
[:div {:class "msg"}
2022-10-10 12:43:47 +00:00
[:strong "Be careful with addons!"]
" If you do not want a space between the addon and the input make sure "
"that there is no space between the "
[:code "<span>"] " and "
[:code "<input>"]" tags. Example: "
[:pre "... </span>" [:span.hl " "] "<input ..."]
2022-10-24 15:05:36 +00:00
[:div.form-block
[:span {:class "addon"} "$"] " "
[:input {:type "text", :class "smooth"}]]
2022-10-10 12:43:47 +00:00
[:pre "... </span><input ..."]
2022-10-24 15:05:36 +00:00
[:div.form-block
[:span {:class "addon"} "$"]
[:input {:type "text", :class "smooth"}]]]]
2022-10-10 12:43:47 +00:00
forms-section {:title "Forms"
:cards [forms]}
navbar [:div {:class "navbar"}
[:nav {:class "nav", :tabindex "-1", :onclick "this.focus()"}
[:div {:class "container"}
[:a {:class "pagename current", :href "#"} "BRUT"]
[:a {:href "#"} "One"]
[:a {:href "#"} "Two"]
[:a {:href "#"} "Three"]
[:a {:href "#"} "Four"]]]
[:button {:class "btn-close btn sm"} "×"]]
navbar-section {:title "Navbar"
2022-10-23 11:04:33 +00:00
:cards [navbar]}
footer [:footer
[:div.container
[:p "Made by " [:a {:href "https://yannesposito.com"} "Yann Esposito"]]]]
footer-section {:title "Footer"
:cards [footer]}
2022-10-10 12:43:47 +00:00
table [:table {:class "table"}
[:thead
[:tr
[:th "#"]
[:th "Widgets Sold"]
[:th "Revenue (£)"]
[:th "Profit (£)"]]]
[:tbody
[:tr
[:td "1"]
[:td "5"]
[:td "10"]
[:td "2"]]
[:tr
[:td "2"]
[:td "10"]
[:td "20"]
[:td "4"]]
[:tr
[:td "3"]
[:td "500"]
[:td "1000"]
[:td "200"]]]]
tables-section {:title "Tables"
:cards [table]}
basic-icons [:div.col.start
[:h4 "Safe"]
2022-10-23 10:10:27 +00:00
[:i {:class "ico block big"} "☎ ♂ ♀ ⓧ © § ® ⇦ ⇧ ⇨ ⇩♠ ♣ ♥ ♦ ♪ ♛ ♜ ♝ ♞ ♟☜ ☞ ♨ ♭ ♯ ¥£ ¢❊ ฿ ๏ ※ ₧ ₨ ₪ € №\n"]
2022-10-11 12:50:00 +00:00
[:div {:class "msg push"}
2022-10-23 10:10:27 +00:00
[:p
"The \"Safe\" icons should work almost everywhere."]
2022-10-23 10:10:27 +00:00
[:p
(mapcat (fn [w i]
2022-10-23 11:04:33 +00:00
[ [:span w " "] [:i.ico i] " "])
2022-10-23 10:10:27 +00:00
(string/split
(str "Inserting in the middle of some text to check the size."
" Now this should give an idea about the size relatively "
"to the text. Hmmm this is quite long and boring to write"
" text in between like that!")
#" ")
(string/split "☎♂♀ⓧ©§®⇦⇧⇨⇩♠♣♥♦♪♛♜♝♞♟☜☞♨♭♯¥£¢❊฿๏※₧₨₪€№" #""))
]]]
2022-10-10 12:43:47 +00:00
full-icons [:div.col.start
[:h4 "Total Set"]
2022-10-23 10:10:27 +00:00
[:i {:class "ico block big"}
2022-10-10 12:43:47 +00:00
"✉ ✰ ☁ ✈ ☑ ☒ ✆ ☀ ☮ ☢ ☠ ☣ ⌂ ℗ ☺ ☻ ☼ ∡ ∿ ⊝ ⊘ ⁂ ☤ ♫ ☄ ✎ ☟ ☝ ☹ ☭ ☚ ☛ ✌ 〠 ☃ ♮ ☂ ☸ ✍ ☯ ✂ ₩ ◍ ۩\n"]
[:div.msg "Just a bunch of a few more unicode icons."]]
2022-10-10 12:43:47 +00:00
icons-section {:title "icons"
:cards [basic-icons full-icons]}
2022-10-23 11:04:33 +00:00
grid
[:div
[:h3 "With default gap"]
[:div
(for [i (range 12 -1 -1)]
(let [cl (str "c" i)
co-cl (str "c" (- 12 i))]
[:div.row
(when (> i 0)
[:div.bg-neutral {:class cl} cl])
(when (> (- 12 i) 0)
[:div.y {:class co-cl} co-cl])]))]]
grid-gapless
[:div
[:h3 "Gapless"]
[:div
(for [i (range 12 -1 -1)]
(let [cl (str "c" i)
co-cl (str "c" (- 12 i))]
[:div.row.gapless
(when (> i 0)
[:div.bg-neutral {:class cl} cl])
(when (> (- 12 i) 0)
[:div.y {:class co-cl} co-cl])]))]]
grid-3col
[:div
[:h3 "3 columns"]
[:div
(for [i (range 11 0 -1)
j (range (- 11 i) -1 -1)]
(let [k (- 12 i j)
cli (str "c" i)
clj (str "c" j)
clk (str "c" k)]
(if (= j 0)
[:br]
[:div.row
(when (> j 0)
[:div.b {:class clj} clj])
(when (> i 0)
[:div.bg-neutral {:class cli} cli])
(when (> k 0)
[:div.r {:class clk} clk])
])))]]
2022-10-10 12:43:47 +00:00
grid-section {:title "Grid"
2022-10-23 11:04:33 +00:00
:cards [grid grid-gapless grid-3col]}]
2022-10-06 20:35:31 +00:00
[:div.container
2022-10-10 12:43:47 +00:00
(for [{:keys [title cards]} [textual-section
grid-section
images-section
icons-section
forms-section
tables-section
buttons-section
messages-section
2022-10-23 11:04:33 +00:00
navbar-section
footer-section]]
2022-10-10 12:43:47 +00:00
[:div.col
2022-10-23 10:10:27 +00:00
[:h2 {:id title}
[:a {:href (str "#" title)} [:i.ico "§"]] " "
title]
2022-10-10 12:43:47 +00:00
(for [[c1 c2] (partition 2 2 nil cards)]
[:div.row
[:div.card.c6
c1
2022-10-10 11:51:07 +00:00
[:details
[:summary "code"]
2022-10-10 12:43:47 +00:00
(to-pre c1)]]
(when c2
[:div.card.c6
c2
[:details
[:summary "code"]
(to-pre c2)]])])])]))
2022-10-03 21:28:51 +00:00
2022-10-03 14:53:52 +00:00
(defn -main [& _args]
2022-10-06 16:42:43 +00:00
(gen-page "index.html"
{:title "BRUT"}
mk-index)
(gen-page "h/download.html"
{:title "BRUT - download"
2022-10-06 17:19:14 +00:00
:footer? false
:gapless? true}
2022-10-06 20:35:31 +00:00
mk-download)
2022-10-10 12:43:47 +00:00
(gen-page "h/docs.html"
2022-10-06 20:35:31 +00:00
{:title "BRUT - documentation"}
mk-docs)
)