From c83ab254f177d9bf9d021bd5abf015979a323df9 Mon Sep 17 00:00:00 2001 From: Chris Najman Date: Tue, 20 Feb 2024 10:11:36 +0000 Subject: [PATCH] New button: Expand / Contract table. Styling improvements. 'Local' folder renamed to 'Dist', and css and JavaScript compressed to style.min.css / scripts.min.js --- README.md | 50 +- css/buttons.css | 5 - css/index.css | 1 + css/table.css | 7 +- css/toolbar.css | 18 + {local => dist}/css/base.css | 0 {local => dist}/css/buttons.css | 0 {local => dist}/css/forms.css | 0 {local => dist}/css/index.css | 0 {local => dist}/css/loader.css | 0 {local => dist}/css/scrollbars.css | 0 dist/css/style.css | 717 ++++++++++++++++++++++ dist/css/style.min.css | 1 + {local => dist}/css/table.css | 0 {local => dist}/css/theme-switcher.css | 0 {local => dist}/css/theme.css | 0 {local => dist}/favicon.ico | Bin {local => dist}/index.html | 22 +- {local => dist}/js/script.js | 29 + dist/js/script.min.js | 1 + index.html | 26 +- js/costs-calculator/costs-calculator.js | 24 + js/costs-calculator/delete-all-entries.js | 1 + js/costs-calculator/expand-table.js | 6 + js/globals.js | 1 + 25 files changed, 875 insertions(+), 34 deletions(-) create mode 100644 css/toolbar.css rename {local => dist}/css/base.css (100%) rename {local => dist}/css/buttons.css (100%) rename {local => dist}/css/forms.css (100%) rename {local => dist}/css/index.css (100%) rename {local => dist}/css/loader.css (100%) rename {local => dist}/css/scrollbars.css (100%) create mode 100644 dist/css/style.css create mode 100644 dist/css/style.min.css rename {local => dist}/css/table.css (100%) rename {local => dist}/css/theme-switcher.css (100%) rename {local => dist}/css/theme.css (100%) rename {local => dist}/favicon.ico (100%) rename {local => dist}/index.html (94%) rename {local => dist}/js/script.js (93%) create mode 100644 dist/js/script.min.js create mode 100644 js/costs-calculator/expand-table.js diff --git a/README.md b/README.md index f569d37..adc5775 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Record and save your daily spend and see the average over a number of days. -**Note**: This is an upgrading and updating of an [earlier app](https://chrisnajman.github.io/costs-calculator/) which I now consider deprecated. +**Note**: This is an upgrading and updating of an [earlier app](https://github.com/chrisnajman/costs-calculator) which I now consider deprecated. The main difference is that in the current version I have substituted a 'Reorder entries?' button for maintaining date order, instead of drag-and-drop (which I found to be buggy). @@ -18,8 +18,9 @@ The main difference is that in the current version I have substituted a 'Reorder - [Date > Button: Reorder Entries?](#date--button-reorder-entries) - [Edit Item(s)](#edit-items) - [Delete Entry](#delete-entry) - - [Button: Delete all entries...](#button-delete-all-entries) -- [The 'local' Folder](#the-local-folder) + - [Button: Delete all entries](#button-delete-all-entries) + - [Button: Expand / Contract table](#button-expand--contract-table) +- [The 'dist' Folder](#the-dist-folder) - [Accessibility](#accessibility) - [WAVE Web Accessibility Evaluation Tools Report](#wave-web-accessibility-evaluation-tools-report) - [Testing](#testing) @@ -59,22 +60,47 @@ This button, located next to the 'Date' heading, is disabled until 2 or more ent --- -### Button: Delete all entries... +### Button: Delete all entries -This button is disabled until 1 entry has been made. Clicking it will launch a 'confirm' dialog. If 'yes' is clicked, local storage for the following will be erased: +This button is disabled until 8 entries have been made. Clicking it will launch a 'confirm' dialog. If 'yes' is clicked, local storage for the following will be erased: - Entries for all dates in the 'Daily Spend' table. - The 'Reorder entries?' button state value. -**Note**: Local storage will be cleared for only this specific pair of keys in the Costs Calculator V2 app; local storage for other apps will not be affected. +> [!NOTE] +> Local storage will be cleared for only this specific pair of keys in the Costs Calculator V2 app; local storage for other apps will not be affected. --- -## The 'local' Folder +### Button: Expand / Contract table -The 'main' version structures the JavaScript with ES6 Modules. ES6 Modules will not work if you want to run the app from the local file system (In Windows, this is `file:///C:/Users/...`). Therefore, in the 'local' folder, all JavaScript is consolidated into 1 file (`script.js`). The app can then be run by clicking 'index.html'. +This button is disabled until 8 entries have been made. Clicking 'Expand table' will remove vertical scrollbars and display all entries; clicking 'Contract table' will reinstate scrollbars. -The functionality remains the same in both versions. +> [!NOTE] +> This behaviour is not saved to local storage. + +--- + +## The 'dist' Folder + +### JavaScript + +The 'main' version structures the JavaScript with ES6 Modules. ES6 Modules will not work if you want to run the app from the local file system (In Windows, this is `file:///C:/Users/...`). Therefore, in the 'dist' folder, all JavaScript is consolidated into 1 file (`scripts.js`). `scripts.js` is minified in a ['Babel'-like JavaScript compressor](https://jscompress.com/) and output to `scripts.min.js`. The app can then be run locally by clicking 'index.html'. + +> [!NOTE] +> The 'dist' version also runs on the server. + +> [!NOTE] > `scripts.min.js` is not readable by humans. To inspect the JavaScript, look in `scripts.js`. + +> [!NOTE] +> The functionality remains the same in both versions. + +### CSS + +The 'main' version structures the CSS with individual files imported into `index.css`. The 'dist'version compresses all CSS files into one, `style.css`. This is then minified and output to `style.min.css`. + +> [!NOTE] +> The styling remains the same in both versions. --- @@ -90,8 +116,8 @@ The functionality remains the same in both versions. Tested on Windows 10 with: -- Chrome 121.0.6167.85 (Official Build) (64-bit) -- Firefox 122.0 (64-bit) -- Microsoft Edge 120.0.2210.144 (Official build) (64-bit) +- Chrome +- Firefox +- Microsoft Edge Page tested in both browser and device views. diff --git a/css/buttons.css b/css/buttons.css index 2510c05..15f7382 100644 --- a/css/buttons.css +++ b/css/buttons.css @@ -14,8 +14,3 @@ button { opacity: 0.5; } } - -.delete-all-entries { - margin: 0 auto; - display: block; -} diff --git a/css/index.css b/css/index.css index 6c81e53..2c4f5dd 100644 --- a/css/index.css +++ b/css/index.css @@ -4,6 +4,7 @@ @import "./loader.css"; @import "./table.css"; @import "./buttons.css"; +@import "./toolbar.css"; @import "./forms.css"; @import "./how-to-use.css"; @import "./scrollbars.css"; diff --git a/css/table.css b/css/table.css index e977739..668f60e 100644 --- a/css/table.css +++ b/css/table.css @@ -1,9 +1,13 @@ .table-scroller { max-width: -moz-fit-content; max-width: fit-content; - max-height: 70rem; margin: 0 auto 5rem; } + +.table-entries-max-height { + max-height: 70rem; +} + table { width: 100%; max-width: 120rem; @@ -54,7 +58,6 @@ table { & .sticky { position: sticky; z-index: 1; - position: sticky; top: 0; } & .delete { diff --git a/css/toolbar.css b/css/toolbar.css new file mode 100644 index 0000000..cf93266 --- /dev/null +++ b/css/toolbar.css @@ -0,0 +1,18 @@ +.toolbar { + margin: 0 auto 1rem; + display: flex; + gap: 3rem; + align-items: center; + justify-content: space-between; + max-width: 67rem; + + & h2 { + margin-block-end: 0; + } + + @media screen and (width <= 600px) { + justify-content: center; + gap: 1rem; + flex-direction: column; + } +} diff --git a/local/css/base.css b/dist/css/base.css similarity index 100% rename from local/css/base.css rename to dist/css/base.css diff --git a/local/css/buttons.css b/dist/css/buttons.css similarity index 100% rename from local/css/buttons.css rename to dist/css/buttons.css diff --git a/local/css/forms.css b/dist/css/forms.css similarity index 100% rename from local/css/forms.css rename to dist/css/forms.css diff --git a/local/css/index.css b/dist/css/index.css similarity index 100% rename from local/css/index.css rename to dist/css/index.css diff --git a/local/css/loader.css b/dist/css/loader.css similarity index 100% rename from local/css/loader.css rename to dist/css/loader.css diff --git a/local/css/scrollbars.css b/dist/css/scrollbars.css similarity index 100% rename from local/css/scrollbars.css rename to dist/css/scrollbars.css diff --git a/dist/css/style.css b/dist/css/style.css new file mode 100644 index 0000000..9c8acb2 --- /dev/null +++ b/dist/css/style.css @@ -0,0 +1,717 @@ +/** THEME */ +:root { + --font-sans: system-ui, sans-serif; + --font-serif: Charter, "Bitstream Charter", "Sitka Text", Cambria, serif; + --font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace; + + --clr-light-blue: rgb(135, 206, 235); + --clr-blue: #0075ff; + --clr-lightest: white; + --clr-pale-grey: rgb(245 244 244); + --clr-pale-green-grey: rgb(201, 211, 211); + --clr-palest-green-grey: rgb(219, 226, 226); + --clr-mid: #555; + --clr-light-green: rgb(239, 250, 250); + --clr-green: rgb(4, 167, 167); + --clr-grey-green: rgb(44, 58, 58); + --clr-dark-green: rgb(3, 94, 94); + --clr-dark: rgb(30, 39, 39); + --clr-darker: #222; + --clr-darkest: black; + --clr-code-bg: beige; + --clr-orange: orange; + --clr-red-tile: rgb(205, 74, 10); + --clr-warning: red; + --clr-transparent: transparent; + + --highlight: var(--clr-light-blue); + --shadow: 0px 10px 6px -3px rgba(0, 0, 0, 0.55); + + /* Dark theme (default) */ + --body-bg: var(--clr-darker); + --body-txt: var(--clr-palest-green-grey); + --header-footer-bg: var(--clr-darkest); + --header-footer-txt: var(--clr-light-green); + --header-footer-border: var(--clr-dark-green); + --page-headings-bg: var(--clr-darkest); + --page-headings-txt: var(--clr-palest-green-grey); + --theme-button-bg: var(--clr-darkest); + --theme-icon: var(--clr-lightest); + --theme-txt: var(--clr-lightest); + /* table */ + --table-borders: var(--clr-dark-green); + --caption-bg: var(--clr-darkest); + --tr-th: var(--clr-darkest); + --tr-odd-bg: var(--clr-grey-green); + --tr-even-bg: var(--clr-dark); + /* form */ + --input-bg: var(--clr-palest-green-grey); + /* costs form */ + --costs-form-bg: var(--clr-grey-green); + --costs-form-border: var(--clr-darker); +} + +.light-theme { + --body-bg: var(--clr-pale-green-grey); + --body-txt: var(--clr-darkest); + --header-footer-bg: var(--clr-lightest); + --header-footer-txt: var(--clr-darkest); + --header-footer-border: var(--clr-green); + --page-headings-bg: var(--clr-lightest); + --page-headings-txt: var(--clr-darkest); + --theme-button-bg: var(--clr-lightest); + --theme-icon: var(--clr-orange); + --theme-txt: var(--clr-darkest); + /* table */ + --table-borders: var(--clr-pale-green-grey); + --caption-bg: var(--clr-lightest); + --tr-th: var(--clr-lightest); + --tr-odd-bg: var(--clr-light-green); + --tr-even-bg: var(--clr-lightest); + /* form */ + --input-bg: var(--clr-lightest); + /* costs form */ + --costs-form-bg: var(--clr-light-green); + --costs-form-border: var(--clr-pale-green-grey); +} + +/** BASE */ +*, +*::after { + box-sizing: border-box; + margin: 0; +} + +html { + overflow-y: scroll; + font-size: 10px; +} + +@media (prefers-reduced-motion: no-preference) { + html, + html:focus-within { + scroll-behavior: smooth; + } +} + +ul:empty, +p:empty { + display: none; +} + +.flow > * + * { + margin-top: 1em; + /* em not rem & NOT margin bottom */ +} + +body { + background-color: var(--body-bg); + color: var(--body-txt); + font-family: var(--font-sans); + margin: 0; + line-height: 1.5; + font-size: clamp(1.5rem, 1.35rem + 0.4vw, 1.8rem); +} + +h1 { + font-size: clamp(2.4rem, 2.2rem + 0.8889vw, 3.2rem); + line-height: 1.3; + @media screen and (width < 360px) { + padding: 0 1rem; + } +} + +h2 { + font-size: clamp(2rem, 1.9rem + 0.4444vw, 2.4rem); +} + +h3 { + font-size: clamp(1.6rem, 1.525rem + 0.3333vw, 1.9rem); + margin-bottom: 1rem; +} + +h1 { + font-weight: 400; +} + +h2, +h3, +h4, +h5, +h6 { + line-height: 1.1; +} + +h2 { + text-align: center; + margin-bottom: 3rem; + background-color: var(--page-headings-bg); + color: var(--page-headings-txt); + width: -moz-fit-content; + width: fit-content; + margin: 0 auto 1rem auto; + padding: 1.5rem 3rem; + font-weight: 500; +} + +img { + max-width: 100%; + height: auto; + vertical-align: middle; /* replaces display: block but also removes space below */ + font-style: italic; +} + +ul[role="list"] { + list-style: none; + padding-left: 0; +} + +code, +pre { + font-family: var(--font-mono); +} + +:focus-visible { + outline: 2px solid var(--highlight); + outline-offset: 1px; +} + +button, +input, +select { + font-family: inherit; + font-size: inherit; +} + +button { + all: unset; + color: inherit; + cursor: pointer; +} + +.page-layout { + min-height: 100vh; + min-height: 100dvh; + display: grid; + grid-template-rows: auto 1fr auto; +} + +.page-header, +.page-footer { + background-color: var(--header-footer-bg); + color: var(--header-footer-txt); + text-align: center; + display: flex; + flex-direction: column; + gap: 2rem; +} + +.page-header { + padding: 3.2rem 0; + border-style: solid; + border-bottom-color: var(--header-footer-border); + border-width: 0 0 0.5rem 0; + @media screen and (width < 360px) { + padding-inline: 1rem; + padding-top: 5rem; + } + + & h1 + p { + margin: 0 auto; + } + + & li, + & p { + max-width: 60ch; + } + + & .intro { + margin: 0 auto; + } +} + +.main { + overflow: hidden; + padding: 5rem 1.6rem; +} + +.page-header a, +.page-footer a { + color: var(--header-footer-txt); + text-decoration: none; +} + +.page-footer ul { + display: flex; + gap: 1rem; +} + +.page-footer { + padding: 3.2rem 0; + border-style: solid; + border-top-color: var(--header-footer-border); + border-width: 0.5rem 0 0 0; + + & a:hover { + text-decoration: underline; + } + + & a::after { + content: " \27F6"; + } + + & ul { + flex-direction: column; + } +} + +.icon-logo { + fill: var(--header-footer-txt); + width: 3.6rem; + height: 3.6rem; + margin: 0 auto; +} + +.article { + width: -moz-fit-content; + width: fit-content; + margin: 0 auto; + + padding: 3rem; + display: flex; + flex-direction: column; + + ul, + ol { + padding-left: 2.4rem; + } + + & h2 { + text-align: center; + margin: 0 0 1.5rem; + } + + & h3 { + text-align: left; + line-height: normal; + margin: 2rem 0 1rem; + } +} + +/** Helpers */ +/* Scrollable container */ +[role="region"][aria-labelledby][tabindex] { + overflow: auto; +} + +/* Skip link */ +.skip-link { + color: var(--body-txt); + text-decoration: none; + font-weight: 600; + padding: 0.5rem 1rem; + + &::after { + content: " \2193"; + } +} +.element-invisible { + clip: rect(1px, 1px, 1px, 1px); + height: 1px; + overflow: hidden; + position: absolute; + top: 0; + left: 0; + z-index: 200; + border-bottom: 5px solid transparent; + &.element-focusable:active, + &.element-focusable:focus { + clip: auto; + height: auto; + overflow: visible; + border-bottom-color: var(--highlight); + } +} + +/* Screenreader only */ +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: clip; + clip-path: inset(0); + border: 0; +} + +/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */ +@media (prefers-reduced-motion: reduce) { + html, + html:focus-within { + scroll-behavior: auto; + } + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + transition-delay: 0ms !important; + } +} + +.warning { + color: var(--clr-warning); + font-weight: 600; +} +/* Always comes last **/ +.hide { + display: none; +} + +/** THEME SWITCHER */ +.theme-picker { + position: absolute; + top: 0.5rem; + right: 1rem; + z-index: 300; + width: -moz-fit-content; + width: fit-content; +} + +.theme-icon { + width: 2.4rem; + height: 2.4rem; + fill: var(--theme-icon); + margin-right: 0.5rem; +} + +.btn-theme-toggle { + display: flex; + align-items: center; + padding: 0.5rem 0.5rem 0.75rem 0; + border-width: 0 0 5px 0; + border-bottom-style: solid; + border-bottom-color: var(--clr-green); + background-color: var(--theme-button-bg); + color: var(--theme-txt); + font-size: clamp(1.2rem, 1.1rem + 0.4444vw, 1.6rem); + + &:hover { + opacity: 0.8; + } + + & .mode { + margin-inline-start: 0.5rem; + } +} + +/** LOADER */ +.loader { + position: fixed; + z-index: 500; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + background: var(--clr-dark); +} + +.loader-hidden { + opacity: 0; + visibility: hidden; +} + +.loader::after { + content: "Loading..."; + font-size: 5rem; +} + +@media (prefers-reduced-motion: no-preference) { + .loader { + transition: + opacity 0.75s, + visibility 0.75s; + } + + .loader::after { + content: ""; + font-size: 0rem; + width: 10rem; + height: 10rem; + border: 2rem solid var(--clr-lightest); + border-top-color: var(--clr-green); + border-radius: 50%; + animation: loading 0.75s ease infinite; + } + @keyframes loading { + from { + transform: rotate(0turn); + } + to { + transform: rotate(1turn); + } + } +} + +/** TABLE */ +.table-scroller { + max-width: -moz-fit-content; + max-width: fit-content; + margin: 0 auto 5rem; +} + +.table-entries-max-height { + max-height: 70rem; +} + +table { + width: 100%; + max-width: 120rem; + min-width: 73.6rem; /* Fits Ipad Mini: At viewport width 768px, no scrollbars on table container */ + font-size: clamp(1.6rem, 1.4512rem + 0.3101vw, 1.8rem); + margin: 0 auto; + border-collapse: collapse; + + & th, + & td { + padding: 2rem 3rem; + + &:last-child { + border-right: 0; + } + } + + & th { + border-right: 3px solid var(--table-borders); + &:last-child { + border-right: 0; + } + } + + & td { + border-right: 3px solid var(--table-borders); + &:last-child { + border-right: 0; + } + } + + & .table-headings { + background-color: var(--tr-th); + border-bottom: 3px solid var(--table-borders); + } + + /* class applied only when > 10 entries */ + & .table-heading-shadow { + box-shadow: var(--shadow); + border-bottom-width: 0; + } + + & .centred { + text-align: center; + } + + /** Daily Spend **/ + & .sticky { + position: sticky; + z-index: 1; + top: 0; + } + & .delete { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + + & .icon-delete { + fill: var(--body-txt); + width: 3.6rem; + height: 3.6rem; + } + } + + & .date { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: 2rem; + + & .sort-button { + display: flex; + flex-direction: column; + gap: 0; + padding-block-end: 0.8rem; + line-height: 1.1; + font-weight: normal; + } + } + & .items-container { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 2rem; + + & button { + margin-left: auto; + } + } + + & .tbody { + & tr:nth-child(odd) { + background-color: var(--tr-odd-bg); + } + & tr:nth-child(even) { + background-color: var(--tr-even-bg); + } + } + + & [contenteditable] { + outline: 1px dotted var(--body-txt); + padding: 1rem; + cursor: default; + } + /** Fixes an overflow failure on mobile **/ + & .visually-hidden { + top: -1000px; + left: -1000px; + } +} + +/** BUTTONS */ +button { + background-color: var(--clr-dark-green); + color: var(--clr-lightest); + border: 3px solid var(--clr-green); + border-radius: 0.5rem; + padding: 0.5rem 1rem; + + &:hover { + opacity: 0.8; + } + + &[disabled] { + pointer-events: none; + opacity: 0.5; + } +} + +/** TOOLBAR */ +.toolbar { + margin: 0 auto 1rem; + display: flex; + gap: 3rem; + align-items: center; + justify-content: space-between; + max-width: 67rem; + + & h2 { + margin-block-end: 0; + } + + @media screen and (width <= 600px) { + justify-content: center; + gap: 1rem; + flex-direction: column; + } +} + +/** FORMS */ +input, +select { + background: var(--input-bg); + color: var(--clr-darkest); + border: 1px solid var(--body-txt); +} + +.costs-form-wrapper { + width: -moz-fit-content; + width: fit-content; + margin: 0 auto 5rem; +} + +.costs-form { + background-color: var(--costs-form-bg); + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 2rem; + padding: 3rem; + + & fieldset { + border: 0; + padding: 0; + display: flex; + align-items: center; + gap: 1rem; + } + + & label[for="pence"] { + padding-inline-end: 0.7rem; + font-weight: 700; + } + + & input[type="number"] { + width: 5ch; + } +} + +/** HOW TO USE */ +.summary { + cursor: pointer; + font-weight: 600; + margin-bottom: 2rem; +} + +.details { + position: relative; + + --_content-max-width: 66rem; + --_content-space-outside: 2rem; + + width: min(var(--_content-max-width), 100% - var(--_content-space-outside) * 2); + margin-inline: auto; + + & .details-content { + background-color: var(--header-footer-bg); + border: 0.2rem solid var(--header-footer-border); + + padding: 1rem 2rem 4rem; + + & p, + & li { + text-align: left; + } + + .close-button { + padding-top: 1.5rem; + } + } +} + +/** SCROLLBARS */ +/* Works for webkit browsers */ +::-webkit-scrollbar { + width: auto; +} + +::-webkit-scrollbar-track { + background-color: var(--clr-dark-green); +} +::-webkit-scrollbar-thumb { + background-color: var(--clr-green); + border-radius: 100vw; +} +::-webkit-scrollbar-thumb:hover { + opacity: 0.8; +} + +/* Works for firefox */ +/* Note: values in @supports (property: value value) are arbitrary colours*/ +@supports (scrollbar-color: black grey) { + * { + scrollbar-color: var(--clr-green) var(--clr-dark-green); + } +} diff --git a/dist/css/style.min.css b/dist/css/style.min.css new file mode 100644 index 0000000..0a8a796 --- /dev/null +++ b/dist/css/style.min.css @@ -0,0 +1 @@ + :root {--font-sans: system-ui, sans-serif;--font-serif: Charter, "Bitstream Charter", "Sitka Text", Cambria, serif;--font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace;--clr-light-blue: rgb(135, 206, 235);--clr-blue: #0075ff;--clr-lightest: white;--clr-pale-grey: rgb(245 244 244);--clr-pale-green-grey: rgb(201, 211, 211);--clr-palest-green-grey: rgb(219, 226, 226);--clr-mid: #555;--clr-light-green: rgb(239, 250, 250);--clr-green: rgb(4, 167, 167);--clr-grey-green: rgb(44, 58, 58);--clr-dark-green: rgb(3, 94, 94);--clr-dark: rgb(30, 39, 39);--clr-darker: #222;--clr-darkest: black;--clr-code-bg: beige;--clr-orange: orange;--clr-red-tile: rgb(205, 74, 10);--clr-warning: red;--clr-transparent: transparent;--highlight: var(--clr-light-blue);--shadow: 0px 10px 6px -3px rgba(0, 0, 0, 0.55);--body-bg: var(--clr-darker);--body-txt: var(--clr-palest-green-grey);--header-footer-bg: var(--clr-darkest);--header-footer-txt: var(--clr-light-green);--header-footer-border: var(--clr-dark-green);--page-headings-bg: var(--clr-darkest);--page-headings-txt: var(--clr-palest-green-grey);--theme-button-bg: var(--clr-darkest);--theme-icon: var(--clr-lightest);--theme-txt: var(--clr-lightest);--table-borders: var(--clr-dark-green);--caption-bg: var(--clr-darkest);--tr-th: var(--clr-darkest);--tr-odd-bg: var(--clr-grey-green);--tr-even-bg: var(--clr-dark);--input-bg: var(--clr-palest-green-grey);--costs-form-bg: var(--clr-grey-green);--costs-form-border: var(--clr-darker);}.light-theme {--body-bg: var(--clr-pale-green-grey);--body-txt: var(--clr-darkest);--header-footer-bg: var(--clr-lightest);--header-footer-txt: var(--clr-darkest);--header-footer-border: var(--clr-green);--page-headings-bg: var(--clr-lightest);--page-headings-txt: var(--clr-darkest);--theme-button-bg: var(--clr-lightest);--theme-icon: var(--clr-orange);--theme-txt: var(--clr-darkest);--table-borders: var(--clr-pale-green-grey);--caption-bg: var(--clr-lightest);--tr-th: var(--clr-lightest);--tr-odd-bg: var(--clr-light-green);--tr-even-bg: var(--clr-lightest);--input-bg: var(--clr-lightest);--costs-form-bg: var(--clr-light-green);--costs-form-border: var(--clr-pale-green-grey);}*, *::after {box-sizing: border-box;margin: 0;}html {overflow-y: scroll;font-size: 10px;}@media (prefers-reduced-motion: no-preference) {html, html:focus-within {scroll-behavior: smooth;}}ul:empty, p:empty {display: none;}.flow > * + * {margin-top: 1em;}body {background-color: var(--body-bg);color: var(--body-txt);font-family: var(--font-sans);margin: 0;line-height: 1.5;font-size: clamp(1.5rem, 1.35rem + 0.4vw, 1.8rem);}h1 {font-size: clamp(2.4rem, 2.2rem + 0.8889vw, 3.2rem);line-height: 1.3;@media screen and (width < 360px) {padding: 0 1rem;}}h2 {font-size: clamp(2rem, 1.9rem + 0.4444vw, 2.4rem);}h3 {font-size: clamp(1.6rem, 1.525rem + 0.3333vw, 1.9rem);margin-bottom: 1rem;}h1 {font-weight: 400;}h2, h3, h4, h5, h6 {line-height: 1.1;}h2 {text-align: center;margin-bottom: 3rem;background-color: var(--page-headings-bg);color: var(--page-headings-txt);width: -moz-fit-content;width: fit-content;margin: 0 auto 1rem auto;padding: 1.5rem 3rem;font-weight: 500;}img {max-width: 100%;height: auto;vertical-align: middle;font-style: italic;}ul[role="list"] {list-style: none;padding-left: 0;}code, pre {font-family: var(--font-mono);}:focus-visible {outline: 2px solid var(--highlight);outline-offset: 1px;}button, input, select {font-family: inherit;font-size: inherit;}button {all: unset;color: inherit;cursor: pointer;}.page-layout {min-height: 100vh;min-height: 100dvh;display: grid;grid-template-rows: auto 1fr auto;}.page-header, .page-footer {background-color: var(--header-footer-bg);color: var(--header-footer-txt);text-align: center;display: flex;flex-direction: column;gap: 2rem;}.page-header {padding: 3.2rem 0;border-style: solid;border-bottom-color: var(--header-footer-border);border-width: 0 0 0.5rem 0;@media screen and (width < 360px) {padding-inline: 1rem;padding-top: 5rem;}& h1 + p {margin: 0 auto;}& li, & p {max-width: 60ch;}& .intro {margin: 0 auto;}}.main {overflow: hidden;padding: 5rem 1.6rem;}.page-header a, .page-footer a {color: var(--header-footer-txt);text-decoration: none;}.page-footer ul {display: flex;gap: 1rem;}.page-footer {padding: 3.2rem 0;border-style: solid;border-top-color: var(--header-footer-border);border-width: 0.5rem 0 0 0;& a:hover {text-decoration: underline;}& a::after {content: " \27F6";}& ul {flex-direction: column;}}.icon-logo {fill: var(--header-footer-txt);width: 3.6rem;height: 3.6rem;margin: 0 auto;}.article {width: -moz-fit-content;width: fit-content;margin: 0 auto;padding: 3rem;display: flex;flex-direction: column;ul, ol {padding-left: 2.4rem;}& h2 {text-align: center;margin: 0 0 1.5rem;}& h3 {text-align: left;line-height: normal;margin: 2rem 0 1rem;}}[role="region"][aria-labelledby][tabindex] {overflow: auto;}.skip-link {color: var(--body-txt);text-decoration: none;font-weight: 600;padding: 0.5rem 1rem;&::after {content: " \2193";}}.element-invisible {clip: rect(1px, 1px, 1px, 1px);height: 1px;overflow: hidden;position: absolute;top: 0;left: 0;z-index: 200;border-bottom: 5px solid transparent;&.element-focusable:active, &.element-focusable:focus {clip: auto;height: auto;overflow: visible;border-bottom-color: var(--highlight);}}.visually-hidden {position: absolute;width: 1px;height: 1px;padding: 0;margin: -1px;overflow: clip;clip-path: inset(0);border: 0;}@media (prefers-reduced-motion: reduce) {html, html:focus-within {scroll-behavior: auto;}*, *::before, *::after {animation-duration: 0.01ms !important;animation-iteration-count: 1 !important;transition-duration: 0.01ms !important;scroll-behavior: auto !important;transition-delay: 0ms !important;}}.warning {color: var(--clr-warning);font-weight: 600;}.hide {display: none;}.theme-picker {position: absolute;top: 0.5rem;right: 1rem;z-index: 300;width: -moz-fit-content;width: fit-content;}.theme-icon {width: 2.4rem;height: 2.4rem;fill: var(--theme-icon);margin-right: 0.5rem;}.btn-theme-toggle {display: flex;align-items: center;padding: 0.5rem 0.5rem 0.75rem 0;border-width: 0 0 5px 0;border-bottom-style: solid;border-bottom-color: var(--clr-green);background-color: var(--theme-button-bg);color: var(--theme-txt);font-size: clamp(1.2rem, 1.1rem + 0.4444vw, 1.6rem);&:hover {opacity: 0.8;}& .mode {margin-inline-start: 0.5rem;}}.loader {position: fixed;z-index: 500;inset: 0;display: flex;align-items: center;justify-content: center;background: var(--clr-dark);}.loader-hidden {opacity: 0;visibility: hidden;}.loader::after {content: "Loading...";font-size: 5rem;}@media (prefers-reduced-motion: no-preference) {.loader {transition: opacity 0.75s, visibility 0.75s;}.loader::after {content: "";font-size: 0rem;width: 10rem;height: 10rem;border: 2rem solid var(--clr-lightest);border-top-color: var(--clr-green);border-radius: 50%;animation: loading 0.75s ease infinite;}@keyframes loading {from {transform: rotate(0turn);}to {transform: rotate(1turn);}}}.table-scroller {max-width: -moz-fit-content;max-width: fit-content;margin: 0 auto 5rem;}.table-entries-max-height {max-height: 70rem;}table {width: 100%;max-width: 120rem;min-width: 73.6rem;font-size: clamp(1.6rem, 1.4512rem + 0.3101vw, 1.8rem);margin: 0 auto;border-collapse: collapse;& th, & td {padding: 2rem 3rem;&:last-child {border-right: 0;}}& th {border-right: 3px solid var(--table-borders);&:last-child {border-right: 0;}}& td {border-right: 3px solid var(--table-borders);&:last-child {border-right: 0;}}& .table-headings {background-color: var(--tr-th);border-bottom: 3px solid var(--table-borders);}& .table-heading-shadow {box-shadow: var(--shadow);border-bottom-width: 0;}& .centred {text-align: center;}& .sticky {position: sticky;z-index: 1;top: 0;}& .delete {display: flex;align-items: center;justify-content: center;gap: 1rem;& .icon-delete {fill: var(--body-txt);width: 3.6rem;height: 3.6rem;}}& .date {display: flex;flex-wrap: wrap;align-items: center;justify-content: space-between;gap: 2rem;& .sort-button {display: flex;flex-direction: column;gap: 0;padding-block-end: 0.8rem;line-height: 1.1;font-weight: normal;}}& .items-container {display: flex;flex-wrap: wrap;align-items: center;gap: 2rem;& button {margin-left: auto;}}& .tbody {& tr:nth-child(odd) {background-color: var(--tr-odd-bg);}& tr:nth-child(even) {background-color: var(--tr-even-bg);}}& [contenteditable] {outline: 1px dotted var(--body-txt);padding: 1rem;cursor: default;}& .visually-hidden {top: -1000px;left: -1000px;}}button {background-color: var(--clr-dark-green);color: var(--clr-lightest);border: 3px solid var(--clr-green);border-radius: 0.5rem;padding: 0.5rem 1rem;&:hover {opacity: 0.8;}&[disabled] {pointer-events: none;opacity: 0.5;}}.toolbar {margin: 0 auto 1rem;display: flex;gap: 3rem;align-items: center;justify-content: space-between;max-width: 67rem;& h2 {margin-block-end: 0;}@media screen and (width <= 600px) {justify-content: center;gap: 1rem;flex-direction: column;}}input, select {background: var(--input-bg);color: var(--clr-darkest);border: 1px solid var(--body-txt);}.costs-form-wrapper {width: -moz-fit-content;width: fit-content;margin: 0 auto 5rem;}.costs-form {background-color: var(--costs-form-bg);display: flex;flex-wrap: wrap;align-items: center;gap: 2rem;padding: 3rem;& fieldset {border: 0;padding: 0;display: flex;align-items: center;gap: 1rem;}& label[for="pence"] {padding-inline-end: 0.7rem;font-weight: 700;}& input[type="number"] {width: 5ch;}}.summary {cursor: pointer;font-weight: 600;margin-bottom: 2rem;}.details {position: relative;--_content-max-width: 66rem;--_content-space-outside: 2rem;width: min(var(--_content-max-width), 100% - var(--_content-space-outside) * 2);margin-inline: auto;& .details-content {background-color: var(--header-footer-bg);border: 0.2rem solid var(--header-footer-border);padding: 1rem 2rem 4rem;& p, & li {text-align: left;}.close-button {padding-top: 1.5rem;}}}::-webkit-scrollbar {width: auto;}::-webkit-scrollbar-track {background-color: var(--clr-dark-green);}::-webkit-scrollbar-thumb {background-color: var(--clr-green);border-radius: 100vw;}::-webkit-scrollbar-thumb:hover {opacity: 0.8;}@supports (scrollbar-color: black grey) {* {scrollbar-color: var(--clr-green) var(--clr-dark-green);}} \ No newline at end of file diff --git a/local/css/table.css b/dist/css/table.css similarity index 100% rename from local/css/table.css rename to dist/css/table.css diff --git a/local/css/theme-switcher.css b/dist/css/theme-switcher.css similarity index 100% rename from local/css/theme-switcher.css rename to dist/css/theme-switcher.css diff --git a/local/css/theme.css b/dist/css/theme.css similarity index 100% rename from local/css/theme.css rename to dist/css/theme.css diff --git a/local/favicon.ico b/dist/favicon.ico similarity index 100% rename from local/favicon.ico rename to dist/favicon.ico diff --git a/local/index.html b/dist/index.html similarity index 94% rename from local/index.html rename to dist/index.html index b0da74e..8fa6aa4 100644 --- a/local/index.html +++ b/dist/index.html @@ -9,8 +9,8 @@ content="Record and save your daily costs. See the average daily cost over a number of days. Reorder entries if they get out of synch. Save entries to local storage."> Costs Calculator - - + + @@ -124,13 +124,21 @@

Average Spend

-

Daily Spend

-
+ +
+ +

Daily Spend

+ +
+ + +
- +
Daily spend
@@ -164,9 +172,7 @@

Daily Spend

- +