feat: added and customized AY navbar

This commit is contained in:
Nick 2024-12-11 02:38:42 -06:00
parent 0569a063bb
commit a7000d6302
53 changed files with 2517 additions and 872 deletions

607
Navbar.elm Executable file
View file

@ -0,0 +1,607 @@
module Layouts.Navbar exposing (Model, Msg, Props, layout)
import Config.Data.Identity exposing (..)
import Config.Format.Format
exposing
( paragraphFontSize
, paragraphSpacing
)
import Config.Style.Colour exposing (colourTheme)
import Config.Style.Fonts exposing (spartanFont)
import Config.Style.Glow exposing (glowDeepDarkGreyNavbar)
import Config.Style.Svgs
exposing
( contact
, debate
, discord
, donate
, gitlab
, home
, hyperBlog
, interviews
, mastodon
, nutriDex
, services
, twitter
, upRootLarge
, upRootMedium
, upRootSmall
)
import Config.Style.Transitions
exposing
( hoverFontLightOrange
, transitionStyleMedium
)
import Effect exposing (Effect)
import Element as E exposing (..)
import Element.Background as B
import Element.Border as D
import Element.Events as Events
import Element.Font as F
import Element.Region exposing (description)
import Html exposing (Html)
import Html.Attributes as H
exposing
( class
, style
)
import Layout exposing (Layout)
import Route exposing (Route)
import Route.Path as Path
import Shared
import View exposing (View)
type alias Props =
{}
layout : Props -> Shared.Model -> Route () -> Layout () Model Msg contentMsg
layout props shared route =
Layout.new
{ init = init
, update = update
, view =
\layoutArgs ->
view route
shared
{ props = props
, content = layoutArgs.content
, model = layoutArgs.model
, toContentMsg = layoutArgs.toContentMsg
}
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init _ =
( {}
, Effect.none
)
-- UPDATE
type Msg
= ReplaceMe
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
ReplaceMe ->
( model
, Effect.none
)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view :
Route ()
-> Shared.Model
->
{ content : View contentMsg
, model : Model
, toContentMsg : Msg -> contentMsg
, props : Props
}
-> View contentMsg
view route shared { content, model, toContentMsg, props } =
{ title = "uRN :: " ++ content.title
, attributes = [ F.family [ spartanFont ] ]
, element = navbarContainer route shared.device content.element
}
navbarContainer : Route () -> Device -> Element msg -> Element msg
navbarContainer route device content =
row
[ E.width fill
, height fill
, B.color colourTheme.backgroundDarkGrey
, E.height E.fill
]
[ column
[ htmlAttribute (H.style "position" "fixed")
, htmlAttribute (H.style "left" "0")
, htmlAttribute (H.style "top" "0")
, htmlAttribute (H.style "height" "100vh")
, htmlAttribute (H.style "z-index" "10")
, htmlAttribute (H.style "transform-style" "preserve-3d")
, D.widthEach { top = 0, bottom = 0, left = 0, right = 3 }
, D.color colourTheme.textDarkOrange
, B.color colourTheme.backgroundDarkGrey
, glowDeepDarkGreyNavbar
, spacing 3
]
(case ( device.class, device.orientation ) of
( Phone, Portrait ) ->
[ mobileIconMaker, mobileNavbar, mobileFooterIcons ]
( Phone, Landscape ) ->
[ mobileIconMaker, mobileNavbar, mobileFooterIcons ]
( Tablet, Portrait ) ->
[ mobileIconMaker, mobileNavbar, mobileFooterIcons ]
_ ->
[ desktopIconMaker, desktopNavbar route, desktopFooterIcons ]
)
, el
[ E.width fill
, height fill
, paddingEach
{ top = 0
, right = 0
, bottom = 0
, left =
case ( device.class, device.orientation ) of
( Phone, _ ) ->
mobileBarWidth
( Tablet, Portrait ) ->
mobileBarWidth
_ ->
desktopBarWidth
}
]
content
]
desktopBarWidth : Int
desktopBarWidth =
200
mobileBarWidth : Int
mobileBarWidth =
50
localhostUrl : String
localhostUrl =
url
desktopNavbar : Route () -> Element msg
desktopNavbar route =
column
[ alignLeft
, height fill
, F.color colourTheme.textLightGrey
, scrollbarY
]
[ column
[ padding 20, alignTop, alignLeft ]
[ column
[ F.bold
, F.color colourTheme.textLightGrey
, F.size 17
, spacing 10
, paddingEach
{ top = 0
, right = 0
, bottom = 0
, left = 10
}
]
(List.map2 (desktopButtonMaker route)
pageList
iconList
)
]
]
desktopIconMaker : Element msg
desktopIconMaker =
column
[ centerX
, E.width <| px desktopBarWidth
]
[ row
[ centerX
, spacing 2
, E.width <| px 140
, centerX
, paddingEach
{ top = 20
, right = 0
, bottom = 20
, left = 0
}
]
[ html upRootMedium
]
, el
[ E.width <| px 140
, alignTop
, centerX
, D.widthEach
{ bottom = 1
, top = 0
, left = 0
, right = 0
}
, D.color colourTheme.textDarkGrey
]
none
]
mobileIconMaker : Element msg
mobileIconMaker =
column
[ centerX
, E.width <| px mobileBarWidth
]
[ row
[ centerX
, spacing 2
, E.width <| px 35
, centerX
, paddingEach
{ top = 10
, right = 0
, bottom = 10
, left = 0
}
]
[ html upRootSmall
]
, el
[ E.width <| px 20
, alignTop
, centerX
, D.widthEach
{ bottom = 1
, top = 0
, left = 0
, right = 0
}
, D.color colourTheme.textDarkGrey
]
none
]
mobileNavbar : Element msg
mobileNavbar =
column
[ height fill
, E.width fill
, F.color colourTheme.textLightGrey
, scrollbarY
]
[ column
[ padding 5
, alignTop
, centerX
]
[ column
[ spacing 8
, centerX
]
(List.map2 mobileButtonMaker
pageList
iconList
)
]
]
desktopBackground : Element msg -> Element msg
desktopBackground =
el
[ E.width fill
, height fill
, paddingEach
{ top = 0
, right = 0
, bottom = 0
, left = desktopBarWidth
}
]
mobileBackground : Element msg -> Element msg
mobileBackground =
el
[ E.width fill
, height fill
, paddingEach
{ top = 0
, right = 0
, bottom = 0
, left = mobileBarWidth
}
]
desktopButtonMaker : Route () -> String -> Html msg -> Element msg
desktopButtonMaker route name icon =
link
[ E.width fill ]
{ url =
if name == "Home" then
localhostUrl
else
localhostUrl ++ String.toLower name
, label =
row
[ spacing 0, height <| px 30 ]
[ el
[ E.width <| px 35
, paddingEach
{ top = 0
, right = 10
, bottom = 0
, left = 0
}
]
<|
html icon
, el
((if route.path == Path.Hyperblog then
F.color colourTheme.textLightOrange
else
F.color colourTheme.textLightGrey
)
:: [ transitionStyleMedium
, alignBottom
]
)
<|
text <|
String.toUpper name
]
}
mobileButtonMaker : String -> Html msg -> Element msg
mobileButtonMaker name icon =
link
[]
{ url = localhostUrl ++ String.toLower name
, label =
row
[ spacing 10 ]
[ column
[ E.width <| px 20
]
[ html icon
]
]
}
iconList : List (Html msg)
iconList =
[ home
, services
, hyperBlog
, debate
, nutriDex
, interviews
, donate
, contact
]
pageList : List String
pageList =
[ "Home"
, "Services"
, "HyperBlog"
, "Debate"
, "NutriDex"
, "Interviews"
, "Donate"
, "Contact"
]
desktopFooterIcons : Element msg
desktopFooterIcons =
column
[ E.width <| px 140
, alignTop
, centerX
, D.widthEach
{ bottom = 0
, top = 1
, left = 0
, right = 0
}
, D.color colourTheme.textDarkGrey
]
[ row
[ alignBottom
, E.width fill
, centerX
]
[ row
[ centerX
, centerY
, E.width fill
, E.height fill
, spacing 20
, paddingEach
{ top = 25
, bottom = 25
, left = 0
, right = 0
}
]
(List.map2
desktopFooterImageMaker
[ gitlabDetails
, twitterDetails
, mastodonDetails
, discordDetails
]
footerIconList
)
]
]
mobileFooterIcons : Element msg
mobileFooterIcons =
column
[ E.width <| px 20
, alignTop
, centerX
, D.widthEach
{ bottom = 0
, top = 1
, left = 0
, right = 0
}
, D.color colourTheme.textDarkGrey
]
[ column
[ alignBottom
, E.width fill
]
[ column
[ centerX
, centerY
, E.width fill
, E.height fill
, spacing 10
, paddingEach
{ top = 10
, bottom = 10
, left = 0
, right = 0
}
]
(List.map2
mobileFooterImageMaker
[ gitlabDetails
, twitterDetails
, mastodonDetails
, discordDetails
]
footerIconList
)
]
]
desktopFooterImageMaker :
{ name : String
, url : String
}
-> Html msg
-> Element msg
desktopFooterImageMaker config icon =
column [ centerX ]
[ newTabLink []
{ url = config.url
, label =
row
[ E.width <| px 20 ]
[ html icon
]
}
]
mobileFooterImageMaker :
{ name : String
, url : String
}
-> Html msg
-> Element msg
mobileFooterImageMaker config icon =
column [ centerX ]
[ newTabLink []
{ url = config.url
, label =
row
[ E.width <| px 15 ]
[ html icon
]
}
]
gitlabDetails : { name : String, url : String }
gitlabDetails =
{ name = "gitlab"
, url = "https://gitlab.com/upRootNutrition/website"
}
twitterDetails : { name : String, url : String }
twitterDetails =
{ name = "twitter"
, url = "https://x.com/upRootNutrition"
}
mastodonDetails : { name : String, url : String }
mastodonDetails =
{ name = "mastodon"
, url = "https://social.uprootnutrition.com/@nick"
}
discordDetails : { name : String, url : String }
discordDetails =
{ name = "discord"
, url = "https://discord.com/invite/YrcEvgRTqy"
}
footerIconList =
[ gitlab
, twitter
, mastodon
, discord
]

View file

@ -17,6 +17,7 @@
"elm-community/list-extra": "8.7.0",
"elm-community/maybe-extra": "5.3.0",
"hecrj/html-parser": "2.4.0",
"juliusl/elm-ui-hexcolor": "1.0.0",
"mdgriffith/elm-ui": "1.1.8"
},
"indirect": {

View file

@ -0,0 +1,115 @@
module Config.Data.Language exposing (..)
{-| Types for facilitating multilingual functionality.
-}
import Element
{-| A list of all currently supported languages. DeepL <https://www.deepl.com/translator> seems to
have the best translations, so we're just using those. Arabic will need some custom work though
since it runs right to left. It will be nice to expand this list over time as DeepL adds support
for more languages. Eventually it could be nice to host some local AI to do translation so we can
reduce lines of code by writing all text only once in English then automatically generating
translations.
-}
type Language
= -- Arabic
Bulgarian
| Chinese
| Czech
| Danish
| Dutch
| English
| Estonian
| Finnish
| French
| German
| Greek
| Hungarian
| Indonesian
| Italian
| Japanese
| Korean
| Latvian
| Lithuanian
| Norwegian
| Polish
| Portuguese
| Romanian
| Russian
| Slovak
| Slovenian
| Spanish
| Swedish
| Turkish
| Ukranian
-- type alias MultilingualText =
-- { bulgarian : String
-- , chinese : String
-- , czech : String
-- , danish : String
-- , dutch : String
-- , english : String
-- , estonian : String
-- , finnish : String
-- , french : String
-- , german : String
-- , greek : String
-- , hungarian : String
-- , indonesian : String
-- , italian : String
-- , japanese : String
-- , korean : String
-- , latvian : String
-- , lithuanian : String
-- , norwegian : String
-- , polish : String
-- , portuguese : String
-- , romanian : String
-- , russian : String
-- , slovak : String
-- , slovenian : String
-- , spanish : String
-- , swedish : String
-- , turkish : String
-- , ukranian : String
-- }
{-| We need a type that returns a different element based on which language is selected.
-}
type alias MultilingualTextElement msg =
{ bulgarian : Element.Element msg
, chinese : Element.Element msg
, czech : Element.Element msg
, danish : Element.Element msg
, dutch : Element.Element msg
, english : Element.Element msg
, estonian : Element.Element msg
, finnish : Element.Element msg
, french : Element.Element msg
, german : Element.Element msg
, greek : Element.Element msg
, hungarian : Element.Element msg
, indonesian : Element.Element msg
, italian : Element.Element msg
, japanese : Element.Element msg
, korean : Element.Element msg
, latvian : Element.Element msg
, lithuanian : Element.Element msg
, norwegian : Element.Element msg
, polish : Element.Element msg
, portuguese : Element.Element msg
, romanian : Element.Element msg
, russian : Element.Element msg
, slovak : Element.Element msg
, slovenian : Element.Element msg
, spanish : Element.Element msg
, swedish : Element.Element msg
, turkish : Element.Element msg
, ukranian : Element.Element msg
}

View file

@ -0,0 +1,59 @@
module Config.Data.LocalPath exposing (..)module Config.Data.LocalPath exposing (..)
import Route
import Route.Path as Path
isLocalPath : Route.Path -> Bool
isLocalPath path =
case Route.Path.current path of
Route.Path.Home_ ->
True
Route.Path.Contact ->
True
Route.Path.Debate ->
True
Route.Path.Debate_Arguments ->
True
Route.Path.Debate_Cucklist ->
True
Route.Path.Debate_Gibberish ->
True
Route.Path.Donate ->
True
Route.Path.Hyperblog ->
True
Route.Path.Interviews ->
True
Route.Path.Nutridex ->
True
Route.Path.Services ->
True
Route.Path.Services_Analysis ->
True
Route.Path.Services_Coaching ->
True
Route.Path.Services_Elm ->
True
Route.Path.Services_Nix ->
True
Route.Path.Services_Nutrition ->
True
_ ->
False

View file

@ -29,6 +29,7 @@ import Element.Background as B
import Element.Border as D
import Element.Font as F
import Html.Attributes as H
import Route.Path as Path
topLevelBox =
@ -129,11 +130,37 @@ cardImageMaker image urlLink =
imageTransitionStyle
[ if
urlLink
== (url ++ formatName pageNames.pageArguments)
== Path.toString Path.Home_
|| urlLink
== (url ++ formatName pageNames.pageCucks)
== Path.toString Path.Contact
|| urlLink
== (url ++ formatName pageNames.pageGibberish)
== Path.toString Path.Debate
|| urlLink
== Path.toString Path.Debate_Arguments
|| urlLink
== Path.toString Path.Debate_Cucklist
|| urlLink
== Path.toString Path.Debate_Gibberish
|| urlLink
== Path.toString Path.Donate
|| urlLink
== Path.toString Path.Hyperblog
|| urlLink
== Path.toString Path.Interviews
|| urlLink
== Path.toString Path.Nutridex
|| urlLink
== Path.toString Path.Services
|| urlLink
== Path.toString Path.Services_Analysis
|| urlLink
== Path.toString Path.Services_Coaching
|| urlLink
== Path.toString Path.Services_Elm
|| urlLink
== Path.toString Path.Services_Nix
|| urlLink
== Path.toString Path.Services_Nutrition
then
link []
{ url = urlLink

0
frontend/src/Config/Helpers/Converters.elm Normal file → Executable file
View file

View file

@ -28,94 +28,6 @@ import Element.Font as F
import Html.Attributes as H exposing (style)
contactMaker : Contact -> Element msg
contactMaker contact =
row
topLevelBox
[ cardMaker
[ cardTitleMaker (contactTitle contact)
, cardFormatter
[ cardContentSpacing
[ column
fieldSpacer
[ linkMaker contact
, descriptionMaker contact
]
]
]
]
]
contactImage :
Contact
->
{ src : String
, description : String
}
contactImage contact =
{ src = "contact/" ++ contact.contactImage ++ ".png"
, description = contact.contactName
}
contactTitle : Contact -> String
contactTitle contact =
contact.contactName
descriptionMaker : Contact -> Element msg
descriptionMaker contact =
column
[ width fill
, height fill
]
[ paragraph [ width fill, F.size 15, spacing 10 ] <|
List.map makeDescription
contact.contactEntry
]
makeDescription : Method -> Element msg
makeDescription method =
paragraph
[ F.regular
, F.alignLeft
]
[ paragraph
[ F.color colourTheme.textLightGrey
]
[ text method.contactInstructions
]
]
linkMaker : Contact -> Element msg
linkMaker contact =
paragraph
[ F.color colourTheme.textLightGrey
, paragraphSpacing
, paragraphFontSize
, F.bold
, F.size 18
, spacing 8
]
[ newTabLink
[ paragraphFontSize
, F.color colourTheme.textLightOrange
]
{ url = contact.contactLink
, label =
el
[ transitionStyleSlow
, hoverFontDarkOrange
]
<|
text contact.contactLinkLabel
}
]
instructionMaker : Element msg
instructionMaker =
row

View file

@ -134,7 +134,7 @@ argumentMakerMobile argument =
argumentImage : Argument -> { src : String, description : String }
argumentImage argument =
{ src = "arguments/" ++ argument.argumentImage ++ ".png"
{ src = "/arguments/" ++ argument.argumentImage ++ ".png"
, description = argument.argumentTitle
}

View file

@ -38,7 +38,7 @@ argumentAnabolicKeto =
}
]
, conclusion = "Therefore, ketogenic diets are likely to cost anabolic potential compared to non-ketogenic diets."
, conclusionNotation = "R"
, conclusionNotation = "R"
}
]
}

View file

@ -147,7 +147,7 @@ cuckImage :
, description : String
}
cuckImage cuck =
{ src = "cucks/" ++ cuck.cuckImage ++ "/" ++ cuck.cuckImage ++ ".png"
{ src = "/cucks/" ++ cuck.cuckImage ++ "/" ++ cuck.cuckImage ++ ".png"
, description = cuck.cuckName
}

View file

@ -44,7 +44,7 @@ desktopDebateMaker : Debate -> Element msg
desktopDebateMaker debate =
row
topLevelBox
[ cardImageMaker (debateImage debate) (debateLink debate)
[ cardImageMaker (debateImage debate) debate.debateLink
, cardMaker
[ cardTitleMaker debate.debateTitle
, cardFormatter
@ -70,7 +70,7 @@ mobileDebateMaker debate =
[ column
fieldSpacer
[ row [ width fill, spacing 10 ]
[ cardImageMakerMobile (debateImage debate) (debateLink debate)
[ cardImageMakerMobile (debateImage debate) debate.debateLink
, column
[ width fill ]
[]
@ -94,16 +94,6 @@ debateImage debate =
}
debateTitle : Debate -> String
debateTitle debate =
debate.debateTitle
debateLink : Debate -> String
debateLink debate =
debate.debateLink
descriptionMaker : Debate -> Element msg
descriptionMaker debate =
column
@ -113,24 +103,14 @@ descriptionMaker debate =
]
[ row []
[ paragraph
([ F.color colourTheme.textLightOrange
, paragraphSpacing
, paragraphFontSize
, F.bold
]
++ [ F.size 18
, E.width fill
]
)
[ if
let
formatCuckCount =
[ F.regular
, F.size 16
]
in
debate.debateTitle == "Arguments"
then
[ F.color colourTheme.textLightOrange
, paragraphSpacing
, paragraphFontSize
, F.bold
, F.size 18
, E.width fill
]
[ if debate.debateTitle == "Arguments" then
text "Inferences: "
else if debate.debateTitle == "Cucklist" then

View file

@ -8,6 +8,8 @@ import Config.Data.Identity
import Config.Helpers.Converters exposing (formatName)
import Config.Pages.Debate.Arguments.Helpers exposing (argumentListNumber)
import Config.Pages.Debate.Debate.Types exposing (..)
import Route
import Route.Path as Path
debateArguments : Debate
@ -17,8 +19,9 @@ debateArguments =
"Arguments"
in
{ debateTitle = name
, debateLink = formatName (url ++ pageNames.pageArguments)
, debateLink = Path.toString Path.Debate_Arguments
, debateCount = argumentListNumber
, debateImage = formatName name
, isNewTabLink = False
, debateDescription = "This page features arguments that I hold to be sound. I'm open to hearing all challenges, as I am ready to engage with and defend any argument listed."
}

View file

@ -8,6 +8,7 @@ import Config.Data.Identity
import Config.Helpers.Converters exposing (formatName)
import Config.Pages.Debate.Cuckery.Helpers exposing (cuckListNumber)
import Config.Pages.Debate.Debate.Types exposing (..)
import Route.Path as Path
debateCuckList =
@ -16,8 +17,9 @@ debateCuckList =
"Cucklist"
in
{ debateTitle = name
, debateLink = formatName (url ++ pageNames.pageCucks)
, debateLink = Path.toString Path.Debate_Cucklist
, debateCount = cuckListNumber
, debateImage = formatName name
, isNewTabLink = False
, debateDescription = "This page features a list of morons who wrote cheques with their mouths that their asses couldn't cash. Each person included in this list has dodged debating me."
}

View file

@ -8,6 +8,7 @@ import Config.Data.Identity
import Config.Helpers.Converters exposing (formatName)
import Config.Pages.Debate.Debate.Types exposing (..)
import Config.Pages.Debate.Gibberish.Helpers exposing (gibberishListNumber)
import Route.Path as Path
debateGibberish =
@ -16,8 +17,9 @@ debateGibberish =
"Gibberish"
in
{ debateTitle = name
, debateLink = formatName (url ++ pageNames.pageGibberish)
, debateLink = Path.toString Path.Debate_Gibberish
, debateCount = gibberishListNumber
, debateImage = formatName name
, isNewTabLink = False
, debateDescription = "This page is specifically for terms and ostensible concepts that I think are either nonsensical or so practically useless that its intelligiblity is irrelevant."
}

View file

@ -6,5 +6,6 @@ type alias Debate =
, debateLink : String
, debateImage : String
, debateCount : Int
, isNewTabLink : Bool
, debateDescription : String
}

View file

@ -84,7 +84,7 @@ gibberishMakerBody gibberish =
gibberishImage : Gibberish -> { src : String, description : String }
gibberishImage gibberish =
{ src = "gibberish/" ++ gibberish.gibberishImage ++ ".png"
{ src = "/gibberish/" ++ gibberish.gibberishImage ++ ".png"
, description = gibberish.gibberishTitle
}

0
frontend/src/Config/Pages/Headers/Pages/Debate.elm Normal file → Executable file
View file

View file

@ -32,9 +32,8 @@ homePage image =
, centerY
, spacing 20
]
[ row [ centerX, E.width fill, height <| px 100 ]
[ html image
]
[ el [ centerX, E.width fill, height <| px 100 ] <|
html image
, column
[ paddingEach
{ top = 15

View file

@ -1,4 +1,4 @@
module Config.Pages.Services.Offerings.DebateAnalysis exposing (..)
module Config.Pages.Services.Services.DebateAnalysis exposing (..)
import Config.Pages.Services.Types exposing (..)
import Config.Helpers.Converters exposing (formatName)

View file

@ -1,4 +1,4 @@
module Config.Pages.Services.Offerings.DebateTutoring exposing (..)
module Config.Pages.Services.Services.DebateTutoring exposing (..)
import Config.Pages.Services.Types exposing (..)
import Config.Helpers.Converters exposing (formatName)

View file

@ -1,4 +1,4 @@
module Config.Pages.Services.Offerings.ElmBuilds exposing (..)
module Config.Pages.Services.Services.ElmBuilds exposing (..)
import Element exposing (..)
import Config.Pages.Services.Types exposing (..)

View file

@ -1,4 +1,4 @@
module Config.Pages.Services.Offerings.NixBuilds exposing (..)
module Config.Pages.Services.Services.NixBuilds exposing (..)
import Config.Pages.Services.Types exposing (..)
import Config.Helpers.Converters exposing (formatName)

View file

@ -1,4 +1,4 @@
module Config.Pages.Services.Offerings.NutritionScience exposing (..)
module Config.Pages.Services.Services.NutritionScience exposing (..)
import Config.Helpers.Converters exposing (formatName)
import Config.Pages.Services.Types exposing (..)

View file

@ -12,6 +12,7 @@ type alias Theme =
, backgroundLightGrey : Color
, backgroundDarkGrey : Color
, backgroundDeepDarkGrey : Color
, shadow : Color
, barGreen : Color
, barRed : Color
, debugColour : Color
@ -29,6 +30,7 @@ colourTheme =
, backgroundLightGrey = rgb255 40 40 40
, backgroundDarkGrey = rgb255 30 30 30
, backgroundDeepDarkGrey = rgb255 20 20 20
, shadow = rgb255 10 10 10
, barGreen = rgb255 0 102 0
, barRed = rgb255 102 0 0
, debugColour = rgb255 227 28 121

0
frontend/src/Config/Style/Fonts.elm Normal file → Executable file
View file

9
frontend/src/Config/Style/Glow.elm Normal file → Executable file
View file

@ -8,9 +8,14 @@ import Html.Attributes as H exposing (style)
glowDeepDarkGrey : Attr decorative msg
glowDeepDarkGrey =
D.glow colourTheme.backgroundDeepDarkGrey 5
D.glow colourTheme.shadow 4
glowDeepDarkOrange : Attr decorative msg
glowDeepDarkOrange =
D.glow colourTheme.textDeepDarkOrange 5
D.glow colourTheme.shadow 4
glowDeepDarkGreyNavbar : Attr decorative msg
glowDeepDarkGreyNavbar =
D.glow colourTheme.shadow 10

View file

@ -1,5 +1,9 @@
module Config.Style.Svgs exposing (..)
import Config.Helpers.Viewport exposing (Msg)
import Config.Style.Svgs.Helpers as HeSvg exposing (buildSvg)
import Config.Style.Svgs.Types as SvgTypes exposing (..)
import Element as E exposing (..)
import Html exposing (Html)
import Svg exposing (..)
import Svg.Attributes as SvgAttr
@ -475,301 +479,400 @@ nutriDexLogo =
]
home : Html msg
home =
svg
[ SvgAttr.viewBox "0 0 576 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"
home : SvgTypes.OuterPart msg -> Element msg
home inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 576 512"
, SvgAttr.fill "currentColor"
]
[]
]
services : Html msg
services =
svg
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M78.6 5C69.1-2.4 55.6-1.5 47 7L7 47c-8.5 8.5-9.4 22-2.1 31.6l80 104c4.5 5.9 11.6 9.4 19 9.4l54.1 0 109 109c-14.7 29-10 65.4 14.3 89.6l112 112c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-112-112c-24.2-24.2-60.6-29-89.6-14.3l-109-109 0-54.1c0-7.5-3.5-14.5-9.4-19L78.6 5zM19.9 396.1C7.2 408.8 0 426.1 0 444.1C0 481.6 30.4 512 67.9 512c18 0 35.3-7.2 48-19.9L233.7 374.3c-7.8-20.9-9-43.6-3.6-65.1l-61.7-61.7L19.9 396.1zM512 144c0-10.5-1.1-20.7-3.2-30.5c-2.4-11.2-16.1-14.1-24.2-6l-63.9 63.9c-3 3-7.1 4.7-11.3 4.7L352 176c-8.8 0-16-7.2-16-16l0-57.4c0-4.2 1.7-8.3 4.7-11.3l63.9-63.9c8.1-8.1 5.2-21.8-6-24.2C388.7 1.1 378.5 0 368 0C288.5 0 224 64.5 224 144l0 .8 85.3 85.3c36-9.1 75.8 .5 104 28.7L429 274.5c49-23 83-72.8 83-130.5zM56 432a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z"
, svg =
[ path
[ SvgAttr.d "M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"
]
[]
]
[]
]
}
hyperBlog : Html msg
hyperBlog =
svg
[ SvgAttr.viewBox "0 0 448 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M248 106.6c18.9-9 32-28.3 32-50.6c0-30.9-25.1-56-56-56s-56 25.1-56 56c0 22.3 13.1 41.6 32 50.6l0 98.8c-2.8 1.3-5.5 2.9-8 4.7l-80.1-45.8c1.6-20.8-8.6-41.6-27.9-52.8C57.2 96 23 105.2 7.5 132S1.2 193 28 208.5c1.3 .8 2.6 1.5 4 2.1l0 90.8c-1.3 .6-2.7 1.3-4 2.1C1.2 319-8 353.2 7.5 380S57.2 416 84 400.5c19.3-11.1 29.4-32 27.8-52.8l50.5-28.9c-11.5-11.2-19.9-25.6-23.8-41.7L88 306.1c-2.6-1.8-5.2-3.3-8-4.7l0-90.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-.1 1.4-.2 2.8-.2 4.3c0 22.3 13.1 41.6 32 50.6l0 98.8c-18.9 9-32 28.3-32 50.6c0 30.9 25.1 56 56 56s56-25.1 56-56c0-22.3-13.1-41.6-32-50.6l0-98.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-1.6 20.8 8.6 41.6 27.8 52.8c26.8 15.5 61 6.3 76.5-20.5s6.3-61-20.5-76.5c-1.3-.8-2.7-1.5-4-2.1l0-90.8c1.4-.6 2.7-1.3 4-2.1c26.8-15.5 36-49.7 20.5-76.5S390.8 96 364 111.5c-19.3 11.1-29.4 32-27.8 52.8l-50.6 28.9c11.5 11.2 19.9 25.6 23.8 41.7L360 205.9c2.6 1.8 5.2 3.3 8 4.7l0 90.8c-2.8 1.3-5.5 2.9-8 4.6l-80.1-45.8c.1-1.4 .2-2.8 .2-4.3c0-22.3-13.1-41.6-32-50.6l0-98.8z"
services : SvgTypes.OuterPart msg -> Element msg
services inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "currentColor"
]
[]
]
debate : Html msg
debate =
svg
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8l0 378.1C394 378 431.1 230.1 432 141.4L256 66.8s0 0 0 0z"
, svg =
[ path
[ SvgAttr.d "M78.6 5C69.1-2.4 55.6-1.5 47 7L7 47c-8.5 8.5-9.4 22-2.1 31.6l80 104c4.5 5.9 11.6 9.4 19 9.4l54.1 0 109 109c-14.7 29-10 65.4 14.3 89.6l112 112c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-112-112c-24.2-24.2-60.6-29-89.6-14.3l-109-109 0-54.1c0-7.5-3.5-14.5-9.4-19L78.6 5zM19.9 396.1C7.2 408.8 0 426.1 0 444.1C0 481.6 30.4 512 67.9 512c18 0 35.3-7.2 48-19.9L233.7 374.3c-7.8-20.9-9-43.6-3.6-65.1l-61.7-61.7L19.9 396.1zM512 144c0-10.5-1.1-20.7-3.2-30.5c-2.4-11.2-16.1-14.1-24.2-6l-63.9 63.9c-3 3-7.1 4.7-11.3 4.7L352 176c-8.8 0-16-7.2-16-16l0-57.4c0-4.2 1.7-8.3 4.7-11.3l63.9-63.9c8.1-8.1 5.2-21.8-6-24.2C388.7 1.1 378.5 0 368 0C288.5 0 224 64.5 224 144l0 .8 85.3 85.3c36-9.1 75.8 .5 104 28.7L429 274.5c49-23 83-72.8 83-130.5zM56 432a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z"
]
[]
]
[]
]
}
nutriDex : Html msg
nutriDex =
svg
[ SvgAttr.width "100%"
, SvgAttr.height "100%"
, SvgAttr.viewBox "0 0 269 254"
, SvgAttr.version "1.1"
, SvgAttr.xmlSpace "preserve"
, SvgAttr.style "fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"
]
[ Svg.g
[ SvgAttr.transform "matrix(1,0,0,1,-3213.08,-2929.6)"
hyperBlog : SvgTypes.OuterPart msg -> Element msg
hyperBlog inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 448 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M248 106.6c18.9-9 32-28.3 32-50.6c0-30.9-25.1-56-56-56s-56 25.1-56 56c0 22.3 13.1 41.6 32 50.6l0 98.8c-2.8 1.3-5.5 2.9-8 4.7l-80.1-45.8c1.6-20.8-8.6-41.6-27.9-52.8C57.2 96 23 105.2 7.5 132S1.2 193 28 208.5c1.3 .8 2.6 1.5 4 2.1l0 90.8c-1.3 .6-2.7 1.3-4 2.1C1.2 319-8 353.2 7.5 380S57.2 416 84 400.5c19.3-11.1 29.4-32 27.8-52.8l50.5-28.9c-11.5-11.2-19.9-25.6-23.8-41.7L88 306.1c-2.6-1.8-5.2-3.3-8-4.7l0-90.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-.1 1.4-.2 2.8-.2 4.3c0 22.3 13.1 41.6 32 50.6l0 98.8c-18.9 9-32 28.3-32 50.6c0 30.9 25.1 56 56 56s56-25.1 56-56c0-22.3-13.1-41.6-32-50.6l0-98.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-1.6 20.8 8.6 41.6 27.8 52.8c26.8 15.5 61 6.3 76.5-20.5s6.3-61-20.5-76.5c-1.3-.8-2.7-1.5-4-2.1l0-90.8c1.4-.6 2.7-1.3 4-2.1c26.8-15.5 36-49.7 20.5-76.5S390.8 96 364 111.5c-19.3 11.1-29.4 32-27.8 52.8l-50.6 28.9c11.5 11.2 19.9 25.6 23.8 41.7L360 205.9c2.6 1.8 5.2 3.3 8 4.7l0 90.8c-2.8 1.3-5.5 2.9-8 4.6l-80.1-45.8c.1-1.4 .2-2.8 .2-4.3c0-22.3-13.1-41.6-32-50.6l0-98.8z"
]
[]
]
}
debate : SvgTypes.OuterPart msg -> Element msg
debate inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8l0 378.1C394 378 431.1 230.1 432 141.4L256 66.8s0 0 0 0z"
]
[]
]
}
nutriDex : SvgTypes.OuterPart msg -> Element msg
nutriDex inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 269 254"
, SvgAttr.fill "currentColor"
]
, svg =
[ Svg.g
[ SvgAttr.transform "matrix(-0.305281,-0.528763,-0.528763,0.305281,4477.01,4051.59)"
[ SvgAttr.transform "matrix(1,0,0,1,-3213.08,-2929.6)"
]
[ path
[ SvgAttr.d "M2438.06,573.79L2421.04,607.88"
, SvgAttr.style "fill:none;stroke:rgb(204,102,0);stroke-width:26.21px;"
[ Svg.g
[ SvgAttr.transform "matrix(-0.305281,-0.528763,-0.528763,0.305281,4477.01,4051.59)"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(-0.520336,-0.901248,-0.901248,0.520336,5215.05,4836.33)"
]
[ path
[ SvgAttr.d "M2384.94,593.791L2428.07,593.791"
, SvgAttr.style "fill:none;stroke:rgb(204,102,0);stroke-width:15.37px;"
[ path
[ SvgAttr.d "M2438.06,573.79L2421.04,607.88"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(-1.46201,0,0,1.46201,6982.34,1712.61)"
]
[ path
[ SvgAttr.d "M2439.01,851.153L2458.28,851.153"
, SvgAttr.style "fill:none;stroke:rgb(204,102,0);stroke-width:10.94px;"
, Svg.g
[ SvgAttr.transform "matrix(-0.520336,-0.901248,-0.901248,0.520336,5215.05,4836.33)"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.520336,-0.901248,0.901248,0.520336,1614.66,4836.33)"
]
[ path
[ SvgAttr.d "M2319.68,627.395C2323.07,629.57 2324.23,634.05 2322.24,637.617L2299.1,678.996C2298.35,680.341 2297.25,681.373 2295.98,682.042L2292.05,675.243L2319.68,627.395Z"
, SvgAttr.style "fill:rgb(204,102,0);"
[ path
[ SvgAttr.d "M2384.94,593.791L2428.07,593.791"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.520336,-0.901248,0.901248,0.520336,1614.66,4836.33)"
]
[ path
[ SvgAttr.d "M2344.65,603.881L2362.65,634.203L2338.66,673.941L2384.94,673.941"
, SvgAttr.style "fill:none;stroke:rgb(204,102,0);stroke-width:15.37px;"
, Svg.g
[ SvgAttr.transform "matrix(-1.46201,0,0,1.46201,6982.34,1712.61)"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(1.46201,0,0,1.46201,-152.629,1712.61)"
]
[ path
[ SvgAttr.d "M2423.66,877.745L2456.6,877.745"
, SvgAttr.style "fill:none;stroke:rgb(204,102,0);stroke-width:10.94px;"
[ path
[ SvgAttr.d "M2439.01,851.153L2458.28,851.153"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1653.93,4549.24)"
]
[ path
[ SvgAttr.d "M2484.47,812.271C2487.52,814.103 2490.15,816.709 2492.05,820.001C2498.05,830.377 2494.49,843.663 2484.11,849.654C2477.29,853.592 2469.21,853.402 2462.77,849.863L2484.47,812.271ZM2456.98,859.904C2463.26,863.709 2467.46,870.611 2467.46,878.486C2467.46,890.467 2457.74,900.193 2445.76,900.193C2441.96,900.193 2438.38,899.215 2435.28,897.496L2456.98,859.904ZM2429.48,907.537C2435.76,911.342 2439.96,918.243 2439.96,926.117C2439.96,934.544 2435.15,941.856 2428.13,945.452L2417.86,927.666L2429.48,907.537ZM2451.62,832.633C2450.96,824.532 2454.9,816.387 2462.4,812.056C2462.92,811.757 2463.45,811.482 2463.97,811.231L2451.62,832.633ZM2406.34,944.257C2400.44,940.374 2396.55,933.697 2396.55,926.117C2396.55,917.453 2401.64,909.968 2408.98,906.488L2400.88,920.526C2398.33,924.945 2398.33,930.389 2400.88,934.807L2406.34,944.257ZM2424.12,880.266C2424.07,879.679 2424.05,879.086 2424.05,878.486C2424.05,869.824 2429.13,862.34 2436.48,858.859L2424.12,880.266Z"
, SvgAttr.style "fill:rgb(204,102,0);"
, Svg.g
[ SvgAttr.transform "matrix(0.520336,-0.901248,0.901248,0.520336,1614.66,4836.33)"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1702.08,4465.83)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.style "fill:rgb(204,102,0);"
[ path
[ SvgAttr.d "M2319.68,627.395C2323.07,629.57 2324.23,634.05 2322.24,637.617L2299.1,678.996C2298.35,680.341 2297.25,681.373 2295.98,682.042L2292.05,675.243L2319.68,627.395Z"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,0.75827,-0.75827,0.437787,2986.19,756.746)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.style "fill:rgb(204,102,0);"
, Svg.g
[ SvgAttr.transform "matrix(0.520336,-0.901248,0.901248,0.520336,1614.66,4836.33)"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1678.01,4507.54)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.style "fill:rgb(204,102,0);"
[ path
[ SvgAttr.d "M2344.65,603.881L2362.65,634.203L2338.66,673.941L2384.94,673.941"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1726.16,4507.54)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.style "fill:rgb(204,102,0);"
, Svg.g
[ SvgAttr.transform "matrix(1.46201,0,0,1.46201,-152.629,1712.61)"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1702.08,4549.24)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.style "fill:rgb(204,102,0);"
[ path
[ SvgAttr.d "M2423.66,877.745L2456.6,877.745"
, SvgAttr.style "none"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(1,0,-0.402297,0.712005,2955.89,2912.86)"
]
[ path
[ SvgAttr.d "M410,379.833C410,379.833 410.056,260.455 410.09,188.088C410.095,176.87 404.503,163.127 395.402,151.992C386.302,140.858 375.063,134.008 365.884,134.002C358.352,133.997 351.428,133.992 346.641,133.989C345.213,133.988 343.47,132.952 342.03,131.25C340.591,129.547 339.658,127.419 339.564,125.619C338.962,114.141 337.955,94.916 337.955,94.916L397.955,94.916C397.955,94.916 537.356,266.295 570.787,307.394C575.207,312.828 580.681,316.175 585.149,316.175C597.174,316.175 620,316.175 620,316.175L620,379.833L560.605,379.833C553.617,379.833 545.056,374.614 538.129,366.13C524.324,349.222 491.306,308.782 480.375,295.394C476.268,290.363 471.189,287.278 467.055,287.302C462.921,287.326 460.361,290.456 460.34,295.511C460.211,327.614 460,379.833 460,379.833L410,379.833Z"
, SvgAttr.style "fill:rgb(204,102,0);"
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1653.93,4549.24)"
]
[ path
[ SvgAttr.d "M2484.47,812.271C2487.52,814.103 2490.15,816.709 2492.05,820.001C2498.05,830.377 2494.49,843.663 2484.11,849.654C2477.29,853.592 2469.21,853.402 2462.77,849.863L2484.47,812.271ZM2456.98,859.904C2463.26,863.709 2467.46,870.611 2467.46,878.486C2467.46,890.467 2457.74,900.193 2445.76,900.193C2441.96,900.193 2438.38,899.215 2435.28,897.496L2456.98,859.904ZM2429.48,907.537C2435.76,911.342 2439.96,918.243 2439.96,926.117C2439.96,934.544 2435.15,941.856 2428.13,945.452L2417.86,927.666L2429.48,907.537ZM2451.62,832.633C2450.96,824.532 2454.9,816.387 2462.4,812.056C2462.92,811.757 2463.45,811.482 2463.97,811.231L2451.62,832.633ZM2406.34,944.257C2400.44,940.374 2396.55,933.697 2396.55,926.117C2396.55,917.453 2401.64,909.968 2408.98,906.488L2400.88,920.526C2398.33,924.945 2398.33,930.389 2400.88,934.807L2406.34,944.257ZM2424.12,880.266C2424.07,879.679 2424.05,879.086 2424.05,878.486C2424.05,869.824 2429.13,862.34 2436.48,858.859L2424.12,880.266Z"
, SvgAttr.fill "currentColor"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1702.08,4465.83)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.fill "currentColor"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,0.75827,-0.75827,0.437787,2986.19,756.746)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.fill "currentColor"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1678.01,4507.54)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.fill "currentColor"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1726.16,4507.54)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.fill "currentColor"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(0.437787,-0.75827,0.75827,0.437787,1702.08,4549.24)"
]
[ Svg.circle
[ SvgAttr.cx "2445.76"
, SvgAttr.cy "878.486"
, SvgAttr.r "21.707"
, SvgAttr.fill "currentColor"
]
[]
]
, Svg.g
[ SvgAttr.transform "matrix(1,0,-0.402297,0.712005,2955.89,2912.86)"
]
[ path
[ SvgAttr.d "M410,379.833C410,379.833 410.056,260.455 410.09,188.088C410.095,176.87 404.503,163.127 395.402,151.992C386.302,140.858 375.063,134.008 365.884,134.002C358.352,133.997 351.428,133.992 346.641,133.989C345.213,133.988 343.47,132.952 342.03,131.25C340.591,129.547 339.658,127.419 339.564,125.619C338.962,114.141 337.955,94.916 337.955,94.916L397.955,94.916C397.955,94.916 537.356,266.295 570.787,307.394C575.207,312.828 580.681,316.175 585.149,316.175C597.174,316.175 620,316.175 620,316.175L620,379.833L560.605,379.833C553.617,379.833 545.056,374.614 538.129,366.13C524.324,349.222 491.306,308.782 480.375,295.394C476.268,290.363 471.189,287.278 467.055,287.302C462.921,287.326 460.361,290.456 460.34,295.511C460.211,327.614 460,379.833 460,379.833L410,379.833Z"
, SvgAttr.fill "currentColor"
]
[]
]
[]
]
]
]
}
interviews : Html msg
interviews =
svg
[ SvgAttr.viewBox "0 0 640 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M208 352c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176c0 38.6 14.7 74.3 39.6 103.4c-3.5 9.4-8.7 17.7-14.2 24.7c-4.8 6.2-9.7 11-13.3 14.3c-1.8 1.6-3.3 2.9-4.3 3.7c-.5 .4-.9 .7-1.1 .8l-.2 .2s0 0 0 0s0 0 0 0C1 327.2-1.4 334.4 .8 340.9S9.1 352 16 352c21.8 0 43.8-5.6 62.1-12.5c9.2-3.5 17.8-7.4 25.2-11.4C134.1 343.3 169.8 352 208 352zM448 176c0 112.3-99.1 196.9-216.5 207C255.8 457.4 336.4 512 432 512c38.2 0 73.9-8.7 104.7-23.9c7.5 4 16 7.9 25.2 11.4c18.3 6.9 40.3 12.5 62.1 12.5c6.9 0 13.1-4.5 15.2-11.1c2.1-6.6-.2-13.8-5.8-17.9c0 0 0 0 0 0s0 0 0 0l-.2-.2c-.2-.2-.6-.4-1.1-.8c-1-.8-2.5-2-4.3-3.7c-3.6-3.3-8.5-8.1-13.3-14.3c-5.5-7-10.7-15.4-14.2-24.7c24.9-29 39.6-64.7 39.6-103.4c0-92.8-84.9-168.9-192.6-175.5c.4 5.1 .6 10.3 .6 15.5z"
interviews : SvgTypes.OuterPart msg -> Element msg
interviews inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 640 512"
, SvgAttr.fill "currentColor"
]
[]
]
donate : Html msg
donate =
svg
[ SvgAttr.viewBox "0 0 576 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M64 32C28.7 32 0 60.7 0 96l0 32 576 0 0-32c0-35.3-28.7-64-64-64L64 32zM576 224L0 224 0 416c0 35.3 28.7 64 64 64l448 0c35.3 0 64-28.7 64-64l0-192zM112 352l64 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-64 0c-8.8 0-16-7.2-16-16s7.2-16 16-16zm112 16c0-8.8 7.2-16 16-16l128 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-128 0c-8.8 0-16-7.2-16-16z"
, svg =
[ path
[ SvgAttr.d "M208 352c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176c0 38.6 14.7 74.3 39.6 103.4c-3.5 9.4-8.7 17.7-14.2 24.7c-4.8 6.2-9.7 11-13.3 14.3c-1.8 1.6-3.3 2.9-4.3 3.7c-.5 .4-.9 .7-1.1 .8l-.2 .2s0 0 0 0s0 0 0 0C1 327.2-1.4 334.4 .8 340.9S9.1 352 16 352c21.8 0 43.8-5.6 62.1-12.5c9.2-3.5 17.8-7.4 25.2-11.4C134.1 343.3 169.8 352 208 352zM448 176c0 112.3-99.1 196.9-216.5 207C255.8 457.4 336.4 512 432 512c38.2 0 73.9-8.7 104.7-23.9c7.5 4 16 7.9 25.2 11.4c18.3 6.9 40.3 12.5 62.1 12.5c6.9 0 13.1-4.5 15.2-11.1c2.1-6.6-.2-13.8-5.8-17.9c0 0 0 0 0 0s0 0 0 0l-.2-.2c-.2-.2-.6-.4-1.1-.8c-1-.8-2.5-2-4.3-3.7c-3.6-3.3-8.5-8.1-13.3-14.3c-5.5-7-10.7-15.4-14.2-24.7c24.9-29 39.6-64.7 39.6-103.4c0-92.8-84.9-168.9-192.6-175.5c.4 5.1 .6 10.3 .6 15.5z"
]
[]
]
[]
]
}
contact : Html msg
contact =
svg
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "#cc6600"
]
[ path
[ SvgAttr.d "M215.4 96L144 96l-36.2 0L96 96l0 8.8L96 144l0 40.4 0 89L.2 202.5c1.6-18.1 10.9-34.9 25.7-45.8L48 140.3 48 96c0-26.5 21.5-48 48-48l76.6 0 49.9-36.9C232.2 3.9 243.9 0 256 0s23.8 3.9 33.5 11L339.4 48 416 48c26.5 0 48 21.5 48 48l0 44.3 22.1 16.4c14.8 10.9 24.1 27.7 25.7 45.8L416 273.4l0-89 0-40.4 0-39.2 0-8.8-11.8 0L368 96l-71.4 0-81.3 0zM0 448L0 242.1 217.6 403.3c11.1 8.2 24.6 12.7 38.4 12.7s27.3-4.4 38.4-12.7L512 242.1 512 448s0 0 0 0c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64c0 0 0 0 0 0zM176 160l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16s7.2-16 16-16z"
donate : SvgTypes.OuterPart msg -> Element msg
donate inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 576 512"
, SvgAttr.fill "currentColor"
]
[]
]
gitlab : Html msg
gitlab =
svg
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "#D4D4D4"
]
[ path
[ SvgAttr.d "M503.5 204.6L502.8 202.8L433.1 21C431.7 17.5 429.2 14.4 425.9 12.4C423.5 10.8 420.8 9.9 417.9 9.6C415 9.3 412.2 9.7 409.5 10.7C406.8 11.7 404.4 13.3 402.4 15.5C400.5 17.6 399.1 20.1 398.3 22.9L351.3 166.9H160.8L113.7 22.9C112.9 20.1 111.5 17.6 109.6 15.5C107.6 13.4 105.2 11.7 102.5 10.7C99.9 9.7 97 9.3 94.1 9.6C91.3 9.9 88.5 10.8 86.1 12.4C82.8 14.4 80.3 17.5 78.9 21L9.3 202.8L8.5 204.6C-1.5 230.8-2.7 259.6 5 286.6C12.8 313.5 29.1 337.3 51.5 354.2L51.7 354.4L52.3 354.8L158.3 434.3L210.9 474L242.9 498.2C246.6 500.1 251.2 502.5 255.9 502.5C260.6 502.5 265.2 500.1 268.9 498.2L300.9 474L353.5 434.3L460.2 354.4L460.5 354.1C482.9 337.2 499.2 313.5 506.1 286.6C514.7 259.6 513.5 230.8 503.5 204.6z"
, svg =
[ path
[ SvgAttr.d "M64 32C28.7 32 0 60.7 0 96l0 32 576 0 0-32c0-35.3-28.7-64-64-64L64 32zM576 224L0 224 0 416c0 35.3 28.7 64 64 64l448 0c35.3 0 64-28.7 64-64l0-192zM112 352l64 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-64 0c-8.8 0-16-7.2-16-16s7.2-16 16-16zm112 16c0-8.8 7.2-16 16-16l128 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-128 0c-8.8 0-16-7.2-16-16z"
]
[]
]
[]
]
}
twitter : Html msg
twitter =
svg
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "#D4D4D4"
]
[ path
[ SvgAttr.d "M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"
contact : SvgTypes.OuterPart msg -> Element msg
contact inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "currentColor"
]
[]
]
mastodon : Html msg
mastodon =
svg
[ SvgAttr.viewBox "0 0 448 512"
, SvgAttr.fill "#D4D4D4"
]
[ path
[ SvgAttr.d "M433 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.6-28.4-290.5 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54a102.5 102.5 0 0 1 -.9-13.9c85.6 20.9 158.7 9.1 178.8 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zm-75.1 125.2h-46.6v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.3V197c0-58.5-64-56.6-64-6.9v114.2H90.2c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175z"
, svg =
[ path
[ SvgAttr.d "M215.4 96L144 96l-36.2 0L96 96l0 8.8L96 144l0 40.4 0 89L.2 202.5c1.6-18.1 10.9-34.9 25.7-45.8L48 140.3 48 96c0-26.5 21.5-48 48-48l76.6 0 49.9-36.9C232.2 3.9 243.9 0 256 0s23.8 3.9 33.5 11L339.4 48 416 48c26.5 0 48 21.5 48 48l0 44.3 22.1 16.4c14.8 10.9 24.1 27.7 25.7 45.8L416 273.4l0-89 0-40.4 0-39.2 0-8.8-11.8 0L368 96l-71.4 0-81.3 0zM0 448L0 242.1 217.6 403.3c11.1 8.2 24.6 12.7 38.4 12.7s27.3-4.4 38.4-12.7L512 242.1 512 448s0 0 0 0c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64c0 0 0 0 0 0zM176 160l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16s7.2-16 16-16z"
]
[]
]
[]
]
}
discord : Html msg
discord =
svg
[ SvgAttr.viewBox "0 0 640 512"
, SvgAttr.fill "#D4D4D4"
]
[ path
[ SvgAttr.d "M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"
gitlab : SvgTypes.OuterPart msg -> Element msg
gitlab inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "currentColor"
]
[]
]
, svg =
[ path
[ SvgAttr.d "M503.5 204.6L502.8 202.8L433.1 21C431.7 17.5 429.2 14.4 425.9 12.4C423.5 10.8 420.8 9.9 417.9 9.6C415 9.3 412.2 9.7 409.5 10.7C406.8 11.7 404.4 13.3 402.4 15.5C400.5 17.6 399.1 20.1 398.3 22.9L351.3 166.9H160.8L113.7 22.9C112.9 20.1 111.5 17.6 109.6 15.5C107.6 13.4 105.2 11.7 102.5 10.7C99.9 9.7 97 9.3 94.1 9.6C91.3 9.9 88.5 10.8 86.1 12.4C82.8 14.4 80.3 17.5 78.9 21L9.3 202.8L8.5 204.6C-1.5 230.8-2.7 259.6 5 286.6C12.8 313.5 29.1 337.3 51.5 354.2L51.7 354.4L52.3 354.8L158.3 434.3L210.9 474L242.9 498.2C246.6 500.1 251.2 502.5 255.9 502.5C260.6 502.5 265.2 500.1 268.9 498.2L300.9 474L353.5 434.3L460.2 354.4L460.5 354.1C482.9 337.2 499.2 313.5 506.1 286.6C514.7 259.6 513.5 230.8 503.5 204.6z"
]
[]
]
}
twitter : SvgTypes.OuterPart msg -> Element msg
twitter inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"
]
[]
]
}
mastodon : SvgTypes.OuterPart msg -> Element msg
mastodon inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 448 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M433 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.6-28.4-290.5 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54a102.5 102.5 0 0 1 -.9-13.9c85.6 20.9 158.7 9.1 178.8 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zm-75.1 125.2h-46.6v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.3V197c0-58.5-64-56.6-64-6.9v114.2H90.2c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175z"
]
[]
]
}
discord : SvgTypes.OuterPart msg -> Element msg
discord inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 640 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"
]
[]
]
}
lock : SvgTypes.OuterPart msg -> Element msg
lock inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 448 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M144 144l0 48 160 0 0-48c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192l0-48C80 64.5 144.5 0 224 0s144 64.5 144 144l0 48 16 0c35.3 0 64 28.7 64 64l0 192c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 256c0-35.3 28.7-64 64-64l16 0z"
]
[]
]
}
circleX : SvgTypes.OuterPart msg -> Element msg
circleX inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 512 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c-9.4 9.4-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0z"
]
[]
]
}
circleDots : SvgTypes.OuterPart msg -> Element msg
circleDots inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 448 512"
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M8 256a56 56 0 1 1 112 0A56 56 0 1 1 8 256zm160 0a56 56 0 1 1 112 0 56 56 0 1 1 -112 0zm216-56a56 56 0 1 1 0 112 56 56 0 1 1 0-112z"
]
[]
]
}
construction : Html msg
construction =
svg
[ SvgAttr.viewBox "0 0 576 512"
, SvgAttr.fill "#D4D4D4"
, SvgAttr.fill "currentColor"
]
[ path
[ SvgAttr.d "M208 64a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM9.8 214.8c5.1-12.2 19.1-18 31.4-12.9L60.7 210l22.9-38.1C99.9 144.6 129.3 128 161 128c51.4 0 97 32.9 113.3 81.7l34.6 103.7 79.3 33.1 34.2-45.6c6.4-8.5 16.6-13.3 27.2-12.8s20.3 6.4 25.8 15.5l96 160c5.9 9.9 6.1 22.2 .4 32.2s-16.3 16.2-27.8 16.2l-256 0c-11.1 0-21.4-5.7-27.2-15.2s-6.4-21.2-1.4-31.1l16-32c5.4-10.8 16.5-17.7 28.6-17.7l32 0 22.5-30L22.8 246.2c-12.2-5.1-18-19.1-12.9-31.4zm82.8 91.8l112 48c11.8 5 19.4 16.6 19.4 29.4l0 96c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-74.9-60.6-26-37 111c-5.6 16.8-23.7 25.8-40.5 20.2S-3.9 486.6 1.6 469.9l48-144 11-33 32 13.7z"
]
[]
]
construction2 : SvgTypes.OuterPart msg -> Element msg
construction2 inner =
HeSvg.buildSvg inner
{ svgAttributes =
[ SvgAttr.viewBox "0 0 576 512"
-- Using elm-svg because typed-svg has no way of setting the fill to currentColor.
, SvgAttr.fill "currentColor"
]
, svg =
[ path
[ SvgAttr.d "M208 64a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM9.8 214.8c5.1-12.2 19.1-18 31.4-12.9L60.7 210l22.9-38.1C99.9 144.6 129.3 128 161 128c51.4 0 97 32.9 113.3 81.7l34.6 103.7 79.3 33.1 34.2-45.6c6.4-8.5 16.6-13.3 27.2-12.8s20.3 6.4 25.8 15.5l96 160c5.9 9.9 6.1 22.2 .4 32.2s-16.3 16.2-27.8 16.2l-256 0c-11.1 0-21.4-5.7-27.2-15.2s-6.4-21.2-1.4-31.1l16-32c5.4-10.8 16.5-17.7 28.6-17.7l32 0 22.5-30L22.8 246.2c-12.2-5.1-18-19.1-12.9-31.4zm82.8 91.8l112 48c11.8 5 19.4 16.6 19.4 29.4l0 96c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-74.9-60.6-26-37 111c-5.6 16.8-23.7 25.8-40.5 20.2S-3.9 486.6 1.6 469.9l48-144 11-33 32 13.7z"
]
[]
]
}

View file

@ -0,0 +1,23 @@
module Config.Style.Svgs.Helpers exposing (..)
import Config.Style.Svgs.Types as SvgTypes exposing (..)
import Element as E exposing (..)
import Svg
{- buildSvg consumes an inner record to construct most of an SVG, and an outer record to supply
any potentially varying TypedSvg.Core.Attribute msgs and wrap it in an Element.el so it can be
used by elm-ui. It provides a consistent interface for inserting SVGs into elm-ui code.
-}
buildSvg : SvgTypes.OuterPart msg -> SvgTypes.InnerPart msg -> Element msg
buildSvg outer inner =
el
outer.elementAttributes
<|
html <|
Svg.svg
(outer.svgAttributes ++ inner.svgAttributes)
inner.svg

View file

@ -0,0 +1,25 @@
module Config.Style.Svgs.Types exposing (..)
{-| The types used for SVG management.
-}
import Element
import Shared
import Svg exposing (..)
{-| The outer record for the SVG builder. This is explained in ../Helpers/Svg.elm.
-}
type alias OuterPart msg =
{ elementAttributes : List (Element.Attribute msg)
, sharedModel : Shared.Model
, svgAttributes : List (Svg.Attribute msg)
}
{-| The inner record for the SVG builder. This is explained in ../Helpers/Svg.elm.
-}
type alias InnerPart msg =
{ svgAttributes : List (Svg.Attribute msg)
, svg : List (Svg.Svg msg)
}

5
frontend/src/Config/Style/Transitions.elm Normal file → Executable file
View file

@ -24,6 +24,11 @@ transitionStyleFast =
htmlAttribute <| style "transition" "all 0.1s ease-in-out"
specialNavbarTransition : Attribute msg
specialNavbarTransition =
htmlAttribute <| style "transition" "opacity .4s"
hoverFontLightOrange : Attribute msg
hoverFontLightOrange =
mouseOver [ F.color colourTheme.textLightOrange ]

View file

@ -2,6 +2,7 @@ module Effect exposing
( Effect
, none, batch
, sendCmd, sendMsg
, clearUser, saveUser, signIn, signOut, toggleLanguage, toggleNavbarExpansion
, pushRoute, replaceRoute, loadExternalUrl
, map, toCmd
)
@ -11,6 +12,7 @@ module Effect exposing
@docs Effect
@docs none, batch
@docs sendCmd, sendMsg
@docs clearUser, saveUser, signIn, signOut, toggleLanguage, toggleNavbarExpansion
@docs pushRoute, replaceRoute, loadExternalUrl
@docs map, toCmd
@ -19,6 +21,8 @@ module Effect exposing
import Browser.Navigation
import Dict exposing (Dict)
import Json.Encode
import Ports
import Route exposing (Route)
import Route.Path
import Shared.Model
@ -38,6 +42,7 @@ type Effect msg
| LoadExternalUrl String
-- SHARED
| SendSharedMsg Shared.Msg.Msg
| SendToLocalStorage { key : String, value : Json.Encode.Value }
@ -89,6 +94,7 @@ pushRoute :
pushRoute route =
PushUrl (Route.toString route)
{-| Set given path as route (without any query params or hash), and make the back button go back to the current route.
-}
pushPath :
@ -97,6 +103,7 @@ pushPath :
pushPath path =
PushUrl (Route.toString { path = path, query = Dict.empty, hash = Nothing })
{-| Set the new route, but replace the previous one, so clicking the back
button **won't** go back to the previous route.
-}
@ -109,6 +116,7 @@ replaceRoute :
replaceRoute route =
ReplaceUrl (Route.toString route)
{-| Set given path as route (without any query params or hash), but replace the previous route,
so clicking the back button **won't** go back to the previous route
-}
@ -118,6 +126,7 @@ replacePath :
replacePath path =
ReplaceUrl (Route.toString { path = path, query = Dict.empty, hash = Nothing })
{-| Redirect users to a new URL, somewhere external your web application.
-}
loadExternalUrl : String -> Effect msg
@ -156,6 +165,9 @@ map fn effect =
SendSharedMsg sharedMsg ->
SendSharedMsg sharedMsg
SendToLocalStorage value ->
SendToLocalStorage value
{-| Elm Land depends on this function to perform your effects.
-}
@ -192,3 +204,54 @@ toCmd options effect =
SendSharedMsg sharedMsg ->
Task.succeed sharedMsg
|> Task.perform options.fromSharedMsg
SendToLocalStorage value ->
Ports.sendToLocalStorage value
toggleNavbarExpansion : Effect msg
toggleNavbarExpansion =
SendSharedMsg Shared.Msg.ToggleNavbarExpansion
toggleLanguage : Effect msg
toggleLanguage =
SendSharedMsg Shared.Msg.ToggleLanguage
signIn :
{ token : String
, name : String
}
-> Effect msg
signIn user =
SendSharedMsg (Shared.Msg.SignIn user)
signOut : Effect msg
signOut =
SendSharedMsg Shared.Msg.SignOut
saveUser :
{ token : String
, name : String
}
-> Effect msg
saveUser user =
SendToLocalStorage
{ key = "user"
, value =
Json.Encode.object
[ ( "token", Json.Encode.string user.token )
, ( "name", Json.Encode.string user.name )
]
}
clearUser : Effect msg
clearUser =
SendToLocalStorage
{ key = "user"
, value = Json.Encode.null
}

1039
frontend/src/Layouts/Navbar.elm Executable file → Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
module Pages.Arguments exposing (Model, Msg, page)
module Pages.Debate.Arguments exposing (Model, Msg, page)
import Config.Data.Identity exposing (pageNames)
import Config.Format.Response

View file

@ -1,4 +1,4 @@
module Pages.Cucklist exposing (Model, Msg, page)
module Pages.Debate.Cucklist exposing (Model, Msg, page)
import Config.Data.Identity exposing (pageNames)
import Config.Format.Response
@ -86,17 +86,17 @@ view : Shared.Model -> Model -> View Msg
view shared model =
{ title = "debate (" ++ pageNames.pageCucks ++ ")"
, attributes = []
, element = dodgersContainer shared.device
, element = cucksContainer shared.device
}
dodgersContainer : Device -> Element msg
dodgersContainer device =
topLevelContainer (dodgersList device)
cucksContainer : Device -> Element msg
cucksContainer device =
topLevelContainer (cucksList device)
dodgersList : Device -> Element msg
dodgersList device =
cucksList : Device -> Element msg
cucksList device =
column
(case ( device.class, device.orientation ) of
_ ->

View file

@ -1,4 +1,4 @@
module Pages.Gibberish exposing (Model, Msg, page)
module Pages.Debate.Gibberish exposing (Model, Msg, page)
import Config.Data.Identity exposing (pageNames)
import Config.Format.Response

View file

@ -9,12 +9,16 @@ import Config.Format.Response
import Config.Helpers.Viewport exposing (resetViewport)
import Config.Pages.Home.Helpers exposing (..)
import Config.Style.Colour exposing (colourTheme)
import Config.Style.Svgs exposing (construction2)
import Config.Style.Transitions exposing (transitionStyleMedium)
import Effect exposing (Effect)
import Element as E exposing (..)
import Element.Font as F exposing (color)
import Layouts
import Page exposing (Page)
import Route exposing (Route)
import Shared exposing (..)
import Svg.Attributes as SvgAttr exposing (..)
import View exposing (View)
@ -89,6 +93,21 @@ view shared model =
}
-- construction2
-- { elementAttributes =
-- [ centerX
-- , centerY
-- , transitionStyleMedium
-- , mouseOver [ F.color colourTheme.textDarkOrange ]
-- ]
-- , sharedModel = shared
-- , svgAttributes =
-- [ SvgAttr.width "300" ]
-- }
-- , element = homeContainer shared.device
homeContainer : Device -> Element msg
homeContainer device =
topLevelContainer (homeList device)

View file

@ -10,11 +10,11 @@ import Config.Helpers.Viewport exposing (resetViewport)
import Config.Pages.Headers.Helpers exposing (headerMaker)
import Config.Pages.Headers.Pages.Services exposing (servicesHeader)
import Config.Pages.Services.Helpers exposing (..)
import Config.Pages.Services.Offerings.DebateAnalysis exposing (..)
import Config.Pages.Services.Offerings.DebateTutoring exposing (..)
import Config.Pages.Services.Offerings.ElmBuilds exposing (..)
import Config.Pages.Services.Offerings.NixBuilds exposing (..)
import Config.Pages.Services.Offerings.NutritionScience exposing (..)
import Config.Pages.Services.Services.DebateAnalysis exposing (..)
import Config.Pages.Services.Services.DebateTutoring exposing (..)
import Config.Pages.Services.Services.ElmBuilds exposing (..)
import Config.Pages.Services.Services.NixBuilds exposing (..)
import Config.Pages.Services.Services.NutritionScience exposing (..)
import Config.Style.Colour as T exposing (..)
import Effect exposing (Effect)
import Element as E exposing (..)

View file

@ -0,0 +1,68 @@
module Pages.Services.Analysis exposing (Model, Msg, page)
import Effect exposing (Effect)
import Route exposing (Route)
import Html
import Page exposing (Page)
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
, Effect.none
)
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
View.fromString "Pages.Services.Analysis"

View file

@ -0,0 +1,101 @@
module Pages.Services.Coaching exposing (Model, Msg, page)
import Config.Data.Identity exposing (pageNames)
import Config.Format.Response
exposing
( pageList
, topLevelContainer
)
-- import Config.Pages.Services.Coaching.Helpers exposing (instructionMaker)
import Effect exposing (Effect)
import Element as E exposing (..)
import Html
import Layouts
import Page exposing (Page)
import Route exposing (Route)
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view shared
}
|> Page.withLayout toLayout
toLayout : Model -> Layouts.Layout Msg
toLayout model =
Layouts.Navbar {}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
, Effect.none
)
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Shared.Model -> Model -> View Msg
view shared model =
{ title = pageNames.pageContact ++ " ( )"
, attributes = []
, element = coachContainer shared.device
}
coachContainer : Device -> Element msg
coachContainer device =
topLevelContainer (coachList device)
coachList : Device -> Element msg
coachList device =
column pageList <|
List.concat
(case ( device.class, device.orientation ) of
_ ->
[ [ ] ]
)

View file

@ -0,0 +1,68 @@
module Pages.Services.Elm exposing (Model, Msg, page)
import Effect exposing (Effect)
import Route exposing (Route)
import Html
import Page exposing (Page)
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
, Effect.none
)
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
View.fromString "Pages.Services.Elm"

View file

@ -0,0 +1,68 @@
module Pages.Services.Nix exposing (Model, Msg, page)
import Effect exposing (Effect)
import Route exposing (Route)
import Html
import Page exposing (Page)
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
, Effect.none
)
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
View.fromString "Pages.Services.Nix"

View file

@ -0,0 +1,68 @@
module Pages.Services.Nutrition exposing (Model, Msg, page)
import Effect exposing (Effect)
import Route exposing (Route)
import Html
import Page exposing (Page)
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
, Effect.none
)
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
View.fromString "Pages.Services.Nutrition"

View file

@ -1,2 +1,6 @@
port module Ports exposing (..)
port module Ports exposing (sendToLocalStorage)
import Json.Encode as Encode
port sendToLocalStorage : { key : String, value : Encode.Value } -> Cmd msg

View file

@ -13,12 +13,14 @@ module Shared exposing
-}
import Browser.Events as BR exposing (..)
import Effect exposing (Effect)
import Config.Data.Language as TyLang
import Dict
import Effect exposing (Effect, none)
import Element as E exposing (..)
import Json.Decode exposing (..)
import Route exposing (Route)
import Route.Path
import Shared.Model
import Shared.Model exposing (..)
import Shared.Msg
@ -28,22 +30,32 @@ import Shared.Msg
type alias Flags =
{ height : Int
, user : Maybe Shared.Model.User
, width : Int
}
decoder : Json.Decode.Decoder Flags
decoder =
Json.Decode.map2
(\height width ->
Json.Decode.map3
(\height user width ->
{ height = height
, user = user
, width = width
}
)
(field "height" int)
(field "user" (Json.Decode.maybe userDecoder))
(field "width" int)
userDecoder : Json.Decode.Decoder Shared.Model.User
userDecoder =
Json.Decode.map2 Shared.Model.User
(Json.Decode.field "token" Json.Decode.string)
(Json.Decode.field "name" Json.Decode.string)
-- INIT
@ -64,8 +76,11 @@ modelFromFlagsResult : Result Error Flags -> Model
modelFromFlagsResult f =
case f of
Ok flags ->
{ device = E.classifyDevice flags
{ device = classifyDevice flags
, height = flags.height
, isNavbarExpanded = False
, language = TyLang.English
, user = Just { token = "asht", name = "billy" }
, width = flags.width
}
@ -75,11 +90,14 @@ modelFromFlagsResult f =
Debug.log "error" e
in
{ device =
E.classifyDevice
classifyDevice
{ height = 0
, width = 0
}
, height = 10
, isNavbarExpanded = False
, language = TyLang.English
, user = Nothing
, width = 10
}
@ -108,6 +126,125 @@ update route msg model =
, Effect.none
)
Shared.Msg.ToggleNavbarExpansion ->
( { model | isNavbarExpanded = not model.isNavbarExpanded }
, Effect.none
)
Shared.Msg.SignIn user ->
( { model | user = Just user }
, Effect.batch
[ Effect.pushRoute
{ path =
Dict.get "from" route.query
|> Maybe.andThen Route.Path.fromString
|> Maybe.withDefault Route.Path.Contact
, query = Dict.empty
, hash = Nothing
}
, Effect.saveUser user
]
)
Shared.Msg.SignOut ->
( { model | user = Nothing }
, Effect.clearUser
)
Shared.Msg.ToggleLanguage ->
( { model
| language =
case model.language of
TyLang.Bulgarian ->
TyLang.Chinese
TyLang.Chinese ->
TyLang.Czech
TyLang.Czech ->
TyLang.Danish
TyLang.Danish ->
TyLang.Dutch
TyLang.Dutch ->
TyLang.English
TyLang.English ->
TyLang.Estonian
TyLang.Estonian ->
TyLang.Finnish
TyLang.Finnish ->
TyLang.French
TyLang.French ->
TyLang.German
TyLang.German ->
TyLang.Greek
TyLang.Greek ->
TyLang.Hungarian
TyLang.Hungarian ->
TyLang.Indonesian
TyLang.Indonesian ->
TyLang.Italian
TyLang.Italian ->
TyLang.Japanese
TyLang.Japanese ->
TyLang.Korean
TyLang.Korean ->
TyLang.Latvian
TyLang.Latvian ->
TyLang.Lithuanian
TyLang.Lithuanian ->
TyLang.Norwegian
TyLang.Norwegian ->
TyLang.Polish
TyLang.Polish ->
TyLang.Portuguese
TyLang.Portuguese ->
TyLang.Romanian
TyLang.Romanian ->
TyLang.Russian
TyLang.Russian ->
TyLang.Slovak
TyLang.Slovak ->
TyLang.Slovenian
TyLang.Slovenian ->
TyLang.Spanish
TyLang.Spanish ->
TyLang.Swedish
TyLang.Swedish ->
TyLang.Turkish
TyLang.Turkish ->
TyLang.Ukranian
TyLang.Ukranian ->
TyLang.Bulgarian
}
, Effect.none
)
-- SUBSCRIPTIONS

View file

@ -1,5 +1,6 @@
module Shared.Model exposing (Model)
module Shared.Model exposing (Model, User)
import Config.Data.Language as TyLang
import Element exposing (Device)
@ -7,4 +8,13 @@ type alias Model =
{ height : Int
, width : Int
, device : Device
, language : TyLang.Language
, isNavbarExpanded : Bool
, user : Maybe User
}
type alias User =
{ token : String
, name : String
}

View file

@ -12,3 +12,10 @@ own file, so they can be imported by `Effect.elm`
-}
type Msg
= Resize Int Int
| SignIn
{ token : String
, name : String
}
| SignOut
| ToggleLanguage
| ToggleNavbarExpansion

View file

@ -1,16 +0,0 @@
// This is called BEFORE your Elm app starts up
//
// The value returned here will be passed as flags
// into your `Shared.init` function.
export const flags = ({ env }) => {
return {
height: window.innerHeight,
width: window.innerWidth,
};
};
// This is called AFTER your Elm app starts up
//
// Here you can work with `app.ports` to send messages
// to your Elm application, or subscribe to incoming
// messages from Elm
export const onReady = ({ app, env }) => {};

36
frontend/src/interop.ts Executable file
View file

@ -0,0 +1,36 @@
// On init:
export const flags = ({env}) => {
return {
height: window.innerHeight,
user: JSON.parse(window.localStorage.user || null),
width: window.innerWidth,
};
};
// While running:
export const onReady = ({ app, env }) => {
// app.ports.copy.subscribe((text: string) => {
// const clipboard = navigator.clipboard;
// if (!clipboard) return;
// clipboard.writeText(text);
// });
// app.ports.popup.subscribe(() => {
// setTimeout(() => {
// app.ports.popupDone.send(null);
// }, 2000);
// });
// if (app.ports && app.ports.sendToLocalStorage) {
// app.ports.sendToLocalStorage.subscribe(({ key, value }) => {
// window.localStorage[key] = JSON.stringify(value);
// });
// }
// app.ports.arrow.subscribe((text: string) => {
// const elements = document.getElementsByClassName(text);
// Array.from(elements).forEach(element => {
// element.setAttribute('display', 'highlight');
// });
// })
};

0
frontend/static/debate/arguments.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

Before After
Before After

0
frontend/static/debate/cucklist.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Before After
Before After

0
frontend/static/debate/cucklist1.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 387 KiB

After

Width:  |  Height:  |  Size: 387 KiB

Before After
Before After

0
frontend/static/debate/gibberish.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 216 KiB

Before After
Before After

View file

@ -1,8 +1,8 @@
/* * {
* {
scrollbar-width: none;
}
*::-webkit-scrollbar {
display: none;
}
*/