diff --git a/src/assets/css/blocks/blog.css b/src/assets/css/blocks/blog.css deleted file mode 100644 index 48a576b..0000000 --- a/src/assets/css/blocks/blog.css +++ /dev/null @@ -1,16 +0,0 @@ -.blog h1 { - font-size: var(--size-step-4); -} - -.blog h2 { - font-size: var(--size-step-3); -} - -.blog h3 { - font-size: var(--size-step-2); -} - -.blog img { - max-inline-size: var(--max-img-width, 100%); - block-size: auto; -} diff --git a/src/assets/css/blocks/button.css b/src/assets/css/blocks/button.css index b020307..27c597d 100644 --- a/src/assets/css/blocks/button.css +++ b/src/assets/css/blocks/button.css @@ -1,20 +1,46 @@ .button { - color: var(--button-text, var(--color-dark)); - background-color: var(--button-bg, var(--color-light)); - border: 2px solid var(--button-border, var(--color-dark)); + color: var(--button-text, var(--color-text)); + background-color: var(--button-bg, var(--color-bg)); + border: 2px solid var(--button-border, var(--color-text)); border-radius: var(--border-radius); display: inline-block; font: inherit; - padding: 0.3em 1em; + padding: 0.3rem var(--space-s); font-weight: 700; - transition-property: background-color, border; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-timing); text-decoration: none; + text-align: center; } -.button:hover { - --button-bg: var(--color-dark); - --button-text: var(--color-light); - --button-border: var(--color-dark); +.button:hover, +.button[aria-current='page'], +.button[aria-pressed='true'] { + background-size: 150% 150%; + --button-bg: var(--color-text); + --button-text: var(--color-bg); + --button-border: var(--color-text); +} + +.button:active { + transform: scale(99%); +} + +.button:where(:has(svg)) { + display: flex; + gap: 0.5em; + align-items: center; +} + +.button:where(:has(.visually-hidden)) { + border-radius: 50%; + padding: 0.5em; +} + +/* all buttons have a min size */ +.button:where(:not(:has(svg))) { + text-align: center; + min-inline-size: 6ch; +} + +.button:where(:not(:has(.visually-hidden))) { + padding: var(--button-padding, 0.35em 1em); } diff --git a/src/assets/css/blocks/card.css b/src/assets/css/blocks/card.css index 3d6c103..f91a81b 100644 --- a/src/assets/css/blocks/card.css +++ b/src/assets/css/blocks/card.css @@ -1,21 +1,23 @@ .card { - background: var(--color-dark); - border: 4px solid var(--color-dark); - color: var(--color-light); - padding: var(--space-m-l); + background-color: var(--color-bg-accent); + border: 3px solid var(--color-bg-accent); + color: var(--color-text); + padding: var(--space-s-m); border-radius: var(--border-radius); max-inline-size: unset; } .card ::selection { color: var(--color-dark); - background: var(--color-secondary); + background-color: var(--color-secondary); } -.card h2 { - font-size: var(--size-step-3); +.card h2, +.card h3 { + font-family: var(--font-base); + font-size: var(--size-step-2); + font-weight: 700; } - .card h2 a, .card h3 a { text-decoration: none; @@ -23,11 +25,7 @@ .card:hover, .card:focus-within { - border: 4px solid var(--color-primary); -} - -.card a { - text-decoration: none; + border: 3px solid var(--color-primary); } /* 'clickable' */ @@ -46,3 +44,7 @@ right: 0; top: 0; } + +.blogcards { + --gutter: var(--space-l); +} diff --git a/src/assets/css/blocks/code.css b/src/assets/css/blocks/code.css index 7f28e82..a4513d2 100644 --- a/src/assets/css/blocks/code.css +++ b/src/assets/css/blocks/code.css @@ -1,15 +1,31 @@ +code { + --color-code-red: var(--color-primary); + --color-code-orange: hsl(30, 70%, 60%); + --color-code-yellow: var(--color-terriary); + --color-code-blue: var(--color-secondary); + --color-code-indigo: hsl(260, 48%, 56%); + --color-code-violet: hsl(314, 70%, 60%); + --color-code-pink: hsl(350, 70%, 60%); + --color-code-gray: hsl(0, 0%, 58%); +} + +pre { + --dark-bg: color-mix(in oklab, var(--color-bg) 92%, black); + grid-column: popout !important; +} + code, pre { - padding: 0.125em 0.4em; font-family: var(--font-mono); - background: var(--color-dark); + font-size: var(--size-step-min-1); + line-height: 1.4; + background-color: var(--color-bg-accent); + padding: 0.1em 0.4em; border-radius: var(--border-radius); - color: var(--color-light); - font-size: var(--size-step-0); } pre[class*='language-'] { - padding: var(--space-s-m); + padding: var(--space-m-l); } code[class*='language-'] { @@ -23,25 +39,43 @@ pre[class*='language-'] { word-spacing: normal; word-break: normal; word-wrap: normal; - color: var(--color-light); - background: var(--color-dark); + color: var(--color-text); + background: var(--color-bg); line-height: 1.5; border-radius: var(--border-radius); - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; hyphens: none; } -:not(pre) > code[class*='language-'] { - white-space: normal; - border-radius: var(--border-radius); - padding: 0.1em; +@media (prefers-color-scheme: dark) { + code[class*='language-'], + pre[class*='language-'] { + background-color: var(--dark-bg); + } +} + +:root[data-theme='light'] { + code[class*='language-'], + pre[class*='language-'] { + background-color: var(--color-bg-accent); + } +} + +/* Dark Color Scheme (Override) */ +:root[data-theme='dark'] { + code[class*='language-'], + pre[class*='language-'] { + background-color: var(--dark-bg); + } +} + +:where(:not(pre)) > code { + position: relative; + top: -0.1em; + background-color: var(--color-bg-accent); +} + +:where(:not(a, pre, blockquote)) > code { + color: var(--color-text-accent); } pre[class*='language-'] { @@ -52,7 +86,7 @@ pre[class*='language-'] { .language-css > code, .language-sass > code, .language-scss > code { - color: #fd9170; + color: var(--color-code-violet); } [class*='language-'] .namespace { @@ -60,163 +94,172 @@ pre[class*='language-'] { } .token.atrule { - color: #d2b1e7; + color: var(--color-code-red); } .token.attr-name { - color: #ffcb6b; + color: var(--color-code-yellow); } .token.attr-value { - color: #80cbc4; + color: var(--color-code-blue); } .token.attribute { - color: #80cbc4; + color: var(--color-code-blue); } .token.boolean { - color: #d2b1e7; + color: var(--color-code-red); } .token.builtin { - color: #ffcb6b; + color: var(--color-code-yellow); } .token.cdata { - color: #80cbc4; + color: var(--color-code-orange); } .token.char { - color: #80cbc4; + color: var(--color-code-orange); } .token.class { - color: #ffcb6b; + color: var(--color-code-yellow); } .token.class-name { - color: #ff8b59; + color: var(--color-code-yellow); } .token.color { - color: #ff8b59; + color: var(--color-code-yellow); } .token.comment { - color: #779daf; + color: var(--color-code-gray); } .token.constant { - color: #d2b1e7; + color: var(--color-code-red); } .token.deleted { - color: #ee979c; + color: var(--color-code-pink); } .token.doctype { - color: #546e7a; + color: var(--color-code-orange); } .token.entity { - color: #ee979c; + color: var(--color-code-pink); } .token.function { - color: #d2b1e7; + color: var(--color-code-red); } .token.hexcode { - color: #ff8b59; + color: var(--color-code-yellow); } .token.id { - color: #d2b1e7; + color: var(--color-code-red); font-weight: bold; } .token.important { - color: #d2b1e7; + color: var(--color-code-red); font-weight: bold; } .token.inserted { - color: #80cbc4; + color: var(--color-code-orange); } .token.keyword { - color: #d2b1e7; + color: var(--color-code-red); font-style: italic; } .token.number { - color: #fd9170; + color: var(--color-code-violet); } .token.operator { - color: #89ddff; + color: var(--color-code-indigo); } .token.prolog { - color: #546e7a; + color: var(--color-code-orange); } .token.property { - color: #80cbc4; + color: var(--color-code-orange); } .token.pseudo-class { - color: #80cbc4; + color: var(--color-code-blue); } .token.pseudo-element { - color: #80cbc4; + color: var(--color-code-blue); } .token.punctuation { - color: #80cbc4; + color: var(--color-code-indigo); } .token.regex { - color: #ff8b59; + color: var(--color-code-yellow); } .token.selector { - color: #ee979c; + color: var(--color-code-pink); } .token.string { - color: #f48ea2; + color: var(--color-code-blue); } .token.symbol { - color: #d2b1e7; + color: var(--color-code-red); } .token.tag { - color: #ee979c; + color: var(--color-code-pink); } .token.unit { - color: #ee979c; + color: var(--color-code-pink); } .token.url { - color: #fd9170; + color: var(--color-code-violet); } .token.variable { - color: #ee979c; + color: var(--color-code-pink); } -.codepen { - padding: var(--space-xs); - color: var(--color-primary); - border: 2px dashed var(--color-primary); +/* CodePen iframe */ +.codepen a { + --icon-size: 1.2em; + + display: flex; + align-items: center; + gap: var(--space-2xs); +} + +.prose .cp_embed_wrapper, +.prose .cp_embed_wrapper + script + *:not(h2) { + --flow-space: var(--space-l); } .cp_embed_wrapper { + grid-column: popout; position: relative; overflow: auto; display: grid; @@ -227,5 +270,5 @@ pre[class*='language-'] { .cp_embed_wrapper iframe { grid-area: container; - inline-size: 100%; + width: 100%; } diff --git a/src/assets/css/blocks/external-link.css b/src/assets/css/blocks/external-link.css new file mode 100644 index 0000000..9af757d --- /dev/null +++ b/src/assets/css/blocks/external-link.css @@ -0,0 +1,25 @@ +article + [href^='http']:not([href*='localhost:8080']):not( + [href*='eleventy-excellent.netlify.app'] + ):not(.button) { + padding-inline-end: 0.8em; +} + +article + [href^='http']:not([href*='localhost:8080']):not( + [href*='eleventy-excellent.netlify.app'] + ):not(.no-indicator)::after { + position: absolute; + display: inline-block; + inline-size: 1em; + block-size: 1em; + background-image: url('/assets/images/template/external.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: 60% auto; + /* alternative text rules */ + content: '(enlace externo)'; + overflow: hidden; + white-space: nowrap; + text-indent: 1em; /* the width of the icon */ +} diff --git a/src/assets/css/blocks/gallery.css b/src/assets/css/blocks/gallery.css new file mode 100644 index 0000000..76f0b69 --- /dev/null +++ b/src/assets/css/blocks/gallery.css @@ -0,0 +1,15 @@ +dialog { + border: none; + border-radius: var(--border-radius); +} + +dialog + button { + all: unset; + cursor: pointer; +} + +dialog::backdrop { + background-image: var(--gradient-stripes); + opacity: 0.85; + filter: brightness(50%); +} diff --git a/src/assets/css/blocks/grid-card.css b/src/assets/css/blocks/grid-card.css new file mode 100644 index 0000000..b22f0f1 --- /dev/null +++ b/src/assets/css/blocks/grid-card.css @@ -0,0 +1,14 @@ +.grid-card { + display: grid; + gap: 2ch; + grid-row: span 3; + grid-template-rows: subgrid; +} + +.grid-card img { + max-inline-size: var(--max-img-width, 100%); + block-size: auto; + aspect-ratio: 12/9; + object-fit: cover; + object-position: center; +} diff --git a/src/assets/css/blocks/menu.css b/src/assets/css/blocks/menu.css deleted file mode 100644 index 28b9b19..0000000 --- a/src/assets/css/blocks/menu.css +++ /dev/null @@ -1,117 +0,0 @@ -@media (min-width: 38em) { - nav.navbar { - --nav-button-display: none; - --nav-position: static; - } - - nav.navbar ul { - --nav-list-background: transparent; - --nav-list-layout: row; - --nav-list-position: static; - --nav-list-padding: 0; - --nav-list-height: auto; - --nav-list-width: 100%; - --nav-list-shadow: none; - --nav-list-transform: none; - --nav-list-visibility: visible; - } -} - -/* set on parent div to get the right z-index context */ -.ontop { - z-index: 1; - position: relative; -} - -nav.navbar { - position: var(--nav-position, absolute); - /* inset-block-start: 0.5rem; */ - inset-inline-end: 0.1rem; -} - -/* Remove default list styling and create layout for list */ -nav.navbar ul { - background: var(--nav-list-background, var(--color-light)); - box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2)); - display: flex; - flex-direction: var(--nav-list-layout, column); - gap: var(--space-s); - block-size: var(--nav-list-height, 100vh); - list-style: none; - margin: 0; - padding: var(--nav-list-padding, var(--space-l) var(--space-s)); - position: var(--nav-list-position, fixed); - inset-block-start: 0; /* Logical property. Equivalent to top: 0; */ - inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */ - inline-size: var(--nav-list-width, min(22rem, 100vw)); - visibility: var(--nav-list-visibility, visible); -} - -nav.navbar [aria-expanded='false'] + ul { - transform: var(--nav-list-transform, translateX(100%)); - visibility: var(--nav-list-visibility, hidden); -} - -/* animates ul only when opening to avoid flash on page load, svg always */ -@media (prefers-reduced-motion: no-preference) { - nav.navbar [aria-expanded='true'] + ul, - nav.navbar svg { - transition: transform 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55), - visibility 0.05s linear; - } -} - -/* Basic link styling */ -nav.navbar a { - --text-color: var(--color-dark); - color: var(--text-color); - padding: 0.1rem; - text-decoration: none; - display: block; - text-decoration-line: underline; - text-decoration-color: var(--border-color, transparent); - text-decoration-thickness: 3px; - text-underline-offset: 0.3em; -} - -/* Change the border-color on :hover and :focus */ -nav.navbar a:where(:hover, :focus) { - --border-color: var(--text-color); -} - -/* Change border-color and color for the active page */ -nav.navbar [aria-current='page'] { - --border-color: var(--color-primary); - --text-color: var(--color-primary); -} - -/* Reset button styling */ -nav.navbar button { - all: unset; - display: var(--nav-button-display, flex); - align-items: center; - position: relative; - z-index: 2; - cursor: pointer; - align-items: center; - padding: var(--space-xs) 0; -} - -nav.navbar span { - font-size: var(--size-step-min-1); - font-weight: bold; - text-transform: uppercase; - padding-inline-end: var(--space-2xs); -} - -nav.navbar svg { - block-size: 100%; - inline-size: auto; -} -header svg { - transform: translateY(-0.1em); -} - -nav.navbar [aria-expanded='true'] svg { - transform: var(--nav-list-rotate, rotate(45deg)); -} diff --git a/src/assets/css/blocks/page.css b/src/assets/css/blocks/page.css deleted file mode 100644 index e3880f0..0000000 --- a/src/assets/css/blocks/page.css +++ /dev/null @@ -1,5 +0,0 @@ -.page img { - max-inline-size: var(--max-img-width, 100%); - block-size: auto; - border: 1px solid var(--color-dark); -} diff --git a/src/assets/css/blocks/pagination.css b/src/assets/css/blocks/pagination.css new file mode 100644 index 0000000..0b191b5 --- /dev/null +++ b/src/assets/css/blocks/pagination.css @@ -0,0 +1,41 @@ +.pagination { + --gutter: var(--space-xs-s); +} + +.pagination li { + color: var(--pagination-text, var(--color-text)); + background-color: var(--pagination-bg, var(--color-bg)); + border: 3px solid var(--pagination-border, var(--color-bg-accent)); + border-radius: var(--border-radius); +} + +.pagination li:not(:has(a)) { + padding: var(--space-xs) var(--space-s-m); + opacity: 0.6; +} + +.pagination a { + text-decoration: none; +} + +.pagination a { + padding: var(--space-xs) var(--space-s-m); + text-decoration: none; + display: block; +} + +.pagination li:not(:has(a)) { + padding: var(--space-xs) var(--space-s-m); + opacity: 0.6; +} + +.pagination li:has(a:hover) { + --pagination-bg: var(--color-bg-accent); + --pagination-border: var(--color-bg-accent); +} + +.pagination li:has(a[aria-current='page']) { + --pagination-bg: var(--color-secondary); + --pagination-border: var(--color-secondary); + --pagination-text: var(--color-base-light); +} diff --git a/src/assets/css/blocks/post.css b/src/assets/css/blocks/post.css new file mode 100644 index 0000000..0d327c6 --- /dev/null +++ b/src/assets/css/blocks/post.css @@ -0,0 +1,19 @@ +.post h1 { + font-size: var(--size-step-6); +} + +.post h2 { + font-size: var(--size-step-3); +} + +.post h3 { + font-size: var(--size-step-2); +} + +.post img { + max-inline-size: var(--max-img-width, 100%); + block-size: auto; + aspect-ratio: 16/9; + object-fit: cover; + object-position: center; +} diff --git a/src/assets/css/blocks/prose.css b/src/assets/css/blocks/prose.css index 64f0e37..f52dba5 100644 --- a/src/assets/css/blocks/prose.css +++ b/src/assets/css/blocks/prose.css @@ -1,27 +1,56 @@ .prose { - --flow-space: var(--space-m-l); - --wrapper-width: clamp(16rem, 93vw, 55rem); + --flow-space: var(--space-m); + --wrapper-width: 64rem; } -.prose :is(h2, h3, h4) + * { +.prose :is(pre, pre + *, figure, figure + *) { --flow-space: var(--space-s-m); } -.prose .heading-anchor:is(:hover, :focus) { - text-decoration: underline; +.prose figcaption { + font-size: var(--size-step-min-1); + text-align: center; + padding-block-end: var(--space-xs); + border-bottom: 1px solid var(--color-bg-accent); } + +.prose :is(h2, h3, h4) { + --flow-space: var(--space-l-xl); +} + +.prose :is(h2 + *, h3 + *, h4 + *):not(figure) { + --flow-space: var(--space-s); +} + +.prose .heading-anchor:is(:hover, :focus) { + text-decoration: none; +} + .prose .heading-anchor { text-decoration: none; } .prose mark { - background: var(--color-primary-glare); + background-color: var(--color-tertiary); + color: var(--color-base-dark); } -.prose :not(.grid) li + li { - margin-top: var(--space-s); +/* block space only for "regular lists" */ +.prose :not(.cluster):not(.grid) > li + li { + padding-block-start: var(--space-s-m); } -.prose :when(ul:not(.grid), ol:not(.grid)) { - padding-inline-start: var(--space-s); +/* inline space only for "regular lists" */ +.prose :where(ul:not(.grid), ol:not(.grid)) { + padding-inline-start: var(--space-m); +} + +/* marker only for "regular lists" */ +.prose :where(ul:not(.grid)) li::marker { + color: var(--color-primary); + content: '- '; +} + +.prose img { + border-radius: var(--border-radius); } diff --git a/src/assets/css/blocks/section.css b/src/assets/css/blocks/section.css index be454cd..1f68912 100644 --- a/src/assets/css/blocks/section.css +++ b/src/assets/css/blocks/section.css @@ -3,8 +3,8 @@ } .section__inner { - background: var(--spot-color, var(--color-dark)); - color: var(--color-light); + background-color: var(--spot-color, var(--color-bg-accent)); + color: var(--color-text); } .section blockquote { diff --git a/src/assets/css/blocks/seperator.css b/src/assets/css/blocks/seperator.css index 044c3d0..59e85fd 100644 --- a/src/assets/css/blocks/seperator.css +++ b/src/assets/css/blocks/seperator.css @@ -2,5 +2,5 @@ display: block; block-size: 3.5em; inline-size: 100%; - fill: var(--spot-color, var(--color-light)); + fill: var(--spot-color, var(--color-bg)); } diff --git a/src/assets/css/blocks/site-foot.css b/src/assets/css/blocks/site-foot.css index 44ad8f3..3f8818b 100644 --- a/src/assets/css/blocks/site-foot.css +++ b/src/assets/css/blocks/site-foot.css @@ -1,12 +1,12 @@ .site-foot { + margin-block-start: var(--space-l-xl); padding: var(--space-s-m); - background: var(--color-dark); - color: var(--color-light); + color: var(--color-text); } .site-foot__inner { display: flex; - gap: var(--space-s); + gap: var(--space-xs) var(--space-s); justify-content: center; align-items: center; } @@ -16,6 +16,25 @@ } .site-foot svg { + inline-size: 1em; block-size: 0.9em; - inline-size: 0.9em; +} + +.site-foot .creator { + text-decoration: none; +} + +.site-foot .creator { + text-decoration: none; +} +.site-foot .creator:hover { + color: transparent; + background-image: var(--gradient-rainbow); + background-size: 100%; + background-repeat: repeat; + background-clip: text; +} + +.site-foot .creator:hover svg { + color: var(--color-text); } diff --git a/src/assets/css/blocks/site-head.css b/src/assets/css/blocks/site-head.css deleted file mode 100644 index 0c361d8..0000000 --- a/src/assets/css/blocks/site-head.css +++ /dev/null @@ -1,6 +0,0 @@ -.site-head { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; -} diff --git a/src/assets/css/blocks/site-logo.css b/src/assets/css/blocks/site-logo.css index 815ac06..da3948d 100644 --- a/src/assets/css/blocks/site-logo.css +++ b/src/assets/css/blocks/site-logo.css @@ -1,10 +1,8 @@ .logo { + --gutter: var(--space-xs); + padding: var(--space-s) 0; + font-size: var(--size-step-0); font-weight: bold; text-transform: uppercase; - display: flex; - align-items: center; - gap: var(--space-2xs); - letter-spacing: var(--tracking-s); - padding: var(--space-xs) 0; - font-size: var(--size-step-1); + text-decoration: none; } diff --git a/src/assets/css/blocks/site-nav.css b/src/assets/css/blocks/site-nav.css new file mode 100644 index 0000000..5f2edb4 --- /dev/null +++ b/src/assets/css/blocks/site-nav.css @@ -0,0 +1,72 @@ +/* Basic link styling */ +.site-nav ul { + list-style: none; + margin: 0; + gap: var(--space-xs); + line-height: 0.5em; + padding-block-end: var(--space-s); +} + +.site-nav a { + --text-color: var(--color-text); + --background-color: var(--color-bg); + --border-color: var(--color-bg-accent-2); + background-color: var(--background-color); + color: var(--text-color); + padding: var(--space-s); + text-decoration: none; + display: block; + border-radius: var(--border-radius); + border: 1px solid var(--border-color); +} + +/* Change the border-color on :hover and :focus */ +.site-nav a:where(:hover, :focus) { + --background-color: var(--color-text); + --text-color: var(--color-bg); + --border-color: var(--color-bg); +} + +/* Change border-color and color for the active page. data-state='active' if a child is active. */ +.site-nav [aria-current='page'], +.site-nav [data-state='active'] { + --background-color: var(--color-text); + --text-color: var(--color-bg); + --border-color: var(--color-bg); +} + +@media screen(md) { + /* Basic link styling */ + .site-nav ul { + padding-block-end: 0; + } + + .site-nav a { + --text-color: var(--color-text); + --background-color: transparent; + --border-color: transparent; + --text-decoration: transparent; + background-color: var(--background-color); + color: var(--text-color); + padding: var(--space-xs) 0.2em; + text-decoration-line: underline; + text-decoration-color: var(--text-decoration, transparent); + text-decoration-thickness: 3px; + text-underline-offset: 0.2em; + } + + /* Change the border-color on :hover and :focus */ + .site-nav a:where(:hover, :focus) { + --text-decoration: var(--color-text-accent); + --text-color: var(--color-text); + --background-color: transparent; + } + + /* Change border-color and color for the active page */ + .site-nav [aria-current='page'], + .site-nav [data-state='active'] { + --text-decoration: var(--color-primary); + --text-color: var(--color-primary); + --background-color: transparent; + } +} diff --git a/src/assets/css/blocks/skip-link.css b/src/assets/css/blocks/skip-link.css index e1b2ec4..96b327d 100644 --- a/src/assets/css/blocks/skip-link.css +++ b/src/assets/css/blocks/skip-link.css @@ -15,9 +15,10 @@ block-size: auto; overflow: visible; inline-size: auto; - background-color: var(--color-dark); - color: var(--color-light); - padding: var(--space-s-m); + background-color: var(--color-text); + color: var(--color-bg); + padding: var(--space-xs) var(--space-s-m); + border-radius: var(--border-radius); line-height: 1; } diff --git a/src/assets/css/blocks/styleguide.css b/src/assets/css/blocks/styleguide.css new file mode 100644 index 0000000..8bdf14d --- /dev/null +++ b/src/assets/css/blocks/styleguide.css @@ -0,0 +1,60 @@ +.styleguide :is(h2, h3) { + font-size: var(--size-step-0); + font-family: var(--font-base); + text-transform: uppercase; +} + +.styleguide h2 { + letter-spacing: var(--tracking-wide); +} + +.styleguide section { + padding: var(--space-l-xl); + outline: 2px solid var(--color-bg-accent); /* Increase the outline thickness for better visibility */ + outline-offset: -1px; /* Negative value to make outlines overlap */ +} + +.styleguide .colors { + --cluster-vertical-alignment: flex-start; +} + +.styleguide .colors ul { + --min: 10ch; + --gap: var(--space-s-m); + + display: grid; + grid-gap: var(--gap); + /* min() with 100% prevents overflow + in extra narrow spaces */ + grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr)); +} + +.styleguide .colors li { + display: grid; + gap: var(--space-xs); + grid-row: span 2; + grid-template-rows: subgrid; +} + +.styleguide .colors li div { + max-inline-size: var(--max-img-width, 100%); + block-size: auto; + aspect-ratio: 16/9; + object-fit: cover; + object-position: center; + border: 1px solid var(--color-text); +} + +.styleguide .space { + background-color: var(--color-text); + display: block; +} + +.styleguide .tabs { + align-items: center; + border-block-end: 1px solid #d1d8e0; + display: flex; + gap: var(--space-xs); + margin-block-end: var(--space-s); + padding-block-end: var(--space-s); +} diff --git a/src/assets/css/blocks/table.css b/src/assets/css/blocks/table.css new file mode 100644 index 0000000..156e03b --- /dev/null +++ b/src/assets/css/blocks/table.css @@ -0,0 +1,87 @@ +table { + border: 0; + inline-size: 100%; +} +table br { + display: none; +} + +thead { + border: none; + clip: rect(0 0 0 0); + block-size: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + inline-size: 1px; +} + +tr { + border: 1px solid var(--color-text); + display: block; + margin-block-end: var(--space-s); +} + +th, +td { + padding: var(--space-xs) var(--space-s); + vertical-align: sub; +} + +td { + border-block-end: 1px solid var(--color-text); + display: block; + text-align: start; +} +td::before { + content: attr(data-label); + float: start; + font-weight: bold; +} +td:last-child { + border-block-end: 0; +} + +@media screen(sm) { + table { + border-collapse: collapse; + margin: 0; + padding: 0; + table-layout: fixed; + } + table br { + display: block; + } + thead { + position: static; + text-align: start; + display: table-header-group; + } + caption { + margin: var(--space-xs) 0 var(--space-s); + } + tr { + border: 0; + padding: var(--space-xs); + margin: 0; + display: table-row; + } + + tr:not(:last-child) { + border-block-end: 1px solid var(--color-bg-accent); + } + + td { + border: none; + } + td::before { + display: none; + } + th, + td { + padding: var(--space-s); + text-align: start; + display: table-cell; + } +} diff --git a/src/assets/css/blocks/tag.css b/src/assets/css/blocks/tag.css new file mode 100644 index 0000000..ef5e47d --- /dev/null +++ b/src/assets/css/blocks/tag.css @@ -0,0 +1,28 @@ +/* always in combination with .button */ + +.taglist { + --gutter: var(--space-s-m); +} + +.post-tag { + --button-bg: var(--color-text); + --button-text: var(--color-bg); + --button-border: var(--color-text); + font-size: var(--size-step-min-2); + text-transform: uppercase; + padding: 0.1rem 0.625rem; + font-weight: 700; +} + +.card .post-tag { + --button-bg: var(--color-bg-accent-2); + --button-text: var(--color-text); + --button-border: var(--color-bg-accent-2); + margin-inline-start: var(--space-s-m); +} + +/* layout */ + +.tags h1 { + font-size: var(--size-step-4); +} diff --git a/src/assets/css/blocks/textgradient.css b/src/assets/css/blocks/textgradient.css index 3bcb046..b28d6b3 100644 --- a/src/assets/css/blocks/textgradient.css +++ b/src/assets/css/blocks/textgradient.css @@ -1,13 +1,15 @@ .gradient-text { color: transparent; - background: conic-gradient( - var(--color-primary) 0 33%, - var(--color-secondary) 0 55%, - #1471bb 0 70%, - #ff8b59 0 87%, - #c569bc 0 100% - ); + background-image: var(--gradient-conic); padding: 0.6rem 0; background-size: 50%; background-clip: text; } + +.gradient-text-linear { + color: transparent; + background-image: var(--gradient-rainbow); + background-size: 100%; + background-repeat: repeat; + background-clip: text; +} diff --git a/src/assets/css/blocks/theme-switch.css b/src/assets/css/blocks/theme-switch.css new file mode 100644 index 0000000..2d6e358 --- /dev/null +++ b/src/assets/css/blocks/theme-switch.css @@ -0,0 +1,12 @@ +.theme-switch h2 { + font-size: var(--size-step-min-1); + font-family: var(--font-base); +} + +.theme-switch .button { + --button-border: var(--color-bg-accent-2); + border-radius: var(--border-radius); + font-size: var(--size-step-min-1); + padding: 0.1rem 0; + font-weight: 600; +} diff --git a/src/assets/css/compositions/cluster.css b/src/assets/css/compositions/cluster.css index 9869633..ca5dc9b 100644 --- a/src/assets/css/compositions/cluster.css +++ b/src/assets/css/compositions/cluster.css @@ -1,7 +1,24 @@ +/* +CLUSTER +More info: https://every-layout.dev/layouts/cluster/ +A layout that lets you distribute items with consitent +spacing, regardless of their size + +CUSTOM PROPERTIES AND CONFIGURATION +--gutter (var(--space-s-m)): This defines the space +between each item. + +--cluster-horizontal-alignment (flex-start) How items should align +horizontally. Can be any acceptable flexbox aligmnent value. + +--cluster-vertical-alignment How items should align vertically. +Can be any acceptable flexbox alignment value. +*/ + .cluster { display: flex; flex-wrap: wrap; - gap: var(--space, 1rem); - justify-content: flex-start; - align-items: center; + gap: var(--gutter, var(--space-s-l)); + justify-content: var(--cluster-horizontal-alignment, flex-start); + align-items: var(--cluster-vertical-alignment, center); } diff --git a/src/assets/css/compositions/grid.css b/src/assets/css/compositions/grid.css index 25bcee0..e55e9dd 100644 --- a/src/assets/css/compositions/grid.css +++ b/src/assets/css/compositions/grid.css @@ -13,13 +13,14 @@ ideally, as a minimum. --grid-placement (auto-fill): Set either auto-fit or auto-fill to change how empty grid tracks are handled */ + .grid { display: grid; grid-template-columns: repeat( var(--grid-placement, auto-fill), minmax(var(--grid-min-item-size, 16rem), 1fr) ); - gap: var(--gutter, var(--space-s-l)); + gap: var(--gutter, var(--space-s-m)); } .grid[data-rows='masonry'] { diff --git a/src/assets/css/compositions/reel.css b/src/assets/css/compositions/reel.css new file mode 100644 index 0000000..ad4c59e --- /dev/null +++ b/src/assets/css/compositions/reel.css @@ -0,0 +1,41 @@ +/* + REEL + A layout that creates a carousel-like element + + + CONFIGURATION + Add an attribute of data-scroll="snap" to the element + to enable scroll snapping +*/ + +.reel { + --reel-space: 2rem; + display: flex; + block-size: auto; + max-inline-size: 100%; + margin-inline: auto; + + /* Padding allows child element hover states to show */ + padding: 0.5rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +.reel > * { + flex-basis: var(--reel-item-width, calc(33.333% - var(--reel-space))); + flex-shrink: 0; +} + +.reel > * + * { + margin-inline-start: var(--reel-space); +} + +/* SCROLL TYPE EXCEPTION + Sets the reel to snap on each item on scroll */ +.reel[data-scroll='snap'] { + scroll-snap-type: x mandatory; +} + +.reel[data-scroll='snap'] > * { + scroll-snap-align: start; +} diff --git a/src/assets/css/compositions/repel.css b/src/assets/css/compositions/repel.css new file mode 100644 index 0000000..c079f05 --- /dev/null +++ b/src/assets/css/compositions/repel.css @@ -0,0 +1,24 @@ +/* +REPEL +A little layout that pushes items away from each other where +there is space in the viewport and stacks on small viewports + +CUSTOM PROPERTIES AND CONFIGURATION +--gutter (var(--space-s-m)): This defines the space +between each item. + +--repel-vertical-alignment How items should align vertically. +Can be any acceptable flexbox alignment value. +*/ + +.repel { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: var(--repel-vertical-alignment, center); + gap: var(--gutter, var(--space-s-l)); +} + +.repel[data-nowrap] { + flex-wrap: nowrap; +} diff --git a/src/assets/css/compositions/sidebar.css b/src/assets/css/compositions/sidebar.css new file mode 100644 index 0000000..364fea8 --- /dev/null +++ b/src/assets/css/compositions/sidebar.css @@ -0,0 +1,51 @@ +/* +SIDEBAR +More info: https://every-layout.dev/layouts/sidebar/ +A layout that allows you to have a flexible main content area +and a "fixed" width sidebar that sits on the left or right. +If there is not enough viewport space to fit both the sidebar +width *and* the main content minimum width, they will stack +on top of each other + +CUSTOM PROPERTIES AND CONFIGURATION +--gutter (var(--space-size-1)): This defines the space +between the sidebar and main content. + +--sidebar-target-width (20rem): How large the sidebar should be + +--sidebar-content-min-width(50%): The minimum size of the main content area + +EXCEPTIONS +.sidebar[data-direction='rtl']: flips the sidebar to be on the right +*/ + +.sidebar { + display: flex; + flex-wrap: wrap; + gap: var(--gutter, var(--space-s-l)); +} + +.sidebar:not([data-direction]) > :first-child { + flex-basis: var(--sidebar-target-width, 20rem); + flex-grow: 1; +} + +.sidebar:not([data-direction]) > :last-child { + flex-basis: 0; + flex-grow: 999; + min-inline-size: var(--sidebar-content-min-width, 50%); +} + +/* +A flipped version where the sidebar is on the right +*/ +.sidebar[data-direction='rtl'] > :last-child { + flex-basis: var(--sidebar-target-width, 20rem); + flex-grow: 1; +} + +.sidebar[data-direction='rtl'] > :first-child { + flex-basis: 0; + flex-grow: 999; + min-inline-size: var(--sidebar-content-min-width, 50%); +} diff --git a/src/assets/css/compositions/switcher.css b/src/assets/css/compositions/switcher.css new file mode 100644 index 0000000..1478d94 --- /dev/null +++ b/src/assets/css/compositions/switcher.css @@ -0,0 +1,34 @@ +/* +SWITCHER +More info: https://every-layout.dev/layouts/switcher/ +A layout that allows you to lay **2** items next to each other +until there is not enough horizontal space to allow that. + +CUSTOM PROPERTIES AND CONFIGURATION +--gutter (var(--space-size-1)): This defines the space +between each item + +--switcher-target-container-width (40rem): How large the container +needs to be to allow items to sit inline with each other + +--switcher-vertical-alignment How items should align vertically. +Can be any acceptable flexbox alignment value. +*/ +.switcher { + display: flex; + flex-wrap: wrap; + gap: var(--gutter, var(--space-s-l)); + align-items: var(--switcher-vertical-alignment, flex-start); +} + +.switcher > * { + flex-grow: 1; + flex-basis: calc((var(--switcher-target-container-width, 40rem) - 100%) * 999); +} + +/* Max 2 items, +so we target everything *after* those */ +.switcher > :nth-last-child(n + 3), +.switcher > :nth-last-child(n + 3) ~ * { + flex-basis: 100%; +} diff --git a/src/assets/css/global/global-styles.css b/src/assets/css/global/global-styles.css index 18941ff..a32b07a 100644 --- a/src/assets/css/global/global-styles.css +++ b/src/assets/css/global/global-styles.css @@ -4,15 +4,18 @@ Low-specificity, global styles that apply to the whole project: https://cube.fyi/css.html */ + body { - color: var(--color-dark); - background-color: var(--color-light); - font-size: var(--size-step-1); + color: var(--color-text); + background-color: var(--color-bg); + font-size: var(--size-step-0); font-family: var(--font-base); line-height: 1.4; letter-spacing: var(--tracking); display: flex; flex-direction: column; + font-weight: 500; + accent-color: var(--color-primary); } main { @@ -23,13 +26,14 @@ main { h1, h2, h3 { - line-height: 1; + line-height: 1.2; letter-spacing: var(--tracking-s); + font-weight: 700; font-family: var(--font-display); } h1 { - font-size: var(--size-step-5); + font-size: var(--size-step-6); } h2 { @@ -37,20 +41,14 @@ h2 { } h3 { - font-size: var(--size-step-3); + font-size: var(--size-step-2); } /* Set line lengths */ p, li, blockquote:not([class]) { - max-inline-size: 50ch; -} - -h1, -h2, -h3 { - max-inline-size: 20ch; + max-inline-size: 65ch; } blockquote { @@ -89,46 +87,40 @@ a:hover { text-decoration: none; } -:focus { - outline: 3px solid; - outline-offset: 0.3ch; +strong { + font-weight: 800; } -:target { - scroll-margin-top: 2ex; +:focus-visible { + outline: 2px solid; + outline-offset: 0.3ch; } main:focus { outline: none; } -article [href^='http']:not([href*='eleventy-excellent.netlify.app']) { - padding-inline-end: 0.8em; -} - -article - [href^='http']:not([href*='eleventy-excellent.netlify.app']):not(.no-indicator)::after { - position: absolute; - display: inline-block; - inline-size: 1em; - block-size: 1em; - background-image: url('/assets/images/icn-external.svg'); - background-repeat: no-repeat; - background-position: center; - background-size: 60% auto; - /* alternative text rules */ - content: '(external link)'; - overflow: hidden; - white-space: nowrap; - text-indent: 1em; /* the width of the icon */ -} - /* Base selection styles that invert whatever colours are rendered */ ::selection { - background: var(--color-primary); - color: var(--color-light); + background-color: var(--color-text); + color: var(--color-bg); } .preload-transitions * { transition: none !important; } + +@media (prefers-reduced-motion: reduce) { + html:focus-within { + scroll-behavior: auto; + } + + *, + ::after, + ::before { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + } +} diff --git a/src/assets/css/global/reset.css b/src/assets/css/global/reset.css index 9531f98..fb1caba 100644 --- a/src/assets/css/global/reset.css +++ b/src/assets/css/global/reset.css @@ -1,4 +1,7 @@ +/* inspired by: */ /* Modern reset: https://piccalil.li/blog/a-modern-css-reset/ */ +/* https://keithjgrant.com/posts/2024/01/my-css-resets/ */ +/* https://moderncss.dev/modern-css-for-dynamic-component-based-architecture/#css-reset-additions */ /* Box sizing rules */ *, @@ -41,6 +44,7 @@ html:focus-within { /* Set core body defaults */ body { min-height: 100vh; + min-height: 100dvh; text-rendering: optimizeSpeed; line-height: 1.5; } @@ -52,14 +56,28 @@ a:not([class]) { /* Make images easier to work with */ img, -picture { +picture, +svg, +canvas { max-inline-size: 100%; - display: block; + block-size: auto; + vertical-align: middle; + font-style: italic; + background-repeat: no-repeat; + background-size: cover; + shape-margin: 0.75rem; } /* Inherit fonts for inputs and buttons */ -input, + +/* remove default button styles */ + +button { + all: unset; +} + button, +input, textarea, select { font: inherit; @@ -76,3 +94,22 @@ button, summary { cursor: pointer; } + +:where(*) { + /* No typographic widows */ + text-wrap: pretty; +} +:where(h1, h2, h3, h4) { + text-wrap: balance; +} + +/* Scroll margin allowance above anchor links */ +:target { + scroll-margin-block-start: 2ex; +} + +/* Scroll margin allowance below focused elements + to ensure they are clearly in view */ +:focus { + scroll-margin-block-end: 8vh; +} diff --git a/src/assets/css/global/variables.css b/src/assets/css/global/variables.css index 6b06c55..5e5eee8 100644 --- a/src/assets/css/global/variables.css +++ b/src/assets/css/global/variables.css @@ -1,10 +1,111 @@ /* Global variables */ + :root { - --gutter: var(--space-s-m); - --border-radius: 0.5rem; + --gutter: var(--space-m-l); + --border-radius: 0.3rem; --transition-duration: 250ms; --transition-timing: ease; - --wrapper-width: clamp(16rem, 93vw, 85rem); + --wrapper-width: 85rem; --tracking: -0.05ch; --tracking-s: -0.075ch; + --tracking-wide: 0.05ch; + + --gradient-rainbow: linear-gradient( + 90deg, + var(--color-primary), + var(--color-secondary), + var(--color-tertiary) + ); + --gradient-conic: conic-gradient( + var(--color-primary) 0 28%, + var(--color-secondary) 0 67%, + var(--color-tertiary) 0 100% + ); + --gradient-stripes: linear-gradient( + 45deg, + var(--color-base-dark) 0 75%, + var(--color-primary) 0 85%, + var(--color-secondary) 0 92%, + var(--color-tertiary) 0 100% + ); +} + +:root, +:root[data-theme='light'] { + color-scheme: light dark; + --color-text: var(--color-base-dark); + --color-bg: var(--color-base-light); + --color-base: var(--color-base-highlight); + --color-primary: var(--color-primary-highlight); + --color-secondary: var(--color-secondary-highlight); + --color-tertiary: var(--color-tertiary-highlight); + + /* modify base colors with color-mix - https://caniuse.com/?search=color-mix */ + --color-text-accent: color-mix(in oklab, var(--color-base-dark) 80%, var(--color-text)); + --color-bg-accent: color-mix(in oklab, var(--color-bg) 90%, var(--color-text)); + --color-bg-accent-2: color-mix(in oklab, var(--color-bg) 70%, var(--color-text)); +} + +/* Dark Color Scheme (System Preference) */ +@media (prefers-color-scheme: dark) { + :root { + --color-text: var(--color-base-light); + --color-bg: var(--color-base-dark); + + /* less "intensity" with color-mix */ + --color-text-accent: color-mix( + in oklab, + var(--color-base-light) 70%, + var(--color-bg) + ); + --color-bg-accent: color-mix(in oklab, var(--color-bg) 92%, var(--color-text)); + --color-bg-accent-2: color-mix(in oklab, var(--color-bg) 80%, var(--color-text)); + + /* add opacity with color-mix */ + --color-primary: color-mix(in oklab, var(--color-primary-highlight), transparent 20%); + --color-secondary: color-mix( + in oklab, + var(--color-secondary-highlight), + transparent 20% + ); + --color-tertiary: color-mix( + in oklab, + var(--color-tertiary-highlight), + transparent 20% + ); + + /* desaturate with CSS Relative colors */ + @supports (color: hsl(from white h s l)) { + --color-primary: hsl(from var(--color-primary-highlight) h calc(s - 0.2) l); + --color-secondary: hsl(from var(--color-secondary-highlight) h calc(s - 0.2) l); + --color-tertiary: hsl(from var(--color-tertiary-highlight) h calc(s - 0.2) l); + } + } +} + +/* Dark Color Scheme (Override) */ +:root[data-theme='dark'] { + --color-text: var(--color-base-light); + --color-bg: var(--color-base-dark); + + /* less "intensity" with color-mix */ + --color-text-accent: color-mix(in oklab, var(--color-base-light) 70%, var(--color-bg)); + --color-bg-accent: color-mix(in oklab, var(--color-bg) 92%, var(--color-text)); + --color-bg-accent-2: color-mix(in oklab, var(--color-bg) 80%, var(--color-text)); + + /* add opacity with color-mix */ + --color-primary: color-mix(in oklab, var(--color-primary-highlight), transparent 20%); + --color-secondary: color-mix( + in oklab, + var(--color-secondary-highlight), + transparent 20% + ); + --color-tertiary: color-mix(in oklab, var(--color-tertiary-highlight), transparent 20%); + + /* desaturate with CSS Relative colors */ + @supports (color: hsl(from white h s l)) { + --color-primary: hsl(from var(--color-primary-highlight) h calc(s - 0.2) l); + --color-secondary: hsl(from var(--color-secondary-highlight) h calc(s - 0.2) l); + --color-tertiary: hsl(from var(--color-tertiary-highlight) h calc(s - 0.2) l); + } } diff --git a/src/assets/css/utilities/blur.css b/src/assets/css/utilities/blur.css new file mode 100644 index 0000000..83e20d3 --- /dev/null +++ b/src/assets/css/utilities/blur.css @@ -0,0 +1,3 @@ +.blur { + filter: blur(0.25rem); +} diff --git a/src/assets/css/utilities/content.css b/src/assets/css/utilities/content.css deleted file mode 100644 index cf9efab..0000000 --- a/src/assets/css/utilities/content.css +++ /dev/null @@ -1,19 +0,0 @@ -/* breakout content elements to wrapper based on full bleed image solution by josh cumeau. https://www.joshwcomeau.com/css/full-bleed/ */ - -.content { - --wrapper-width: clamp(16rem, 93vw, 75rem); - display: grid; - grid-template-columns: - 1fr - min(48ch, 100%) - 1fr; -} - -.content > * { - grid-column: 2; -} - -.content .breakout { - inline-size: 100%; - grid-column: 1 / 4; -} diff --git a/src/assets/css/utilities/region.css b/src/assets/css/utilities/region.css index cc9eb69..4a4bef5 100644 --- a/src/assets/css/utilities/region.css +++ b/src/assets/css/utilities/region.css @@ -4,6 +4,6 @@ * Can either be configured by setting --region-space or use a default from the space scale */ .region { - padding-block-start: var(--region-space-top, var(--space-l-2xl)); - padding-block-end: var(--region-space-bottom, var(--space-l-2xl)); + padding-block-start: var(--region-space-top, var(--space-l-xl)); + padding-block-end: var(--region-space-bottom, var(--space-l-xl)); } diff --git a/src/assets/css/utilities/visually-hidden.css b/src/assets/css/utilities/visually-hidden.css new file mode 100644 index 0000000..0b964a2 --- /dev/null +++ b/src/assets/css/utilities/visually-hidden.css @@ -0,0 +1,15 @@ +/* +VISUALLY HIDDEN UTILITY +Info: https://piccalil.li/quick-tip/visually-hidden/ +*/ +.visually-hidden { + border: 0; + clip: rect(0 0 0 0); + height: 0; + margin: 0; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + white-space: nowrap; +}