@@ -189,81 +189,99 @@ def __init__(
189189 preset = brand_bootstrap .preset ,
190190 include_paths = include_paths ,
191191 )
192+
192193 self .brand = brand
193194
194- # brand.color -----------------------------------------------------------------
195+ # Prep Sass and CSS Variables -------------------------------------------------
196+ sass_vars_colors , css_vars_colors = self ._prepare_color_vars ()
197+ sass_vars_typography = self ._prepare_typography_vars ()
198+
199+ # Theme -----------------------------------------------------------------------
200+ # Defaults are added in reverse order, so each chunk appears above the next
201+ # layer of defaults. The intended order in the final output is:
202+ # 1. Brand Sass color and typography vars
203+ # 2. Brand's Bootstrap Sass vars
204+ # 3. Gray scale variables from Brand fg/bg or black/white
205+ # 4. Fallback vars needed by additional Brand rules
206+
207+ self ._add_sass_ensure_variables ()
208+ self ._add_sass_brand_grays ()
209+ self .add_defaults (** brand_bootstrap .defaults )
210+ self .add_defaults (** sass_vars_colors , ** sass_vars_typography )
211+ # Brand Rules ----
212+ self .add_rules (":root {" , * css_vars_colors , "}" )
213+ self ._add_sass_brand_rules ()
214+
215+ def _prepare_color_vars (self ) -> tuple [dict [str , str ], list [str ]]:
216+ if not self .brand .color :
217+ return {}, []
218+
195219 sass_vars_colors : dict [str , str ] = {}
196220 sass_vars_brand_colors : dict [str , str ] = {}
197221 css_vars_brand_colors : list [str ] = []
198222
199- if brand .color :
200- # Map values in colors to their Sass variable counterparts
201- for thm_name , thm_color in brand .color .to_dict (include = "theme" ).items ():
202- if thm_name not in color_map :
203- self ._handle_unmapped_variable (f"color.{ thm_name } " )
204- continue
223+ # Map values in colors to their Sass variable counterparts
224+ for thm_name , thm_color in self .brand .color .to_dict (include = "theme" ).items ():
225+ if thm_name not in color_map :
226+ self ._handle_unmapped_variable (f"color.{ thm_name } " )
227+ continue
205228
206- for sass_var in color_map [thm_name ]:
207- sass_vars_colors [sass_var ] = thm_color
229+ for sass_var in color_map [thm_name ]:
230+ sass_vars_colors [sass_var ] = thm_color
208231
209- brand_color_palette = brand .color .to_dict (include = "palette" )
232+ brand_color_palette = self . brand .color .to_dict (include = "palette" )
210233
211- # Map the brand color palette to Bootstrap's named colors, e.g. $red, $blue.
212- for pal_name , pal_color in brand_color_palette .items ():
213- if pal_name in bootstrap_colors :
214- sass_vars_colors [pal_name ] = pal_color
234+ # Map the brand color palette to Bootstrap's named colors, e.g. $red, $blue.
235+ for pal_name , pal_color in brand_color_palette .items ():
236+ if pal_name in bootstrap_colors :
237+ sass_vars_colors [pal_name ] = pal_color
215238
216- # Create Sass and CSS variables for the brand color palette
217- color_var = sanitize_sass_var_name (pal_name )
239+ # Create Sass and CSS variables for the brand color palette
240+ color_var = sanitize_sass_var_name (pal_name )
218241
219- # => Sass var: `$brand-{name}: {value}`
220- sass_vars_brand_colors .update ({f"brand-{ color_var } " : pal_color })
221- # => CSS var: `--brand-{name}: {value}`
222- css_vars_brand_colors .append (f"--brand-{ color_var } : { pal_color } ;" )
242+ # => Sass var: `$brand-{name}: {value}`
243+ sass_vars_brand_colors .update ({f"brand-{ color_var } " : pal_color })
244+ # => CSS var: `--brand-{name}: {value}`
245+ css_vars_brand_colors .append (f"--brand-{ color_var } : { pal_color } ;" )
223246
224- # brand.typography ------------------------------------------------------------
247+ return {** sass_vars_brand_colors , ** sass_vars_colors }, css_vars_brand_colors
248+
249+ def _prepare_typography_vars (self ) -> dict [str , str ]:
225250 sass_vars_typography : dict [str , str ] = {}
226- if brand .typography :
227- brand_typography = brand .typography .model_dump (
228- exclude = {"fonts" },
229- exclude_none = True ,
230- )
231251
232- for typ_field , typ_value in brand_typography . items () :
233- if typ_field not in typography_map :
234- self . _handle_unmapped_variable ( f"typography. { typ_field } " )
235- continue
236-
237- for typ_field_key , typ_field_value in typ_value . items ():
238- if typ_field_key in typography_map [ typ_field ]:
239- if typ_field == "base" and typ_field_key == "size" :
240- typ_field_value = str (
241- maybe_convert_font_size_to_rem ( typ_field_value )
242- )
243-
244- typo_sass_vars = typography_map [ typ_field ][ typ_field_key ]
245- for typo_sass_var in typo_sass_vars :
246- sass_vars_typography [ typo_sass_var ] = typ_field_value
247- else :
248- self . _handle_unmapped_variable (
249- f"typography. { typ_field } . { typ_field_key } "
252+ if not self . brand . typography :
253+ return sass_vars_typography
254+
255+ brand_typography = self . brand . typography . model_dump (
256+ exclude = { "fonts" },
257+ exclude_none = True ,
258+ )
259+
260+ for typ_field , typ_value in brand_typography . items ():
261+ if typ_field not in typography_map :
262+ self . _handle_unmapped_variable ( f"typography. { typ_field } " )
263+ continue
264+
265+ for typ_field_key , typ_field_value in typ_value . items () :
266+ if typ_field_key in typography_map [ typ_field ]:
267+ if typ_field == "base" and typ_field_key == "size" :
268+ typ_field_value = str (
269+ maybe_convert_font_size_to_rem ( typ_field_value )
250270 )
251271
252- # Theme -----------------------------------------------------------------------
253- sass_vars_brand : dict [ str , str ] = {
254- ** sass_vars_brand_colors ,
255- ** sass_vars_colors ,
256- ** sass_vars_typography ,
257- }
258- sass_vars_brand = { k : v for k , v in sass_vars_brand . items ()}
272+ typo_sass_vars = typography_map [ typ_field ][ typ_field_key ]
273+ for typo_sass_var in typo_sass_vars :
274+ sass_vars_typography [ typo_sass_var ] = typ_field_value
275+ else :
276+ self . _handle_unmapped_variable (
277+ f"typography. { typ_field } . { typ_field_key } "
278+ )
259279
260- # Defaults are added in reverse order, so each chunk appears above the next
261- # layer of defaults. The intended order in the final output is:
262- # 1. Brand Sass vars (colors, typography)
263- # 2. Brand Bootstrap Sass vars
264- # 3. Fallback vars needed by additional Brand rules
280+ return sass_vars_typography
281+
282+ def _add_sass_ensure_variables (self ):
283+ """Ensure the variables we create to augment Bootstrap's variables exist"""
265284 self .add_defaults (
266- # Variables we create to augment Bootstrap's variables
267285 ** {
268286 "code-font-weight" : None ,
269287 "code-inline-font-weight" : None ,
@@ -275,6 +293,12 @@ def __init__(
275293 "link-weight" : None ,
276294 }
277295 )
296+
297+ def _add_sass_brand_grays (self ):
298+ """
299+ Adds functions and defaults to handle creating a gray scale palette from the
300+ brand color palette, or the brand's foreground/background colors.
301+ """
278302 self .add_functions (
279303 """
280304 @function brand-choose-white-black($foreground, $background) {
@@ -348,11 +372,9 @@ def __init__(
348372 }
349373 """
350374 )
351- self .add_defaults (** brand_bootstrap .defaults )
352- self .add_defaults (** sass_vars_brand )
353- # Brand Rules ----
354- self .add_rules (":root {" , * css_vars_brand_colors , "}" )
355- # Additional rules to fill in Bootstrap styles for Brand parameters
375+
376+ def _add_sass_brand_rules (self ):
377+ """Additional rules to fill in Bootstrap styles for Brand parameters"""
356378 self .add_rules (
357379 """
358380 // https://github.com/twbs/bootstrap/blob/5c2f2e7e/scss/_root.scss#L82
0 commit comments