mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
UI: Cleansheet CSS redesign
Initial skeleton and layout is working. Still needs a bunch of tweaks.
This commit is contained in:
parent
61634cd682
commit
45737f24e4
@ -19,7 +19,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" name="viewport"
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" name="viewport"
|
||||||
content="width=device-width, initial-scale=1.0" charset="UTF-8">
|
content="width=device-width, initial-scale=1.0" charset="UTF-8">
|
||||||
<link rel="stylesheet" href="/ui/static/pico.min.css">
|
|
||||||
<link rel="stylesheet" href="/ui/static/app.css">
|
<link rel="stylesheet" href="/ui/static/app.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -35,4 +34,4 @@
|
|||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -23,9 +23,9 @@ pub fn Header<'ctx, G: Html>(cx: Scope<'ctx>, h: StateHandler<'ctx>) -> View<G>
|
|||||||
None => "Login".to_owned(),
|
None => "Login".to_owned(),
|
||||||
});
|
});
|
||||||
view! {cx,
|
view! {cx,
|
||||||
nav(class="no-print") {
|
nav(class="no-print row-flex align-center header-bg heavy-bottom-border") {
|
||||||
h1(class="title") { "Kitchen" }
|
h1(class="title") { "Kitchen" }
|
||||||
ul {
|
ul(class="row-flex align-center") {
|
||||||
li { a(href="/ui/planning/select") { "MealPlan" } }
|
li { a(href="/ui/planning/select") { "MealPlan" } }
|
||||||
li { a(href="/ui/manage/ingredients") { "Manage" } }
|
li { a(href="/ui/manage/ingredients") { "Manage" } }
|
||||||
li { a(href="/ui/login") { (login.get()) } }
|
li { a(href="/ui/login") { (login.get()) } }
|
||||||
|
@ -211,6 +211,7 @@ where
|
|||||||
F: Fn(Event),
|
F: Fn(Event),
|
||||||
{
|
{
|
||||||
name: String,
|
name: String,
|
||||||
|
class: String,
|
||||||
on_change: Option<F>,
|
on_change: Option<F>,
|
||||||
min: f64,
|
min: f64,
|
||||||
counter: &'ctx Signal<f64>,
|
counter: &'ctx Signal<f64>,
|
||||||
@ -223,6 +224,7 @@ where
|
|||||||
{
|
{
|
||||||
let NumberProps {
|
let NumberProps {
|
||||||
name,
|
name,
|
||||||
|
class,
|
||||||
on_change,
|
on_change,
|
||||||
min,
|
min,
|
||||||
counter,
|
counter,
|
||||||
@ -241,7 +243,7 @@ where
|
|||||||
});
|
});
|
||||||
let id = name.clone();
|
let id = name.clone();
|
||||||
view! {cx,
|
view! {cx,
|
||||||
number-spinner(id=id, val=*counter.get(), min=min, on:updated=move |evt: Event| {
|
number-spinner(id=id, class=(class), val=*counter.get(), min=min, on:updated=move |evt: Event| {
|
||||||
let target: HtmlElement = evt.target().unwrap().dyn_into().unwrap();
|
let target: HtmlElement = evt.target().unwrap().dyn_into().unwrap();
|
||||||
let val: f64 = target.get_attribute("val").unwrap().parse().unwrap();
|
let val: f64 = target.get_attribute("val").unwrap().parse().unwrap();
|
||||||
counter.set(val);
|
counter.set(val);
|
||||||
|
@ -38,12 +38,12 @@ pub fn PlanList<'ctx, G: Html>(cx: Scope<'ctx>, props: PlanListProps<'ctx>) -> V
|
|||||||
view!{cx,
|
view!{cx,
|
||||||
tr() {
|
tr() {
|
||||||
td() {
|
td() {
|
||||||
span(role="button", class="outline", on:click=move |_| {
|
button(class="outline", on:click=move |_| {
|
||||||
sh.dispatch(cx, Message::SelectPlanDate(date, None))
|
sh.dispatch(cx, Message::SelectPlanDate(date, None))
|
||||||
}) { (date_display) }
|
}) { (date_display) }
|
||||||
}
|
}
|
||||||
td() {
|
td() {
|
||||||
span(role="button", class="destructive", on:click=move |_| {
|
button(class="destructive", on:click=move |_| {
|
||||||
sh.dispatch(cx, Message::DeletePlan(date, None))
|
sh.dispatch(cx, Message::DeletePlan(date, None))
|
||||||
}) { "Delete Plan" }
|
}) { "Delete Plan" }
|
||||||
}
|
}
|
||||||
|
@ -79,12 +79,14 @@ pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>)
|
|||||||
|
|
||||||
debug!("creating editor view");
|
debug!("creating editor view");
|
||||||
view! {cx,
|
view! {cx,
|
||||||
label(for="recipe_category") { "Category" }
|
div {
|
||||||
input(name="recipe_category", bind:value=category, on:change=move |_| dirty.set(true))
|
label(for="recipe_category") { "Category" }
|
||||||
div(class="grid") {
|
input(name="recipe_category", bind:value=category, on:change=move |_| dirty.set(true))
|
||||||
div {
|
}
|
||||||
label(for="recipe_text") { "Recipe" }
|
div {
|
||||||
textarea(name="recipe_text", bind:value=text, aria-invalid=aria_hint.get(), rows=20, on:change=move |_| {
|
div(class="row-flex") {
|
||||||
|
label(for="recipe_text", class="block align-stretch expand-height") { "Recipe: " }
|
||||||
|
textarea(class="width-third", name="recipe_text", bind:value=text, aria-invalid=aria_hint.get(), cols="50", rows=20, on:change=move |_| {
|
||||||
dirty.set(true);
|
dirty.set(true);
|
||||||
check_recipe_parses(text.get_untracked().as_str(), error_text, aria_hint);
|
check_recipe_parses(text.get_untracked().as_str(), error_text, aria_hint);
|
||||||
}, on:input=move |_| {
|
}, on:input=move |_| {
|
||||||
@ -97,34 +99,36 @@ pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>)
|
|||||||
}
|
}
|
||||||
div(class="parse") { (error_text.get()) }
|
div(class="parse") { (error_text.get()) }
|
||||||
}
|
}
|
||||||
span(role="button", on:click=move |_| {
|
div {
|
||||||
let unparsed = text.get_untracked();
|
button(on:click=move |_| {
|
||||||
if check_recipe_parses(unparsed.as_str(), error_text, aria_hint) {
|
let unparsed = text.get_untracked();
|
||||||
debug!("triggering a save");
|
if check_recipe_parses(unparsed.as_str(), error_text, aria_hint) {
|
||||||
if !*dirty.get_untracked() {
|
debug!("triggering a save");
|
||||||
debug!("Recipe text is unchanged");
|
if !*dirty.get_untracked() {
|
||||||
return;
|
debug!("Recipe text is unchanged");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug!("Recipe text is changed");
|
||||||
|
let category = category.get_untracked();
|
||||||
|
let category = if category.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(category.as_ref().clone())
|
||||||
|
};
|
||||||
|
let recipe_entry = RecipeEntry(
|
||||||
|
id.get_untracked().as_ref().clone(),
|
||||||
|
text.get_untracked().as_ref().clone(),
|
||||||
|
category,
|
||||||
|
);
|
||||||
|
sh.dispatch(cx, Message::SaveRecipe(recipe_entry, None));
|
||||||
|
dirty.set(false);
|
||||||
}
|
}
|
||||||
debug!("Recipe text is changed");
|
// TODO(jwall): Show error message if trying to save when recipe doesn't parse.
|
||||||
let category = category.get_untracked();
|
}) { "Save" } " "
|
||||||
let category = if category.is_empty() {
|
button(on:click=move |_| {
|
||||||
None
|
sh.dispatch(cx, Message::RemoveRecipe(id.get_untracked().as_ref().to_owned(), Some(Box::new(|| sycamore_router::navigate("/ui/planning/plan")))));
|
||||||
} else {
|
}) { "delete" } " "
|
||||||
Some(category.as_ref().clone())
|
}
|
||||||
};
|
|
||||||
let recipe_entry = RecipeEntry(
|
|
||||||
id.get_untracked().as_ref().clone(),
|
|
||||||
text.get_untracked().as_ref().clone(),
|
|
||||||
category,
|
|
||||||
);
|
|
||||||
sh.dispatch(cx, Message::SaveRecipe(recipe_entry, None));
|
|
||||||
dirty.set(false);
|
|
||||||
}
|
|
||||||
// TODO(jwall): Show error message if trying to save when recipe doesn't parse.
|
|
||||||
}) { "Save" } " "
|
|
||||||
span(role="button", on:click=move |_| {
|
|
||||||
sh.dispatch(cx, Message::RemoveRecipe(id.get_untracked().as_ref().to_owned(), Some(Box::new(|| sycamore_router::navigate("/ui/planning/plan")))));
|
|
||||||
}) { "delete" } " "
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ pub fn CategoryGroup<'ctx, G: Html>(
|
|||||||
});
|
});
|
||||||
view! {cx,
|
view! {cx,
|
||||||
h2 { (category) }
|
h2 { (category) }
|
||||||
div(class="recipe_selector no-print") {
|
div(class="no-print flex-wrap-start align-stretch") {
|
||||||
(View::new_fragment(
|
(View::new_fragment(
|
||||||
rows.get().iter().cloned().map(|r| {
|
rows.get().iter().cloned().map(|r| {
|
||||||
view ! {cx,
|
view ! {cx,
|
||||||
@ -61,7 +61,7 @@ pub fn CategoryGroup<'ctx, G: Html>(
|
|||||||
view=move |cx, sig| {
|
view=move |cx, sig| {
|
||||||
let title = create_memo(cx, move || sig.get().1.title.clone());
|
let title = create_memo(cx, move || sig.get().1.title.clone());
|
||||||
view! {cx,
|
view! {cx,
|
||||||
div(class="cell") { RecipeSelection(i=sig.get().0.to_owned(), title=title, sh=sh) }
|
div(class="cell column-flex justify-end align-stretch") { RecipeSelection(i=sig.get().0.to_owned(), title=title, sh=sh) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
key=|sig| sig.get().0.to_owned(),
|
key=|sig| sig.get().0.to_owned(),
|
||||||
@ -108,13 +108,13 @@ pub fn RecipePlan<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> Vie
|
|||||||
},
|
},
|
||||||
key=|(ref cat, _)| cat.clone(),
|
key=|(ref cat, _)| cat.clone(),
|
||||||
)
|
)
|
||||||
span(role="button", on:click=move |_| {
|
button(on:click=move |_| {
|
||||||
sh.dispatch(cx, Message::LoadState(None));
|
sh.dispatch(cx, Message::LoadState(None));
|
||||||
}) { "Reset" } " "
|
}) { "Reset" } " "
|
||||||
span(role="button", on:click=move |_| {
|
button(on:click=move |_| {
|
||||||
sh.dispatch(cx, Message::ResetRecipeCounts);
|
sh.dispatch(cx, Message::ResetRecipeCounts);
|
||||||
}) { "Clear All" } " "
|
}) { "Clear All" } " "
|
||||||
span(role="button", on:click=move |_| {
|
button(on:click=move |_| {
|
||||||
// Poor man's click event signaling.
|
// Poor man's click event signaling.
|
||||||
sh.dispatch(cx, Message::SaveState(None));
|
sh.dispatch(cx, Message::SaveState(None));
|
||||||
}) { "Save Plan" } " "
|
}) { "Save Plan" } " "
|
||||||
|
@ -65,8 +65,8 @@ pub fn RecipeSelection<'ctx, G: Html>(
|
|||||||
let name = format!("recipe_id:{}", id);
|
let name = format!("recipe_id:{}", id);
|
||||||
let for_id = name.clone();
|
let for_id = name.clone();
|
||||||
view! {cx,
|
view! {cx,
|
||||||
label(for=for_id) { a(href=href) { (*title) } }
|
label(for=for_id, class="flex-item-grow") { a(href=href) { (*title) } }
|
||||||
NumberField(name=name, counter=count, min=0.0, on_change=Some(move |_| {
|
NumberField(name=name, class="flex-item-shrink".to_string(), counter=count, min=0.0, on_change=Some(move |_| {
|
||||||
debug!(idx=%id, count=%(*count.get_untracked()), "setting recipe count");
|
debug!(idx=%id, count=%(*count.get_untracked()), "setting recipe count");
|
||||||
sh.dispatch(cx, Message::UpdateRecipeCount(id.as_ref().clone(), *count.get_untracked() as usize));
|
sh.dispatch(cx, Message::UpdateRecipeCount(id.as_ref().clone(), *count.get_untracked() as usize));
|
||||||
}))
|
}))
|
||||||
|
@ -205,15 +205,15 @@ pub fn ShoppingList<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> V
|
|||||||
sh.dispatch(cx, Message::UpdateUseStaples(value));
|
sh.dispatch(cx, Message::UpdateUseStaples(value));
|
||||||
})
|
})
|
||||||
(make_shopping_table(cx, sh, show_staples))
|
(make_shopping_table(cx, sh, show_staples))
|
||||||
span(role="button", class="no-print", on:click=move |_| {
|
button(class="no-print", on:click=move |_| {
|
||||||
info!("Registering add item request for inventory");
|
info!("Registering add item request for inventory");
|
||||||
sh.dispatch(cx, Message::AddExtra(String::new(), String::new()));
|
sh.dispatch(cx, Message::AddExtra(String::new(), String::new()));
|
||||||
}) { "Add Item" } " "
|
}) { "Add Item" } " "
|
||||||
span(role="button", class="no-print", on:click=move |_| {
|
button(class="no-print", on:click=move |_| {
|
||||||
info!("Registering reset request for inventory");
|
info!("Registering reset request for inventory");
|
||||||
sh.dispatch(cx, Message::ResetInventory);
|
sh.dispatch(cx, Message::ResetInventory);
|
||||||
}) { "Reset" } " "
|
}) { "Reset" } " "
|
||||||
span(role="button", class="no-print", on:click=move |_| {
|
button(class="no-print", on:click=move |_| {
|
||||||
info!("Registering save request for inventory");
|
info!("Registering save request for inventory");
|
||||||
sh.dispatch(cx, Message::SaveState(None));
|
sh.dispatch(cx, Message::SaveState(None));
|
||||||
}) { "Save" } " "
|
}) { "Save" } " "
|
||||||
|
@ -72,8 +72,8 @@ pub fn IngredientsEditor<'ctx, G: Html>(
|
|||||||
|
|
||||||
debug!("creating editor view");
|
debug!("creating editor view");
|
||||||
view! {cx,
|
view! {cx,
|
||||||
div(class="grid") {
|
div {
|
||||||
textarea(bind:value=text, aria-invalid=aria_hint.get(), rows=20, on:change=move |_| {
|
textarea(class="width-third", bind:value=text, aria-invalid=aria_hint.get(), rows=20, on:change=move |_| {
|
||||||
dirty.set(true);
|
dirty.set(true);
|
||||||
}, on:input=move |_| {
|
}, on:input=move |_| {
|
||||||
let current_ts = js_lib::get_ms_timestamp();
|
let current_ts = js_lib::get_ms_timestamp();
|
||||||
@ -84,7 +84,7 @@ pub fn IngredientsEditor<'ctx, G: Html>(
|
|||||||
})
|
})
|
||||||
div(class="parse") { (error_text.get()) }
|
div(class="parse") { (error_text.get()) }
|
||||||
}
|
}
|
||||||
span(role="button", on:click=move |_| {
|
button(on:click=move |_| {
|
||||||
let unparsed = text.get();
|
let unparsed = text.get();
|
||||||
if !*dirty.get_untracked() {
|
if !*dirty.get_untracked() {
|
||||||
debug!("Staples text is unchanged");
|
debug!("Staples text is unchanged");
|
||||||
|
@ -47,12 +47,12 @@ pub fn TabbedView<'a, G: Html>(cx: Scope<'a>, state: TabState<'a, G>) -> View<G>
|
|||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
view! {cx,
|
view! {cx,
|
||||||
nav {
|
nav(class="menu-bg expand-height") {
|
||||||
ul(class="tabs") {
|
ul(class="tabs pad-left") {
|
||||||
(menu)
|
(menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
main(class=".conatiner-fluid") {
|
main {
|
||||||
(children)
|
(children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ pub fn LoginForm<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View
|
|||||||
input(type="text", id="username", bind:value=username)
|
input(type="text", id="username", bind:value=username)
|
||||||
label(for="password") { "Password" }
|
label(for="password") { "Password" }
|
||||||
input(type="password", bind:value=password)
|
input(type="password", bind:value=password)
|
||||||
span(role="button", on:click=move |_| {
|
button(on:click=move |_| {
|
||||||
info!("Attempting login request");
|
info!("Attempting login request");
|
||||||
let (username, password) = ((*username.get_untracked()).clone(), (*password.get_untracked()).clone());
|
let (username, password) = ((*username.get_untracked()).clone(), (*password.get_untracked()).clone());
|
||||||
if username != "" && password != "" {
|
if username != "" && password != "" {
|
||||||
|
@ -37,7 +37,7 @@ pub fn SelectPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> Vie
|
|||||||
selected=Some("Select".to_owned()),
|
selected=Some("Select".to_owned()),
|
||||||
) {
|
) {
|
||||||
PlanList(sh=sh, list=plan_dates)
|
PlanList(sh=sh, list=plan_dates)
|
||||||
span(role="button", on:click=move |_| {
|
button(on:click=move |_| {
|
||||||
sh.dispatch(cx, Message::SelectPlanDate(chrono::offset::Local::now().naive_local().date(), Some(Box::new(|| {
|
sh.dispatch(cx, Message::SelectPlanDate(chrono::offset::Local::now().naive_local().date(), Some(Box::new(|| {
|
||||||
sycamore_router::navigate("/ui/planning/plan");
|
sycamore_router::navigate("/ui/planning/plan");
|
||||||
}))))
|
}))))
|
||||||
|
@ -136,11 +136,12 @@ pub fn Handler<'ctx, G: Html>(cx: Scope<'ctx>, props: HandlerProps<'ctx>) -> Vie
|
|||||||
integration=HistoryIntegration::new(),
|
integration=HistoryIntegration::new(),
|
||||||
view=move |cx: Scope, route: &ReadSignal<Routes>| {
|
view=move |cx: Scope, route: &ReadSignal<Routes>| {
|
||||||
view!{cx,
|
view!{cx,
|
||||||
div(class="app") {
|
div {
|
||||||
Header(sh)
|
Header(sh)
|
||||||
|
div(class="app row-flex flex-item-grow expand-height align-stretch") {
|
||||||
(route_switch(route.get().as_ref(), cx, sh))
|
(route_switch(route.get().as_ref(), cx, sh))
|
||||||
Footer { }
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2022 Jeremy Wall
|
* Copyright 2023 Jeremy Wall
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -21,12 +21,33 @@
|
|||||||
--unicode-button-size: 2em;
|
--unicode-button-size: 2em;
|
||||||
--toast-anim-duration: 3s;
|
--toast-anim-duration: 3s;
|
||||||
--notification-font-size: calc(var(--font-size) / 2);
|
--notification-font-size: calc(var(--font-size) / 2);
|
||||||
--error-message-color: rgba(255, 98, 0, 0.797);
|
--error-message-color: #CD5C08;
|
||||||
--error-message-bg: grey;
|
--error-message-bg: grey;
|
||||||
--border-width: 2px;
|
--border-width: 3px;
|
||||||
--cell-margin: 1em;
|
--cell-margin: 1em;
|
||||||
|
--nav-margin: 2em;
|
||||||
|
--main-color: #A9907E;
|
||||||
|
--light-accent: #F3DEBA;
|
||||||
|
--dark-accent: #ABC4AA;
|
||||||
|
--heavy-accent: #675D50;
|
||||||
|
--text-color: black;
|
||||||
|
--menu-bg: var(--main-color);
|
||||||
|
--header-bg: var(--light-accent);
|
||||||
|
--font-size: 20px;
|
||||||
|
--cell-target: 30%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** TODO(jwall): Dark color scheme?
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--text-color: white;
|
||||||
|
--menu-bg: var(--main-color);
|
||||||
|
--header-bg: var(--dark-accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
**/
|
||||||
|
|
||||||
|
/** TODO(jwall): Seperate these out into composable classes **/
|
||||||
@media print {
|
@media print {
|
||||||
|
|
||||||
.no-print,
|
.no-print,
|
||||||
@ -39,28 +60,101 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
/** Resets **/
|
||||||
:root {
|
|
||||||
--font-size: 35px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--tab-border-color: lightgrey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 10px;
|
margin: 0px;
|
||||||
margin: 10px;
|
padding: 0px;
|
||||||
|
background-color: var(--header-bg);
|
||||||
|
font-size: var(--font-size)
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>ul.tabs>li {
|
body, body * {
|
||||||
border-style: none;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>ul.tabs>li.selected {
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Our specific page elements **/
|
||||||
|
|
||||||
|
/** TODO(jwall): Move these onto the html elements themselves. **/
|
||||||
|
.column-flex {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-flex {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item-grow {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item-shrink {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-wrap-start {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-height {
|
||||||
|
height: 100%;
|
||||||
|
min-height: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-stretch {
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.width-third {
|
||||||
|
min-width: fit-content;
|
||||||
|
width: 33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-block {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** nav elements **/
|
||||||
|
nav ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li {
|
||||||
|
margin-right: var(--nav-margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li a::after {
|
||||||
|
content: '| ";
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li a {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-bg {
|
||||||
|
background-color: var(--header-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heavy-bottom-border {
|
||||||
|
border-bottom: var(--border-width) solid var(--heavy-accent)
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
border-style: none;
|
border-style: none;
|
||||||
border-bottom-style: var(--tab-border-style);
|
border-bottom-style: var(--tab-border-style);
|
||||||
border-bottom-color: var(--tab-border-color);
|
border-bottom-color: var(--tab-border-color);
|
||||||
@ -74,10 +168,40 @@ nav>h1 {
|
|||||||
display: inline;
|
display: inline;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
border-bottom-left-radius: 1em;
|
||||||
|
padding: 1em;
|
||||||
|
width: 100%;
|
||||||
|
overflow-block: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell {
|
||||||
|
margin: 1em;
|
||||||
|
width: var(--cell-target);
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-end {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-bg {
|
||||||
|
background-color: var(--menu-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pad-left {
|
||||||
|
padding-left: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app nav li {
|
||||||
|
margin-bottom: var(--nav-margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
.destructive {
|
.destructive {
|
||||||
background-color: firebrick !important;
|
background-color: #CD5C08 !important;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-count-inc-dec {
|
.item-count-inc-dec {
|
||||||
@ -129,24 +253,3 @@ nav>h1 {
|
|||||||
opacity: 0
|
opacity: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.recipe_selector {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: stretch;
|
|
||||||
align-content: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.recipe_selector .cell {
|
|
||||||
margin: 1em;
|
|
||||||
width: calc(100% / 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: stretch;
|
|
||||||
align-content: stretch;
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user