Contents

snippets/css-variables.liquid turns theme settings into CSS custom properties on :root. Every color and size in the theme reads from these variables. Use them in your own CSS so custom code follows the active color palette and any color the merchant overrides.

Settings tokens

Color

Each color token is the merchant's setting when it's been changed, or the color palette's value otherwise.

TokenSetting
--tc-page"Page background"
--tc-ink"Page text"
--tc-panel"Panel background"
--tc-surface"Button background"
--tc-ink-strong"Headings and button text"
--tc-ink-muted"Body text"
--tc-ink-dim"Secondary text"
--tc-line"Lines and borders"
--tc-accent"Accent"
--tc-danger"Alerts"

Type and layout

TokenSettingValue
--tc-font-family"Primary font"The font family and its fallbacks
--tc-font-style"Primary font"The font's style
--tc-font-weight"Primary font"The font's regular weight
--tc-font-weight-boldnone700
--tc-font-size"Base text size"13px to 17px
--tc-type-scale"Base text size"Base size ÷ 14, from about 0.93 to 1.21
--tc-page-width"Page width"90rem, 97.5rem or 110rem
--tc-page-margin"Page margin"10px to 60px
--tc-logo-width"Logo width"80px to 320px
--tc-tap-minnone44px

Header tokens

Set only while Header › "Sticky header" is Always or On scroll up. With None, neither is set.

TokenSet byValue
--tc-header-height<tc-sticky-header>, on :rootThe stuck header's measured height, rounded up to the pixel, including the space above it. Updates when the header's height changes.
--tc-scroll-offsetThe header's stylesheet, on :root--tc-header-height plus 8px, or 7rem plus the page's top spacing before the script has measured. Everything in the page column except the header uses it as scroll-margin-block-start, so anchors and focused elements land below the stuck header.

To keep your own sticky element under a header that's set to Always, use top: var(--tc-header-height, 0px).

Docked bar tokens

TokenSet byValue
--tc-dock-bottom:root, in snippets/css-variables.liquidThe height of the bars docked to the bottom of the screen: --tc-dock-buy plus --tc-dock-compare, 0px when neither shows. The back-to-top button, its scroll margin and the space at the end of the page all grow by it, or by the screen's bottom safe area (env(safe-area-inset-bottom)) while that is larger, never by both.
--tc-dock-buyThe product page's sticky add-to-cart bar (<tc-sticky-buy>), on :root, while it showsThe bar's height, including the bottom safe area it pads itself by. Unset otherwise.
--tc-dock-compareThe compare bar (<tc-compare-tray>, see Product comparison), on :root, while it showsThe bar's height, including the bottom safe area it pads itself by when no sticky add-to-cart bar is under it. Unset otherwise. The compare bar sits on top of the sticky add-to-cart bar, lifted by --tc-dock-buy, so the two never overlap.
--tc-scroll-offset-endThe back-to-top snippet's stylesheet, on :root, while "Show back-to-top button" is on; with it off, the Buy buttons block's stylesheet while the sticky add-to-cart bar shows, and the compare bar's while it shows44px plus 24px plus the larger of --tc-dock-bottom and the bottom safe area with the back-to-top button; --tc-dock-bottom plus 8px without it. Everything in the page column except the header uses it as scroll-margin-block-end, so focused elements stop above the button and the bar. The page column's end padding is at least this much too, so the footer's last line can be scrolled clear of them; without the back-to-top button, only while the sticky add-to-cart bar or the compare bar is docked (their data-docked attribute).

Anything you fix to the bottom of the screen, such as a chat button, should sit at bottom: calc(16px + max(env(safe-area-inset-bottom, 0px), var(--tc-dock-bottom, 0px))), as the back-to-top button does, so the sticky add-to-cart bar and the compare bar never cover it and it stays clear of the phone's home indicator or gesture bar. Take the larger of the two rather than adding them: a docked bar's height already includes the safe area. If your own code docks a bar to the bottom of the screen, place it at bottom: calc(var(--tc-dock-buy, 0px) + var(--tc-dock-compare, 0px)), on top of the theme's bars, and set --tc-dock-bottom on document.documentElement to calc(YOUR-HEIGHT + var(--tc-dock-buy, 0px) + var(--tc-dock-compare, 0px)) while it shows, removing it when it hides, so the back-to-top button moves above all of them. YOUR-HEIGHT is the bar's full height, including any safe-area padding you give it.

Derived tokens

Derived tokens are mixed from the color tokens with color-mix(), so they follow every palette.

Hairlines

Decorative dividers and rules, from faintest to strongest. Don't use these for the border of anything a shopper interacts with.

TokenMix
--tc-hairline-faint9% line
--tc-hairline-row12% line
--tc-hairline-soft16% line
--tc-hairline22% line
--tc-hairline-panel28% line
--tc-hairline-rule30% line
--tc-hairline-strong35% line
--tc-hairline-danger35% danger

Borders

TokenMixUse for
--tc-border-control65% lineInputs, buttons, checkboxes
--tc-border-control-accent72% accentAccent-colored controls
--tc-border-control-danger70% dangerControls in an error state
--tc-border-panel65% linePanel edges
--tc-border-panel-strong80% lineEmphasized panels
Warning

--tc-border-control and --tc-border-control-accent are the WCAG 1.4.11 non-text contrast floor, 3:1, measured over --tc-page, --tc-panel and --tc-surface in all four color palettes. Use them, not a hairline, for any control border, and don't use a lighter mix.

Fills and effects

TokenMixUse for
--tc-fill-hover20% line over pageHover background
--tc-fill-hover-strong24% line over pageHover on emphasized controls
--tc-fill-hover-accent17% accent over pageHover on accent controls
--tc-ink-dim-on-fill25% strong ink into dim inkSecondary text on a hover fill
--tc-accent-on-fill26% strong ink into accentAccent text on a hover fill
--tc-glowLine, per paletteHover bloom. transparent in Blueprint and Monolith.
--tc-scrimPage (dark palettes) or strong ink (light palettes)The backdrop behind open drawers
--tc-filter-monoA CSS filter, not a color: brightness(0) invert(0.8) on the dark palettes, brightness(0) invert(0.2) on the light onesMonochrome logos in the Logo list: every opaque pixel becomes one grey that suits the palette
--tc-scanlinesPer paletteThe scanline overlay, or none
--tc-gridlines11% line over pageThe grid overlay, or none

Using tokens

.my-spec-callout {
  background: var(--tc-panel);
  border: 1px solid var(--tc-border-panel);
  color: var(--tc-ink-muted);
  font-size: calc(13px * var(--tc-type-scale));
}

.my-spec-callout:hover {
  background: var(--tc-fill-hover);
  box-shadow: 0 0 20px var(--tc-glow);
}
  • Scale every font size by --tc-type-scale so "Base text size" applies to your code.
  • Keep text in any field you add at 16px or more on touch screens, or iOS Safari zooms the page when a shopper taps it: for example font-size: max(16px, calc(13px * var(--tc-type-scale))) inside @media (pointer: coarse). Fields with the theme's .tc-input, .tc-select, .tc-textarea or .tc-qty__input class already do.
  • Don't hard-code colors. A hex value won't change with the color palette or the merchant's overrides.
  • When you put text on a color other than the one it was designed for, measure contrast in all four color palettes.

See also