├── .node-version ├── scss ├── _thimble.scss ├── _config.scss ├── _mixins.scss ├── _buttons.scss ├── _utilities.scss ├── _colors.scss ├── _thimble-overrides.scss ├── _forms.scss └── _thimble-core.scss ├── package.json ├── README.md ├── LICENSE └── changelog.md /.node-version: -------------------------------------------------------------------------------- 1 | 18.2.0 2 | -------------------------------------------------------------------------------- /scss/_thimble.scss: -------------------------------------------------------------------------------- 1 | // ThimbleCSS v3.0.0 2 | 3 | @forward 'config'; 4 | 5 | @forward 'thimble-overrides'; 6 | @forward 'colors'; 7 | @forward 'mixins'; 8 | @forward 'thimble-core'; 9 | @forward 'buttons'; 10 | @forward 'forms'; 11 | @forward 'utilities'; -------------------------------------------------------------------------------- /scss/_config.scss: -------------------------------------------------------------------------------- 1 | // Extras 2 | $include-forms: true !default; 3 | $include-buttons: true !default; 4 | $include-utilities: true !default; 5 | 6 | // Media Break Adjustments 7 | $small-break: 480px !default; 8 | $medium-break: 768px !default; 9 | $large-break: 1024px !default; 10 | $xlarge-break: 1280px !default; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thimblecss", 3 | "version": "3.0.0", 4 | "description": "A nimble micro CSS Framework", 5 | "main": "scss/_thimble.scss", 6 | "style": "scss/_thimble.scss", 7 | "files": [ 8 | "scss", 9 | "LICENSE", 10 | "README.md" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/agileleague/thimblecss.git" 15 | }, 16 | "keywords": [ 17 | "css", 18 | "flexbox", 19 | "front-end", 20 | "framework", 21 | "microframework", 22 | "html", 23 | "html5", 24 | "mobile-first", 25 | "responsive", 26 | "sanitize", 27 | "scss", 28 | "web" 29 | ], 30 | "author": "Drew Nolte ", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/agileleague/thimblecss/issues" 34 | }, 35 | "homepage": "https://thimblecss.com" 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ThimbleCSS 2 | 3 | **ThimbleCSS** is a lightweight, modern SCSS micro-framework. 4 | It provides a minimal baseline for typography, layout, utilities, and design tokens—without imposing a full design system or component library. 5 | 6 | Thimble is intended to be **imported into your own SCSS pipeline**, not consumed as a precompiled CSS file. 7 | 8 | --- 9 | 10 | ## Features 11 | 12 | - Modular SCSS architecture 13 | - Configurable variables, breakpoints, and color system 14 | - Utility classes for grids, spacing, media, and typography 15 | - Small surface area, easy to override 16 | - No runtime dependencies 17 | 18 | --- 19 | 20 | ## Installation 21 | 22 | ```bash 23 | npm install thimblecss 24 | ``` 25 | 26 | ## Usage 27 | 28 | ``` SCSS 29 | @use "thimblecss" as *; 30 | 31 | // OR customize variables and modules before import: 32 | 33 | @use "thimblecss" with ( 34 | $small-break: 600px, 35 | $medium-break: 900px, 36 | $large-break: 1200px, 37 | $xlarge-break: 1400px 38 | ); 39 | ``` 40 | 41 | ## Documentation 42 | Full documentation, examples, and guidance are available at: [ThimbleCSS](https://thimblecss.com/) 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 The Agile League 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as bp; 2 | 3 | // Mixins 4 | 5 | // Style Scroll Bar 6 | @mixin scrollbar($track, $bar, $width, $radius) { 7 | &::-webkit-scrollbar {background: $track; width:$width} 8 | &::-webkit-scrollbar-thumb {background: $bar; border-radius:$radius} 9 | &::-webkit-scrollbar-corner {background: $track} 10 | scrollbar-base-color: $bar; 11 | scrollbar-3dlight-color: $bar; 12 | scrollbar-highlight-color: $bar; 13 | scrollbar-track-color: $track; 14 | scrollbar-arrow-color: $track; 15 | scrollbar-shadow-color: $bar; 16 | scrollbar-dark-shadow-color: $bar 17 | } 18 | 19 | // CSS Mutli-columns 20 | @mixin columns($count, $gap) { 21 | column-count:$count; 22 | column-gap:$gap; 23 | break-inside:avoid 24 | } 25 | 26 | // Quick XY center with flexbox 27 | @mixin quick-center { 28 | display: flex; 29 | align-items: center 30 | } 31 | 32 | // Media 33 | $small: 'only screen and (min-width: #{bp.$small-break})'; 34 | $medium: 'only screen and (min-width: #{bp.$medium-break})'; 35 | $large: 'only screen and (min-width: #{bp.$large-break})'; 36 | $xlarge: 'only screen and (min-width: #{bp.$xlarge-break})'; 37 | 38 | $small-down: 'only screen and (max-width: #{bp.$small-break - 1px})'; 39 | $medium-down: 'only screen and (max-width: #{bp.$medium-break - 1px})'; 40 | $large-down: 'only screen and (max-width: #{bp.$large-break - 1px})'; 41 | $xlarge-down: 'only screen and (max-width: #{bp.$xlarge-break - 1px})'; -------------------------------------------------------------------------------- /scss/_buttons.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as *; 2 | @if $include-buttons { 3 | 4 | .button, button, [type="button"], [type="reset"], [type="submit"] { 5 | border-radius: var(--button-radius, 4px); 6 | padding: calc(.75rem + 2px) calc(1rem + 2px); 7 | color: var(--button-text-color); 8 | background-color: var(--button-background); 9 | transition:var(--normal-speed); 10 | text-decoration: none; 11 | display: inline-block; 12 | &:hover { 13 | background-color: var(--button-hover-background) 14 | } 15 | &:active, &:focus { 16 | background-color: var(--button-active-background) 17 | } 18 | &.full { 19 | width:100%; 20 | text-align: center 21 | } 22 | &.secondary { 23 | background-color: var(--button-background-secondary); 24 | &:hover { 25 | background-color: var(--button-hover-background-secondary) 26 | } 27 | &:active, &:focus { 28 | background-color: var(--button-active-background-secondary) 29 | } 30 | } 31 | &.ghost { 32 | background-color: transparent; 33 | padding: .75rem 1rem; 34 | border: 2px solid var(--button-background); 35 | color: var(--button-background); 36 | &:hover { 37 | border-color: var(--button-hover-background); 38 | color: var(--button-hover-background); 39 | background-color: color-mix(in oklch, var(--button-hover-background), transparent 90%) 40 | } 41 | &:active, &:focus { 42 | border-color: var(--button-active-background); 43 | color: var(--button-active-background); 44 | background-color: color-mix(in oklch, var(--button-active-background), transparent 90%) 45 | } 46 | } 47 | } 48 | 49 | } // end if $include-buttons -------------------------------------------------------------------------------- /scss/_utilities.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as *; 2 | @if $include-utilities { 3 | 4 | // Utility Classes 5 | 6 | // Display 7 | .block { display: block !important; } 8 | .inline { display: inline !important; } 9 | .inline-block { display: inline-block !important; } 10 | .flex { display: flex !important; } 11 | 12 | // Position 13 | .relative { position: relative !important; } 14 | .absolute { position: absolute !important; } 15 | .fixed { position: fixed !important; } 16 | .sticky { position: sticky !important; } 17 | 18 | // Overflow 19 | .overflow-hidden { overflow: hidden !important; } 20 | .overflow-auto { overflow: auto !important; } 21 | .overflow-scroll { overflow: scroll !important; } 22 | 23 | // Border radius 24 | .rounded-small { border-radius: var(--radius-small, 4px) !important; } 25 | .rounded-medium { border-radius: var(--radius-medium, 8px) !important; } 26 | .rounded-large { border-radius: var(--radius-large, 12px) !important; } 27 | .rounded-full { border-radius: 50% !important; } 28 | 29 | // Shadow 30 | .shadow { box-shadow: var(--base-shadow) !important; } 31 | .shadow-hover { box-shadow: var(--hover-shadow) !important; } 32 | .shadow-selected { box-shadow: var(--selected-shadow) !important; } 33 | .shadow-solid { box-shadow: var(--solid-shadow) !important; } 34 | .shadow-none { box-shadow: none !important; } 35 | 36 | // Text Color 37 | .text-green { color: var(--green) !important; } 38 | .text-blue { color: var(--blue) !important; } 39 | .text-violet { color: var(--violet) !important; } 40 | .text-red { color: var(--red) !important; } 41 | .text-orange { color: var(--orange) !important; } 42 | .text-yellow { color: var(--yellow) !important; } 43 | 44 | .text-pearl { color: var(--pearl) !important; } 45 | .text-black { color: var(--black) !important; } 46 | .text-white { color: var(--white) !important; } 47 | .text-jet { color: var(--jet) !important; } 48 | .text-gray { color: var(--gray) !important; } 49 | 50 | } // end if $include-utilities -------------------------------------------------------------------------------- /scss/_colors.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --mix-white-20: 46%; 3 | --mix-white-10: 24%; 4 | --mix-black-10: 20%; 5 | --mix-black-20: 40%; 6 | 7 | // Green 8 | --green-l1: color-mix(in oklch, var(--green), white var(--mix-white-10)); 9 | --green-l2: color-mix(in oklch, var(--green), white var(--mix-white-20)); 10 | --green-d1: color-mix(in oklch, var(--green), black var(--mix-black-10)); 11 | --green-d2: color-mix(in oklch, var(--green), black var(--mix-black-20)); 12 | 13 | // Blue 14 | --blue-l1: color-mix(in oklch, var(--blue), white var(--mix-white-10)); 15 | --blue-l2: color-mix(in oklch, var(--blue), white var(--mix-white-20)); 16 | --blue-d1: color-mix(in oklch, var(--blue), black var(--mix-black-10)); 17 | --blue-d2: color-mix(in oklch, var(--blue), black var(--mix-black-20)); 18 | 19 | // Violet 20 | --violet-l1: color-mix(in oklch, var(--violet), white var(--mix-white-10)); 21 | --violet-l2: color-mix(in oklch, var(--violet), white var(--mix-white-20)); 22 | --violet-d1: color-mix(in oklch, var(--violet), black var(--mix-black-10)); 23 | --violet-d2: color-mix(in oklch, var(--violet), black var(--mix-black-20)); 24 | 25 | // Red 26 | --red-l1: color-mix(in oklch, var(--red), white var(--mix-white-10)); 27 | --red-l2: color-mix(in oklch, var(--red), white var(--mix-white-20)); 28 | --red-d1: color-mix(in oklch, var(--red), black var(--mix-black-10)); 29 | --red-d2: color-mix(in oklch, var(--red), black var(--mix-black-20)); 30 | 31 | // Orange 32 | --orange-l1: color-mix(in oklch, var(--orange), white var(--mix-white-10)); 33 | --orange-l2: color-mix(in oklch, var(--orange), white var(--mix-white-20)); 34 | --orange-d1: color-mix(in oklch, var(--orange), black 10%); 35 | --orange-d2: color-mix(in oklch, var(--orange), black 25%); 36 | 37 | // Yellow 38 | --yellow-l1: color-mix(in oklch, var(--yellow), white var(--mix-white-10)); 39 | --yellow-l2: color-mix(in oklch, var(--yellow), white var(--mix-white-20)); 40 | --yellow-d1: color-mix(in oklch, var(--yellow), black 10%); 41 | --yellow-d2: color-mix(in oklch, var(--yellow), black 20%); 42 | 43 | // Gray 44 | --gray-l1: color-mix(in oklch, var(--gray), white var(--mix-white-10)); 45 | --gray-l2: color-mix(in oklch, var(--gray), white var(--mix-white-20)); 46 | --gray-d1: color-mix(in oklch, var(--gray), black var(--mix-black-10)); 47 | --gray-d2: color-mix(in oklch, var(--gray), black var(--mix-black-20)); 48 | } -------------------------------------------------------------------------------- /scss/_thimble-overrides.scss: -------------------------------------------------------------------------------- 1 | // ThimbleCSS Overrides 2 | 3 | :root { 4 | // Set up for automatic dark mode support 5 | color-scheme: light dark; 6 | 7 | // Colors 8 | --green: #6F8D6A; 9 | --blue: #2D5283; 10 | --violet: #9E4770; 11 | --red: #E54013; 12 | --orange: #F45D01; 13 | --yellow: #E3BD33; 14 | 15 | --pearl: #e7dbbf; 16 | --black: #1c1b22; 17 | --white: #ffffff; 18 | --jet: #433e3c; 19 | --gray: #6e7e85; 20 | 21 | --background-color: light-dark(white, var(--black)); 22 | 23 | // Typography 24 | --primary-font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Arial, sans-serif; 25 | --line-height: 1.5; 26 | 27 | --header-color:light-dark(var(--jet), white); 28 | --font-color:light-dark(var(--jet), rgba(255, 255, 255, 0.8)); 29 | --subfont-color: color-mix(in oklch, var(--font-color), transparent 50%); 30 | --link-color:var(--blue); 31 | --link-hover:var(--gray); 32 | 33 | // Transitions 34 | --easing: cubic-bezier(0.4, 0, 0.2, 1); 35 | 36 | --fast-speed: all 0.18s var(--easing); 37 | --normal-speed: all 0.3s var(--easing); 38 | --slow-speed: all 0.5s var(--easing); 39 | --slowest-speed: all 0.75s var(--easing); 40 | 41 | // Shadows 42 | --base-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.14); 43 | --hover-shadow: 0 6px 16px rgba(0, 0, 0, 0.25), 0 4px 20px rgba(0, 0, 0, 0.18); 44 | --selected-shadow: 0 12px 16px rgba(0, 0, 0, 0.25), 0 18px 40px rgba(0, 0, 0, 0.19); 45 | --solid-shadow: 3px 3px 0px rgba(0,0,0,0.2); 46 | 47 | // Container Widths 48 | --container-small: 540px; 49 | --container-medium: 720px; 50 | --container-large: 960px; 51 | --container-xlarge: 1140px; 52 | --container-xxlarge: 1320px; 53 | 54 | // Radius 55 | --radius-small: 4px; 56 | --radius-medium: 8px; 57 | --radius-large: 16px; 58 | 59 | // Grid Spacing 60 | --cell-margin: .5rem; 61 | --cell-padding: .5rem; 62 | 63 | // Forms & Buttons 64 | --button-radius: var(--radius-medium); 65 | --button-text-color: light-dark(var(--white), var(--black)); 66 | --button-background: var(--blue); 67 | --button-background-secondary: var(--gray); 68 | --button-hover-background: var(--gray); 69 | --button-active-background: var(--blue-d1); 70 | --button-hover-background-secondary: var(--gray-l1); 71 | --button-active-background-secondary: var(--gray-l2); 72 | 73 | --form-radius: var(--radius-small); 74 | --form-background: transparent; 75 | --form-border: var(--gray); 76 | --form-hover-border: var(--gray-l2); 77 | --form-active-border: var(--blue); 78 | --form-disabled-background: color-mix(in oklch, var(--gray-l2), transparent 85%); 79 | --form-disabled-border: color-mix(in oklch, var(--gray-l2), transparent 40%); 80 | } -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ============== 3 | 4 | ## v3.0.0 5 | This is a major new releast and reworking of thimble for a modern approach to variables. 6 | 7 | - moved all overrides to CSS variables 8 | - added optional buttons module 9 | - added optional utilities module 10 | - added optional forms module 11 | - moved breakpoints to config file 12 | - updated colors 13 | - added color helper for light/dark variation 14 | - added built in light/dark mode 15 | - added new container classes 16 | - fixed incorrectly named header classes 17 | - removed outdated video container and added ratio helper classes 18 | 19 | ## V2.3.0 20 | - remove legacy precompiled css file 21 | 22 | ## V2.2.6 23 | - add edge and half-edge classes to grid 24 | - rework visibility utility to remove display inherit 25 | - add sizing-down mixin 26 | 27 | ## V2.2.5 28 | - add xlarge container size 29 | 30 | ## V2.2.4 31 | - add responsive fit and fill classes 32 | - add back in min-height and min-width to cell base class 33 | 34 | ## V2.2.3 35 | - Add responsive heading sizes 36 | 37 | ## V2.2.2 38 | - Add $line-height variable to overrides 39 | - Use $line-height to apply margin-bottom to headers in rem 40 | 41 | ## V2.2.1 42 | - Update Sanitize. Based on https://github.com/csstools/sanitize.css/ 43 | - Remove legacy webkit and moz prefixes 44 | - Remove transform mixin 45 | - Remove keyframe mixin 46 | - Remove trailing semi-colons from core 47 | - Remove header class sizing 48 | - Remove super-header for all but h1 49 | - Add reduced motion query to core 50 | - Add text underline class 51 | - Add !default to sass overrides 52 | - Add orange and violet colors 53 | - Update large media break to 1280px 54 | 55 | ## V2.14 56 | - Fix mixins typo for large-down media query 57 | 58 | ## V2.13 59 | - Rename full, small-full, large-full to container, small-container, large-container respectively 60 | - Add align-full 61 | - Add align-wide 62 | - Update Readme 63 | 64 | ## V2.12 65 | - Add h6 sizing in augmented fourth headers 66 | - Add collapse-padding option to grid 67 | - Fix super-header sizing 68 | 69 | ## V2.11 70 | - Add large site width option 71 | 72 | ## V2.1 73 | - Fix xlarge hide class 74 | - Update typography system to augmented fourth scale 75 | - remove class requirement for headers 76 | 77 | ## v2.0 78 | - Remove cards 79 | - Remove buttons 80 | - Remove box styles 81 | - Remove Style Guide 82 | - Removed .css version 83 | - Rebuild grid - Renamed Rows and columns to reflect a single grid box, removed padding from grid cells and replaced with margins for better background handling 84 | - create mixin for grid and typographic breakpoint sizing 85 | - create mobile first media mixins 86 | 87 | ## v1.1-beta 88 | - add style-guide html and css 89 | - move scss to own file 90 | - pull out mixins 91 | - add .em class for italics 92 | 93 | ## v1.0.4-beta 94 | - remove modernizr tags 95 | - fix small validation errors in .css file 96 | - move css into own folder 97 | 98 | ## v1.0.3.5-beta 99 | - Fix multiline css media query 100 | 101 | ## v1.0.3-beta 102 | - Add variable for header font 103 | - Clean up white-space 104 | - Remove some old vendor prefixes 105 | - Remove ordinal flex prefix 106 | - Remove old flexbox standards 107 | 108 | ## v1.0.2-beta 109 | - Add class 'inside' to rows to allow align properly inside other Rows 110 | - fix row's min-width 111 | - fix cell's max-width 112 | - add medium only media queries anc cell widths 113 | 114 | ## v1.0.1-beta 115 | ### Fixed bugs 116 | - Fix column row's spacing with .cell.fit 117 | 118 | ### Implemented enhancements 119 | - Add Changelog! 120 | -------------------------------------------------------------------------------- /scss/_forms.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as *; 2 | @if $include-forms { 3 | 4 | .input { 5 | margin-bottom:1rem 6 | } 7 | 8 | button[type="submit"], input:not([type="checkbox"], [type="radio"]), select, textarea { 9 | width:100% 10 | } 11 | input, textarea, select { 12 | border: 2px solid var(--form-border); 13 | border-radius: var(--form-radius, 4px); 14 | padding: .75rem 1rem; 15 | transition:var(--fast-speed); 16 | background-color: var(--form-background, transparent); 17 | position:relative; 18 | &:hover { 19 | border-color: var(--form-hover-border) 20 | } 21 | &:focus, &:active { 22 | border-color: var(--form-active-border) 23 | } 24 | &:disabled { 25 | background-color: var(--form-disabled-background); 26 | border-color: var(--form-disabled-border) 27 | } 28 | } 29 | 30 | label { 31 | display: flex; 32 | align-items: flex-start; 33 | gap: 0.675rem; 34 | cursor: pointer; 35 | line-height: var(--line-height, 1.5) 36 | } 37 | 38 | input[type="checkbox"], 39 | input[type="radio"] { 40 | appearance: none; 41 | padding:0; 42 | width:1.5rem; 43 | height:1.5rem; 44 | cursor:pointer; 45 | outline-color: transparent; 46 | flex-shrink:0; 47 | &:after { 48 | content: ""; 49 | position: absolute; 50 | transform: scale(.7) rotate(15deg); 51 | transition:var(--normal-speed); 52 | opacity: 0 53 | } 54 | &:hover { 55 | outline: .4rem solid color-mix(in oklch, var(--gray-l2), transparent 90%) 56 | } 57 | &:focus, &:active { 58 | outline: .5rem solid color-mix(in oklch, var(--gray-l2), transparent 75%) 59 | } 60 | &:focus-visible { 61 | box-shadow: 0 0 0 3px var(--blue) 62 | } 63 | &:checked { 64 | background-color: var(--button-background); 65 | border-color: var(--button-background); 66 | &::after { 67 | opacity: 1; 68 | transform: scale(1) rotate(45deg) 69 | } 70 | } 71 | } 72 | 73 | input[type="checkbox"] { 74 | &:checked::after { 75 | width: 28%; 76 | height: 50%; 77 | border: solid var(--button-text-color); 78 | border-width: 0 2px 2px 0; 79 | top: 25%; 80 | left: 36% 81 | } 82 | } 83 | 84 | input[type="radio"] { 85 | border-radius: 50%; 86 | &:checked::after { 87 | width: 50%; 88 | height: 50%; 89 | background-color: var(--button-text-color); 90 | border-radius:50%; 91 | top:25%; 92 | left:25% 93 | } 94 | } 95 | 96 | textarea { 97 | resize: vertical; 98 | max-width: 100%; 99 | height: auto; 100 | min-height: 6rem 101 | } 102 | 103 | 104 | .button, button, [type="button"], [type="reset"], [type="submit"] { 105 | border-radius: var(--button-radius, 4px); 106 | padding: calc(.75rem + 2px) calc(1rem + 2px); 107 | color: var(--button-text-color); 108 | background-color: var(--button-background); 109 | transition:var(--normal-speed); 110 | text-decoration: none; 111 | display: inline-block; 112 | &:hover { 113 | background-color: var(--button-hover-background) 114 | } 115 | &:active, &:focus { 116 | background-color: var(--button-active-background) 117 | } 118 | &.full { 119 | width:100% 120 | } 121 | &.secondary { 122 | background-color: var(--button-background-secondary); 123 | &:hover { 124 | background-color: var(--button-hover-background-secondary) 125 | } 126 | &:active, &:focus { 127 | background-color: var(--button-active-background-secondary) 128 | } 129 | } 130 | &.ghost { 131 | background-color: transparent; 132 | padding: .75rem 1rem; 133 | border: 2px solid var(--button-background); 134 | color: var(--button-background); 135 | &:hover { 136 | border-color: var(--button-hover-background); 137 | color: var(--button-hover-background); 138 | background-color: color-mix(in oklch, var(--button-hover-background), transparent 90%) 139 | } 140 | &:active, &:focus { 141 | border-color: var(--button-active-background); 142 | color: var(--button-active-background); 143 | background-color: color-mix(in oklch, var(--button-active-background), transparent 90%) 144 | } 145 | } 146 | } 147 | 148 | } // End if $include-forms -------------------------------------------------------------------------------- /scss/_thimble-core.scss: -------------------------------------------------------------------------------- 1 | @use 'thimble-overrides' as *; 2 | @use 'mixins' as *; 3 | 4 | // ThimbleCSS Core v3.0.0 5 | 6 | // Sanitize 7 | *, *::before, *::after { 8 | box-sizing:border-box; 9 | } 10 | ::before, 11 | ::after { 12 | text-decoration: inherit; 13 | vertical-align: inherit; 14 | } 15 | html { 16 | -ms-text-size-adjust:100%; 17 | -webkit-text-size-adjust:100%; 18 | -moz-tab-size: 4; 19 | tab-size: 4; 20 | -webkit-tap-highlight-color:transparent; 21 | -moz-osx-font-smoothing:grayscale; 22 | -webkit-font-smoothing:subpixel-antialiased; 23 | line-height:var(--line-height); 24 | } 25 | body { 26 | margin:0; 27 | font-family:var(--primary-font); 28 | color:var(--font-color); 29 | background-color:var(--background-color); 30 | } 31 | hr { 32 | color: inherit; 33 | height: 0; 34 | } 35 | main {display:block} 36 | pre { 37 | font-family: monospace, monospace; 38 | font-size: 1em; 39 | overflow: auto 40 | } 41 | h1, h2, h3, h4, h5, h6, p, blockquote, figure, ol, ul {margin:0;padding:0} 42 | 43 | button, input, select, textarea { 44 | font-family: inherit; 45 | font-size: inherit; 46 | line-height: inherit; 47 | margin: 0; 48 | } 49 | button, [type="button"], [type="reset"], [type="submit"] { 50 | -webkit-appearance: button; 51 | cursor: pointer; 52 | } 53 | 54 | // typography 55 | ::selection {background-color:var(--green);color:#fff} 56 | :focus {outline:0} 57 | p { 58 | margin-bottom:1.1rem; 59 | text-rendering:optimizeLegibility 60 | } 61 | em, i, .em { 62 | font-style:italic; 63 | line-height:inherit 64 | } 65 | .uppercase {text-transform:uppercase} 66 | .capitalize {text-transform:capitalize} 67 | .lowercase {text-transform:lowercase} 68 | .underline {text-decoration:underline} 69 | strong, b, .strong { 70 | font-weight:bolder; 71 | line-height:inherit 72 | } 73 | small, .small {font-size:80%} 74 | .large {font-size:140%} 75 | sup, .sup, sub, .sub { 76 | position:relative; 77 | font-size:75%; 78 | line-height:0; 79 | vertical-align:baseline 80 | } 81 | sup, .sup {top:-.5em} 82 | sub, .sub {bottom:-.25em} 83 | .ellipsis, .ellipsis li { 84 | text-overflow:ellipsis; 85 | white-space:nowrap; 86 | overflow:hidden 87 | } 88 | .text-clip, .text-clip li { 89 | text-overflow:clip; 90 | white-space:nowrap; 91 | overflow:hidden 92 | } 93 | 94 | // Headings 95 | h1, h2, h3, h4, h5, h6 { 96 | font-family:var(--primary-font); 97 | font-weight:normal; 98 | text-rendering:optimizeLegibility; 99 | font-size:inherit; 100 | color:var(--header-color); 101 | margin-bottom: calc(var(--line-height) * 1rem) 102 | } 103 | h1.super-heading {font-size:4.769rem;line-height:1.22} 104 | h1 {font-size:3.052rem;line-height:1.4} 105 | h2 {font-size:2.441rem;line-height:1.55} 106 | h3 {font-size:1.953rem;line-height:1.7} 107 | h4 {font-size:1.563rem;line-height:1.85} 108 | h5 {font-size: 1.25rem;line-height:2} 109 | h6 {font-size: 1rem;line-height:2} 110 | 111 | @media #{$medium} { 112 | h1.super-heading {font-size:5.961rem;line-height:1.18} 113 | h1 {font-size:3.815rem;line-height:1.22} 114 | h2 {font-size:3.052rem;line-height:1.4} 115 | h3 {font-size:2.441rem;line-height:1.55} 116 | h4 {font-size:1.953rem;line-height:1.7} 117 | h5 {font-size:1.563rem;line-height:1.85} 118 | h6 {font-size:1.25rem} 119 | } 120 | 121 | .sub-heading {color:var(--subfont-color)} 122 | 123 | .super-heading.vw {font-size:7vw} 124 | h1.vw {font-size:6vw} 125 | h2.vw {font-size:5vw} 126 | h3.vw {font-size:4.5vw} 127 | h4.vw {font-size:4vw} 128 | h5.vw {font-size:3.5vw} 129 | h6.vw {font-size:3vw} 130 | 131 | // Links 132 | a { 133 | transition:var(--normal-speed); 134 | color:var(--link-color); 135 | cursor:pointer; 136 | &:not(.button):active, &:not(.button):hover { 137 | color:var(--link-hover) 138 | } 139 | &.plain { 140 | color:inherit; 141 | text-decoration: none; 142 | &:active, &:hover { 143 | color:inherit; 144 | text-decoration:underline; 145 | } 146 | } 147 | } 148 | 149 | // Floats & Clears 150 | .float-left {float:left} 151 | .float-right {float:right} 152 | .clear:before,.clear:after {content:'';display:table} 153 | .clear:after {clear:both} 154 | .clear {zoom:1} 155 | 156 | // Lists 157 | ul, ol, dl { 158 | list-style-position:outside; 159 | margin-bottom:1.15rem; 160 | ul, ol, dl { 161 | margin-bottom:0 162 | } 163 | } 164 | ul { 165 | margin-left:1.2rem; 166 | list-style-type:disc; 167 | ul { 168 | list-style-type:circle 169 | } 170 | &.lined, &.none { 171 | list-style-type:none; 172 | margin-left:0 173 | } 174 | &.lined li { 175 | border-bottom:solid 1px var(--subfont-color); 176 | &:last-child { 177 | border-bottom:none 178 | } 179 | } 180 | } 181 | ol { 182 | margin-left:1.55rem; 183 | list-style-type:decimal 184 | } 185 | 186 | // Media 187 | img, iframe, canvas, video, picture { 188 | max-width:100%; 189 | width: 100%; 190 | border:0; 191 | border-style:none 192 | } 193 | img, picture {height: auto} 194 | 195 | svg:not(:root) {overflow:hidden} 196 | 197 | // Aspect Rations for Media 198 | .aspect-16-9 {aspect-ratio:16 / 9} 199 | .aspect-4-3 {aspect-ratio:4 / 3} 200 | .aspect-1-1, .aspect-square {aspect-ratio:1 / 1} 201 | 202 | // Containers 203 | [class*="container-"] { 204 | width:100%; 205 | margin:0 auto 206 | } 207 | .container-small {max-width:var(--container-small)} 208 | .container-medium {max-width:var(--container-medium)} 209 | .container-large {max-width:var(--container-large)} 210 | .container-xlarge {max-width:var(--container-xlarge)} 211 | .container-xxlarge {max-width:var(--container-xxlarge)} 212 | 213 | .align-wide { 214 | margin-left: calc(25% - 25vw); 215 | margin-right: calc(25% - 25vw); 216 | width: auto; 217 | max-width:100vw 218 | } 219 | .align-full { 220 | margin-left: calc( -50vw + 50% ); 221 | margin-right: calc( -50vw + 50% ); 222 | max-width: 100vw; 223 | width:100vw 224 | } 225 | 226 | // Grid 227 | .grid { 228 | position:relative; 229 | display:flex; 230 | -webkit-backface-visibility:hidden; 231 | backface-visibility:hidden; 232 | flex-flow:row wrap; 233 | &.collapse-padding { 234 | > .cell { 235 | padding-left:0; 236 | padding-right:0 237 | } 238 | } 239 | &.edge { 240 | margin-left: calc(0px - var(--cell-margin) - var(--cell-padding)); 241 | margin-right: calc(0px - var(--cell-margin) - var(--cell-padding)); 242 | } 243 | &.half-edge { 244 | margin-left: calc(0px - var(--cell-margin)); 245 | margin-right: calc(0px - var(--cell-margin)); 246 | } 247 | } 248 | .nowrap {flex-wrap:nowrap} 249 | .wrap-reverse {flex-wrap:wrap-reverse} 250 | 251 | // Justify Grid (Vertical Alignment) 252 | .justify-start {justify-content:flex-start} 253 | .justify-end {justify-content:flex-end} 254 | .justify-center {justify-content:center} 255 | .justify-space {justify-content:space-between} 256 | .justify-around { justify-content:space-around} 257 | 258 | // Alignment (Horizontal Alignment) 259 | .align-top {align-items:flex-start;align-self:flex-start} 260 | .align-bottom {align-items:flex-end;align-self:flex-end} 261 | .align-center {align-items:center;align-self:center} 262 | .align-baseline {align-items:baseline} 263 | .align-stretch {align-items:stretch} 264 | 265 | // Grid Direction 266 | .reverse {flex-direction:row-reverse} 267 | .vertical { 268 | flex-direction:column; 269 | flex-wrap:nowrap; 270 | &.reverse { 271 | flex-direction:column-reverse; 272 | flex-wrap:nowrap 273 | } 274 | } 275 | 276 | // Functions 277 | $celladjust:calc(var(--cell-margin) * 2); 278 | $cell-sizes: ( 279 | (twelve, 12), 280 | (eleven, 11), 281 | (ten, 10), 282 | (nine, 9), 283 | (eight, 8), 284 | (seven, 7), 285 | (six, 6), 286 | (five, 5), 287 | (four, 4), 288 | (three, 3), 289 | (two, 2), 290 | (one, 1) 291 | ); 292 | 293 | @mixin sizing($size) { 294 | // Visibilty 295 | .#{$size}hide {display:none!important} 296 | 297 | // Typography 298 | .#{$size}text-left {text-align:left} 299 | .#{$size}text-right {text-align:right} 300 | .#{$size}text-center {text-align:center} 301 | .#{$size}text-justify {text-align:justify} 302 | 303 | @each $size-text, $size-int in $cell-sizes { 304 | // Create Cell Sizes 305 | .#{$size}#{$size-text} { 306 | max-width:calc( 100%/12 * #{$size-int} - #{$celladjust} ); 307 | flex: 0 0 calc( 100%/12 * #{$size-int} - #{$celladjust} ); 308 | &.collapse { 309 | max-width:calc( 100%/12 * #{$size-int} ); 310 | flex: 0 0 calc( 100%/12 * #{$size-int} ) 311 | } 312 | } 313 | 314 | // Create Cell ordering 315 | .#{$size}order-#{$size-int} {order:#{$size-int}} 316 | } 317 | 318 | .#{$size}fifth { 319 | max-width:calc( 20% - #{$celladjust} ); 320 | flex: 0 0 calc( 20% - #{$celladjust} ); 321 | &.collapse { 322 | max-width:20%; 323 | flex: 0 0 20% 324 | } 325 | } 326 | 327 | // Create Responsive fit/fills 328 | .#{$size}fit { 329 | flex:0 0 auto; 330 | width:auto; 331 | max-width:auto; 332 | } 333 | .#{$size}fill { 334 | flex:1 1 0; 335 | width:auto; 336 | max-width:auto; 337 | } 338 | } 339 | 340 | @mixin sizing-down($size) { 341 | .#{$size}show {display:none!important} 342 | } 343 | 344 | // Cells 345 | .cell { 346 | flex:1 1 auto; 347 | max-width:100%; 348 | min-width:0; 349 | min-height:0; 350 | margin-left:var(--cell-margin); 351 | margin-right:var(--cell-margin); 352 | padding-left:var(--cell-padding); 353 | padding-right:var(--cell-padding); 354 | &.fit { 355 | flex:0 0 auto; 356 | width:auto 357 | } 358 | &.fill { 359 | flex:1 1; 360 | width:auto 361 | } 362 | &.collapse { 363 | margin-left:0; 364 | margin-right:0 365 | } 366 | &.collapse-padding { 367 | padding-left:0; 368 | padding-right:0 369 | } 370 | } 371 | 372 | @include sizing(null); 373 | 374 | // Media Queries 375 | @media #{$small-down} { 376 | @include sizing-down(small-); 377 | } 378 | @media #{$small} { 379 | @include sizing(small-); 380 | } 381 | 382 | @media #{$medium-down} { 383 | @include sizing-down(medium-); 384 | } 385 | @media #{$medium} { 386 | @include sizing(medium-); 387 | 388 | // VW Headers 389 | .super-heading.vw {font-size:5vw} 390 | h1.vw {font-size:3.5vw} 391 | h2.vw {font-size:3vw} 392 | h3.vw {font-size:2.5vw} 393 | h4.vw {font-size:2vw} 394 | h5.vw {font-size:1.5vw} 395 | } 396 | 397 | @media #{$large-down} { 398 | @include sizing-down(large-); 399 | } 400 | @media #{$large} { 401 | @include sizing(large-) 402 | } 403 | 404 | @media #{$xlarge-down} { 405 | @include sizing-down(xlarge-); 406 | } 407 | @media #{$xlarge} { 408 | @include sizing(xlarge-) 409 | } 410 | 411 | // Reduced Motion 412 | @media (prefers-reduced-motion: reduce) { 413 | *, ::before, ::after { 414 | animation-delay: -1ms !important; 415 | animation-duration: 1ms !important; 416 | animation-iteration-count: 1 !important; 417 | background-attachment: initial !important; 418 | scroll-behavior: auto !important; 419 | transition-delay: 0s !important; 420 | transition-duration: 0s !important 421 | } 422 | } 423 | 424 | // Respect transparency preferences 425 | @media (prefers-reduced-transparency: reduce) { 426 | * { 427 | backdrop-filter: none !important; 428 | } 429 | } --------------------------------------------------------------------------------