Example #1
0
export const compactSearchVariables = useThemeCache(() => {
    const makeVars = variableFactory("compactSearch");
    const titleBarVars = titleBarVariables();
    const globalVars = globalVariables();

    const baseColor = titleBarVars.colors.bg.darken(0.05);
    const colors = makeVars("colors", {
        bg: baseColor.fade(0.8),
        fg: titleBarVars.colors.fg,
        placeholder: globalVars.mainColors.bg,
        active: {
            bg: baseColor,
        },
    });

    return { colors };
});
Example #2
0
export const meBoxClasses = useThemeCache(() => {
    const globalVars = globalVariables();
    const formVars = formElementsVariables();
    const titleBarVars = titleBarVariables();
    const debug = debugHelper("meBox");
    const mediaQueries = layoutVariables().mediaQueries();
    const flex = flexHelper();
    const style = styleFactory("meBox");

    const root = style(
        {
            ...debug.name(),
            display: "flex",
            alignItems: "center",
            height: unit(titleBarVars.sizing.height),
        },
        mediaQueries.oneColumnDown({
            height: unit(titleBarVars.sizing.mobile.height),
        }),
    );

    const buttonContent = style("buttonContent", {
        ...flex.middle(),
        width: unit(formVars.sizing.height),
        maxWidth: unit(formVars.sizing.height),
        flexBasis: unit(formVars.sizing.height),
        height: unit(titleBarVars.meBox.sizing.buttonContents),
    });

    const rootFlexClass = (count: number) => {
        return style("footFlexClass", {
            flexBasis: unit(count * formElementsVariables().sizing.height),
        });
    };

    return {
        root,
        buttonContent,
        rootFlexClass,
    };
});
Example #3
0
export const mobileDropDownVariables = useThemeCache(() => {
    const globalVars = globalVariables();
    const titleBarVars = titleBarVariables();
    const mixBgAndFg = globalVars.mixBgAndFg;
    const vars = variableFactory("mobileDropDown");

    const title = vars("title", {
        letterSpacing: -0.26,
        maxWidth: calc(`100% - ${px(titleBarVars.endElements.flexBasis * 2)}`),
    });
    const chevron = vars("chevron", {
        width: 8,
        height: 8,
        color: mixBgAndFg(0.7),
    });

    const header = vars("header", {
        minHeight: titleBarVars.sizing.height,
    });

    const padding = vars("padding", {
        horizontal: 2,
    });

    const side = vars("side", {
        width: globalVars.icon.sizes.default + padding.horizontal,
    });

    return {
        title,
        chevron,
        header,
        padding,
        side,
    };
});
Example #4
0
export default function titleBarNavClasses() {
    const globalVars = globalVariables();
    const titleBarVars = titleBarVariables();
    const vars = titleBarNavigationVariables();
    const mediaQueries = layoutVariables().mediaQueries();
    const flex = flexHelper();
    const style = styleFactory("titleBarNav");

    const root = style(
        {
            ...flex.middleLeft(),
            position: "relative",
            height: unit(titleBarVars.sizing.height),
        },
        mediaQueries.oneColumnDown({
            height: unit(titleBarVars.sizing.mobile.height),
        }),
    );

    const navigation = style("navigation", {});

    const items = style(
        "items",
        {
            ...flex.middleLeft(),
            height: unit(titleBarVars.sizing.height),
            ...paddings(vars.padding),
        },
        mediaQueries.oneColumnDown({
            height: px(titleBarVars.sizing.mobile.height),
            justifyContent: "center",
            width: percent(100),
        }),
    );

    const link = style("link", {
        ...userSelect(),
        color: colorOut(titleBarVars.colors.fg),
        whiteSpace: "nowrap",
        lineHeight: globalVars.lineHeights.condensed,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        height: unit(vars.item.size),
        textDecoration: "none",
        $nest: {
            "&.focus-visible": {
                backgroundColor: colorOut(titleBarVars.buttonContents.state.bg),
            },
            "&:focus": {
                backgroundColor: colorOut(titleBarVars.buttonContents.state.bg),
            },
            "&:hover": {
                backgroundColor: colorOut(titleBarVars.buttonContents.state.bg),
            },
        },
    });

    const linkActive = style("linkActive", {
        $nest: {
            "&:after": {
                ...absolutePosition.topLeft(
                    `calc(50% - ${unit(vars.linkActive.height + vars.linkActive.bottomSpace)})`,
                ),
                content: quote(""),
                height: unit(vars.linkActive.height),
                marginLeft: unit(negative(vars.linkActive.offset)),
                width: calc(`100% + ${unit(vars.linkActive.offset * 2)}`),
                backgroundColor: colorOut(vars.linkActive.bg),
                transform: `translateY(${unit(titleBarVars.sizing.height / 2)})`,
            },
        },
    });

    const linkContent = style("linkContent", {
        position: "relative",
    });

    const firstItem = style("lastItem", {
        zIndex: 2,
    });

    const lastItem = style("lastItem", {
        zIndex: 2,
    });

    return {
        root,
        navigation,
        items,
        link,
        linkActive,
        linkContent,
        lastItem,
        firstItem,
    };
}
Example #5
0
export const panelLayoutClasses = useThemeCache(() => {
    const globalVars = globalVariables();
    const vars = layoutVariables();
    const mediaQueries = vars.mediaQueries();
    const style = styleFactory("panelLayout");
    const classesPanelArea = panelAreaClasses();
    const classesPanelList = panelListClasses();
    const titleBarVars = titleBarVariables();

    const main = style("main", {
        minHeight: viewHeight(20),
        width: percent(100),
    });

    const root = style({
        ...margins(vars.panelLayoutSpacing.margin),
        width: percent(100),
        $nest: {
            [`&.noBreadcrumbs > .${main}`]: {
                paddingTop: unit(globalVars.gutter.size),
                ...mediaQueries.oneColumnDown({
                    paddingTop: 0,
                }),
            },
            "&.isOneCol": {
                width: unit(vars.middleColumn.paddedWidth),
                maxWidth: percent(100),
                margin: "auto",
                ...mediaQueries.oneColumnDown({
                    width: percent(100),
                }),
            },
            "&.hasTopPadding": {
                paddingTop: unit(vars.panelLayoutSpacing.extraPadding.top),
            },
            "&.hasTopPadding.noBreadcrumbs": {
                paddingTop: unit(vars.panelLayoutSpacing.extraPadding.noBreadcrumbs.top),
            },
            "&.hasLargePadding": {
                ...paddings(vars.panelLayoutSpacing.largePadding),
            },
        },
    });

    const content = style("content", {
        display: "flex",
        flexGrow: 1,
        width: percent(100),
        justifyContent: "space-between",
    });

    const panel = style("panel", {
        width: percent(100),
        $nest: {
            [`& > .${classesPanelArea.root}:first-child .${classesPanelList.root}`]: {
                marginTop: unit(
                    (globalVars.fonts.size.title * globalVars.lineHeights.condensed) / 2 -
                        globalVariables().fonts.size.medium / 2,
                ),
            },
        },
    });

    const top = style("top", {
        width: percent(100),
        marginBottom: unit(globalVars.gutter.half),
    });

    const container = style("container", {
        display: "flex",
        flexWrap: "nowrap",
        alignItems: "flex-start",
        justifyContent: "space-between",
    });

    const fullWidth = style("fullWidth", {
        position: "relative",
        padding: 0,
    });

    const leftColumn = style("leftColumn", {
        position: "relative",
        width: unit(vars.panel.paddedWidth),
        flexBasis: unit(vars.panel.paddedWidth),
        minWidth: unit(vars.panel.paddedWidth),
    });

    const rightColumn = style("rightColumn", {
        position: "relative",
        width: unit(vars.panel.paddedWidth),
        flexBasis: unit(vars.panel.paddedWidth),
        minWidth: unit(vars.panel.paddedWidth),
        overflow: "initial",
    });

    const middleColumn = style("middleColumn", {
        justifyContent: "space-between",
        flexGrow: 1,
        width: percent(100),
        maxWidth: percent(100),
        ...mediaQueries.oneColumnDown(paddings({ left: important(0), right: important(0) })),
    });

    const middleColumnMaxWidth = style("middleColumnMaxWidth", {
        $nest: {
            "&.hasAdjacentPanel": {
                flexBasis: calc(`100% - ${unit(vars.panel.paddedWidth)}`),
                maxWidth: calc(`100% - ${unit(vars.panel.paddedWidth)}`),
                ...mediaQueries.oneColumnDown({
                    flexBasis: percent(100),
                    maxWidth: percent(100),
                }),
            },
            "&.hasTwoAdjacentPanels": {
                flexBasis: calc(`100% - ${unit(vars.panel.paddedWidth * 2)}`),
                maxWidth: calc(`100% - ${unit(vars.panel.paddedWidth * 2)}`),
                ...mediaQueries.oneColumnDown({
                    flexBasis: percent(100),
                    maxWidth: percent(100),
                }),
            },
        },
    });

    const breadcrumbs = style("breadcrumbs", {});

    const isSticky = style(
        "isSticky",
        {
            ...sticky(),
            top: titleBarVars.sizing.height * 2,
            height: percent(100),
            overflow: "auto",
        },
        mediaQueries.oneColumnDown({
            position: "relative",
            top: "auto",
            left: "auto",
            bottom: "auto",
        }),
    );

    // To remove when we have overlay styles converted
    cssRule(`.overlay .${root}.noBreadcrumbs .${main}`, {
        paddingTop: 0,
    });

    return {
        root,
        content,
        top,
        main,
        container,
        fullWidth,
        leftColumn,
        rightColumn,
        middleColumn,
        middleColumnMaxWidth,
        panel,
        isSticky,
        breadcrumbs,
    };
});
Example #6
0
export const searchBarClasses = useThemeCache(() => {
    const globalVars = globalVariables();
    const vars = searchBarVariables();
    const titleBarVars = titleBarVariables();
    const classesButton = buttonClasses();
    const formElementVars = formElementsVariables();
    const mediaQueries = layoutVariables().mediaQueries();
    const style = styleFactory("searchBar");

    const root = style(
        {
            cursor: "pointer",
            $nest: {
                "& .searchBar__placeholder": {
                    color: colorOut(globalVars.mixBgAndFg(0.5)),
                    margin: "auto",
                },

                "& .suggestedTextInput-valueContainer": {
                    $nest: {
                        ".inputBlock-inputText": {
                            height: "auto",
                        },
                    },
                },
                "& .searchBar-submitButton": {
                    position: "relative",
                    borderTopLeftRadius: important(0),
                    borderBottomLeftRadius: important(0),
                    marginLeft: unit(-globalVars.border.width * 2),
                    minWidth: unit(vars.search.minWidth),
                    flexBasis: unit(vars.search.minWidth),
                    minHeight: unit(vars.sizing.height),
                    $nest: {
                        "&:hover, &:focus": {
                            zIndex: 1,
                        },
                    },
                },
                "& .searchBar__control": {
                    display: "flex",
                    flex: 1,
                    border: 0,
                    backgroundColor: "transparent",
                    height: percent(100),
                    maxWidth: calc(`100% - ${unit(vars.sizing.height)}`),
                    $nest: {
                        "&.searchBar__control--is-focused": {
                            boxShadow: "none",
                            $nest: {
                                "&.inputText": {
                                    borderTopRightRadius: 0,
                                    borderBottomRightRadius: 0,
                                    ...borders(buttonVariables().standard.borders),
                                },
                            },
                        },
                    },
                },
                "& .searchBar__value-container": {
                    overflow: "auto",
                    $nest: {
                        "& > div": {
                            width: percent(100),
                        },
                    },
                },
                "& .searchBar__indicators": {
                    display: "none",
                },
                "& .searchBar__input": {
                    color: colorOut(globalVars.mainColors.fg),
                    width: percent(100),
                    display: important("block"),
                    $nest: {
                        input: {
                            width: important(percent(100).toString()),
                            lineHeight: globalVars.lineHeights.base,
                        },
                    },
                },
                "& .searchBar__menu-list": {
                    maxHeight: calc(`100vh - ${unit(titleBarVars.sizing.height)}`),
                },
            },
        },
        mediaQueries.oneColumnDown({
            $nest: {
                "& .searchBar-submitButton": {
                    minWidth: 0,
                },
            },
        }),
    );

    const results = style("results", {
        backgroundColor: colorOut(vars.results.bg),
        color: colorOut(vars.results.fg),
        $nest: {
            ".suggestedTextInput__placeholder": {
                color: colorOut(formElementVars.placeholder.color),
            },
            ".suggestedTextInput-noOptions": {
                padding: px(12),
            },
            ".suggestedTextInput-option": {
                width: percent(100),
                padding: px(12),
                textAlign: "left",
                display: "block",
                color: "inherit",
                $nest: {
                    "&:hover, &:focus, &.isFocused": {
                        color: "inherit",
                        backgroundColor: globalVars.states.hover.color.toString(),
                    },
                },
            },
            ".suggestedTextInput-menu": {
                borderRadius: unit(globalVars.border.radius),
                marginTop: unit(-formElementVars.border.width),
                marginBottom: unit(-formElementVars.border.width),
            },
            ".suggestedTextInput-item": {
                $nest: {
                    "& + .suggestedTextInput-item": {
                        borderTop: `solid 1px ${globalVars.border.color.toString()}`,
                    },
                },
            },
        },
    });

    const valueContainer = style("valueContainer", {
        display: "flex",
        alignItems: "center",
        borderRight: 0,
        paddingTop: 0,
        paddingBottom: 0,
        height: vars.sizing.height,
        backgroundColor: colorOut(vars.input.bg),
        color: colorOut(vars.input.fg),
        ...borderRadii({
            right: 0,
            left: vars.border.radius,
        }),
        $nest: {
            "&&&": {
                display: "flex",
                flexWrap: "nowrap",
                alignItems: "center",
                justifyContent: "flex-start",
                paddingLeft: unit(vars.searchIcon.gap),
            },
        },
    });

    // Has a search button attached.
    const compoundValueContainer = style("compoundValueContainer", {
        borderTopRightRadius: 0,
        borderBottomRightRadius: 0,
    });

    const actionButton = style("actionButton", {
        marginLeft: -vars.border.width,
        ...borderRadii({
            left: 0,
            right: vars.border.radius,
        }),
    });

    const label = style("label", {
        display: "flex",
        alignItems: "center",
        justifyContent: "flex-start",
    });

    const clear = style("clear", {
        position: "relative",
        display: "flex",
        boxSizing: "border-box",
        height: unit(vars.sizing.height),
        width: unit(vars.sizing.height),
        color: colorOut(globalVars.mixBgAndFg(0.78)),
        $nest: {
            "&, &.buttonIcon": {
                border: "none",
                boxShadow: "none",
            },
            "&:hover": {
                color: colorOut(globalVars.mainColors.primary),
            },
            "&:focus": {
                color: colorOut(globalVars.mainColors.primary),
            },
        },
    });

    const form = style("form", {
        display: "block",
    });

    const content = style("content", {
        display: "flex",
        alignItems: "flex-start",
        justifyContent: "flex-start",
        position: "relative",
        minHeight: unit(vars.sizing.height),
        $nest: {
            "&.hasFocus .searchBar-valueContainer": {
                borderColor: colorOut(globalVars.mainColors.primary),
            },
        },
    });

    // special selector
    const heading = style("heading", {
        $nest: {
            "&&": {
                marginBottom: unit(vars.heading.margin),
            },
        },
    });

    const iconContainer = style("iconContainer", {
        position: "absolute",
        top: 0,
        bottom: 0,
        left: "2px",
        height: percent(100),
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        width: unit(vars.searchIcon.gap),
        zIndex: 1,
    });
    const icon = style("icon", {
        width: unit(vars.searchIcon.width),
        height: unit(vars.searchIcon.height),
        color: colorOut(vars.searchIcon.fg),
    });

    return {
        root,
        compoundValueContainer,
        valueContainer,
        actionButton,
        label,
        clear,
        form,
        content,
        heading,
        iconContainer,
        icon,
        results,
    };
});
Example #7
0
export const modalClasses = useThemeCache(() => {
    const globalVars = globalVariables();
    const vars = modalVariables();
    const style = styleFactory("modal");
    const mediaQueries = layoutVariables().mediaQueries();
    const shadows = shadowHelper();
    const titleBarVars = titleBarVariables();

    const overlay = style("overlay", {
        position: "fixed",
        // Viewport units are useful here because
        // we're actually fine this being taller than the initially visible viewport.
        height: viewHeight(100),
        width: percent(100),
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        background: colorOut(vars.colors.overlayBg),
        zIndex: 10,
    });

    const root = style({
        display: "flex",
        flexDirection: "column",
        width: percent(100),
        maxWidth: percent(100),
        maxHeight: viewHeight(80),
        zIndex: 1,
        backgroundColor: colorOut(vars.colors.bg),
        position: "fixed",
        top: percent(50),
        left: percent(50),
        bottom: "initial",
        overflow: "hidden",
        borderRadius: unit(vars.border.radius),
        // NOTE: This transform can cause issues if anything inside of us needs fixed positioning.
        // See http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/
        // See also https://www.w3.org/TR/2009/WD-css3-2d-transforms-20091201/#introduction
        // This is why fullscreen unsets the transforms.
        transform: translate(`-50%`, `-50%`),
        ...margins({ all: "auto" }),

        $nest: {
            "&&.isFullScreen": {
                width: percent(100),
                height: percent(100),
                maxHeight: percent(100),
                maxWidth: percent(100),
                borderRadius: 0,
                border: "none",
                top: 0,
                bottom: 0,
                transform: "none",
                left: 0,
                right: 0,
            },
            "&.isLarge": {
                width: unit(vars.sizing.large),
                maxWidth: calc(`100% - ${unit(vars.spacing.horizontalMargin * 2)}`),
            },
            "&.isMedium": {
                width: unit(vars.sizing.medium),
                maxWidth: calc(`100% - ${unit(vars.spacing.horizontalMargin * 2)}`),
            },
            "&.isSmall": {
                width: unit(vars.sizing.small),
                maxWidth: calc(`100% - ${unit(vars.spacing.horizontalMargin * 2)}`),
            },
            "&&&.isSidePanel": {
                left: unit(vars.dropDown.padding),
                width: calc(`100% - ${unit(vars.dropDown.padding)}`),
                display: "flex",
                flexDirection: "column",
                top: 0,
                bottom: 0,
                right: 0,
                transform: "none",
                borderTopRightRadius: 0,
                borderBottomRightRadius: 0,
            },
            "&&.isDropDown": {
                top: 0,
                left: 0,
                right: 0,
                bottom: globalVars.gutter.size,
                width: percent(100),
                marginBottom: "auto",
                transform: "none",
                maxHeight: percent(100),
                borderTopLeftRadius: 0,
                borderTopRightRadius: 0,
            },
            "&.isShadowed": {
                ...shadows.dropDown(),
                ...borders(),
            },
        },
    });

    const scroll = style("scroll", {
        // ...absolutePosition.fullSizeOfParent(),
        width: percent(100),
        maxHeight: percent(100),
        overflow: "auto",
    });

    const content = style("content", shadows.modal());

    const pageHeader = style(
        "pageHeader",
        sticky(),
        {
            ...shadows.embed(),
            top: 0,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            height: unit(titleBarVars.sizing.height),
            minHeight: unit(titleBarVars.sizing.height),
            zIndex: 2,
            background: colorOut(vars.colors.bg),
            $nest: {
                "&.noShadow": {
                    boxShadow: "none",
                },
            },
        },
        mediaQueries.oneColumnDown({
            minHeight: unit(titleBarVars.sizing.mobile.height),
        }),
    );

    return {
        root,
        scroll,
        content,
        pageHeader,
        overlay,
    };
});
Example #8
0
export const messagesClasses = useThemeCache(() => {
    const vars = messagesVariables();
    const globalVars = globalVariables();
    const style = styleFactory("messages");
    const titleBarVars = titleBarVariables();
    const shadows = shadowHelper();
    const mediaQueries = layoutVariables().mediaQueries();

    // Fixed wrapper
    const fixed = style("fixed", {
        position: "fixed",
        left: 0,
        top: unit(titleBarVars.sizing.height - 8),
        minHeight: unit(vars.sizing.minHeight),
        width: percent(100),
        maxWidth: viewWidth(100),
        zIndex: 20,
    });

    const root = style(
        {
            width: percent(100),
        },
        margins({ horizontal: "auto" }),
    );

    const wrap = style(
        "wrap",
        {
            display: "flex",
            alignItems: "center",
            justifyContent: "flex-start",
            minHeight: unit(vars.sizing.minHeight),
            backgroundColor: colorOut(vars.colors.bg),
            width: percent(100),
            ...shadowOrBorderBasedOnLightness(
                globalVars.body.backgroundImage.color,
                borders({
                    color: globalVars.mainColors.fg,
                }),
                shadows.embed(),
            ),
            margin: "auto",
            color: colorOut(vars.colors.fg),
            ...paddings({
                ...vars.spacing.padding,
                right: vars.spacing.padding.horizontal / 2,
            }),
        },
        mediaQueries.xs({
            flexWrap: "wrap",
            paddingLeft: unit(vars.spacing.padding.horizontal / 2),
        }),
    );

    const message = style("message", {
        ...userSelect(),
        ...fonts(vars.text.font),
        flex: 1,
    });

    const setWidth = style("setWidth", {
        width: unit(vars.sizing.width),
        maxWidth: percent(100),
    });

    const actionButton = style(
        "actionButton",
        {
            ...paddings(vars.actionButton.padding),
            minHeight: unit(vars.actionButton.minHeight),
            whiteSpace: "nowrap",
            ...fonts(vars.actionButton.font),
            ...allButtonStates({
                noState: {
                    color: colorOut(vars.colors.fg),
                },
                allStates: {
                    color: colorOut(vars.colors.states.fg),
                },
                focusNotKeyboard: {
                    outline: 0,
                },
            }),
        },
        mediaQueries.xs({
            padding: 0,
            width: percent(100),
            textAlign: "center",
        }),
    );

    return {
        root,
        wrap,
        actionButton,
        message,
        fixed,
        setWidth,
    };
});
Example #9
0
export const compactSearchClasses = useThemeCache(() => {
    const globalVars = globalVariables();
    const formElementsVars = formElementsVariables();
    const titleBarVars = titleBarVariables();
    const vars = compactSearchVariables();
    const style = styleFactory("compactSearch");
    const mediaQueries = layoutVariables().mediaQueries();

    const root = style({
        $nest: {
            ".searchBar": {
                flexGrow: 1,
            },
            "& .searchBar__input": {
                color: colorOut(vars.colors.fg),
            },
            ".searchBar-valueContainer": {
                height: unit(formElementsVars.sizing.height),
                backgroundColor: colorOut(vars.colors.bg),
                border: 0,
            },
            ".hasFocus .searchBar-valueContainer": {
                backgroundColor: colorOut(vars.colors.active.bg),
            },
            ".searchBar__placeholder": {
                color: colorOut(vars.colors.placeholder),
            },
            ".searchBar-icon": {
                color: colorOut(vars.colors.placeholder),
            },
            "&.isOpen": {
                maxWidth: percent(100),
            },
            "&.isCentered": {
                margin: "auto",
            },
            ".suggestedTextInput-inputText": {
                borderTopRightRadius: unit(globalVars.border.radius),
                borderBottomRightRadius: unit(globalVars.border.radius),
            },
        },
    });

    const contents = style(
        "contents",
        {
            display: "flex",
            alignItems: "center",
            flexWrap: "nowrap",
            minHeight: unit(formElementsVars.sizing.height),
            justifyContent: "center",
        },
        mediaQueries.oneColumnDown({
            height: unit(titleBarVars.sizing.mobile.height),
        }),
    );

    const close = style("close", {
        color: "inherit",
        whiteSpace: "nowrap",
        fontWeight: globalVars.fonts.weights.semiBold,
    });

    const cancelContents = style("cancelContents", {
        padding: px(4),
    });
    return { root, contents, close, cancelContents };
});
Example #10
0
export const mobileDropDownClasses = useThemeCache(() => {
    const vars = mobileDropDownVariables();
    const globalVars = globalVariables();
    const frameVars = frameVariables();
    const titleBarVars = titleBarVariables();
    const mediaQueries = layoutVariables().mediaQueries();
    const flex = flexHelper();
    const style = styleFactory("mobileDropDown");

    const root = style({
        ...flex.middle(),
        position: "relative",
        flexGrow: 1,
        overflow: "hidden",
    });

    const modal = style("modal", {
        display: "flex",
        flexDirection: "column",
        justifyContent: "center",
        alignItems: "flex-start",
        $nest: {
            ".siteNav": {
                paddingLeft: px(globalVars.gutter.half),
            },
            "&.modal": {
                borderTopLeftRadius: 0,
                borderTopRightRadius: 0,
            },
        },
    });

    const panel = style("panel", {
        position: "relative",
        maxHeight: percent(100),
        padding: px(0),
    });

    const toggleButton = style(
        "toggleButton",
        {
            ...flex.middle(),
            ...userSelect(),
            flexGrow: 1,
            maxWidth: calc(`100% - ${px(globalVars.spacer.size)}`),
            marginLeft: px(globalVars.spacer.size / 2),
            marginRight: px(globalVars.spacer.size / 2),
            outline: 0,
        },
        mediaQueries.xs({
            maxWidth: percent(100),
            margin: 0,
            padding: px(0),
        }),
    );

    const buttonContents = style("buttonContents", {
        display: "inline-block",
        position: "relative",
        paddingRight: vars.chevron.width * 2,
        overflow: "hidden",
        textOverflow: "ellipsis",
        maxWidth: percent(100),
    });

    const title = style(
        "title",
        {
            display: "inline",
            letterSpacing: vars.title.letterSpacing,
            fontWeight: globalVars.fonts.weights.semiBold,
            textAlign: "center",
        },
        mediaQueries.xs({
            textAlign: "left",
        }),
    );

    const icon = style("icon", {
        position: "absolute",
        display: "block",
        top: 0,
        right: 0,
        bottom: 0,
        maxHeight: percent(100),
        maxWidth: percent(100),
        margin: `auto 0`,
        height: vars.chevron.height,
        width: vars.chevron.width,
    });

    const closeModalIcon = style("closeModalIcon", {
        padding: px(0),
        margin: "auto",
        color: vars.chevron.color.toString(),
        $nest: {
            "&:hover": {
                color: colorOut(globalVars.mainColors.primary),
            },
            "&:active": { color: colorOut(globalVars.mainColors.primary) },
            "&:focus": { color: colorOut(globalVars.mainColors.primary) },
        },
    });

    const closeModal = style("closeModal", {
        width: percent(100),
        height: percent(100),
    });

    const header = style("header", {
        borderBottom: singleBorder(),
    });

    const headerContent = style("headerContent", {
        display: "flex",
        flexWrap: "nowrap",
        alignItems: "center",
        height: unit(vars.header.minHeight - globalVars.border.width * 6),
        margin: "auto",
        width: percent(100),
    });

    const closeWidth =
        Math.floor(globalVars.icon.sizes.xSmall) + 2 * (globalVars.gutter.half + globalVars.gutter.quarter);
    const closeButton = style("closeButton", {
        ...absolutePosition.middleLeftOfParent(),
        height: unit(closeWidth),
        width: unit(closeWidth),
        minWidth: unit(closeWidth),
        padding: 0,
        transform: translateX("-50%"),
    });

    const subTitle = style("subTitle", {
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        textTransform: "uppercase",
        minHeight: unit(titleBarVars.sizing.height - 4),
        fontSize: unit(globalVars.fonts.size.small),
        textOverflow: "ellipsis",
        ...paddings({
            vertical: unit(4),
        }),
        ...fonts({
            size: globalVars.fonts.size.small,
            transform: "uppercase",
            color: globalVars.mixBgAndFg(0.6),
        }),
    });

    const listContainer = style("listContainer", {
        borderBottom: singleBorder(),
    });

    return {
        root,
        modal,
        panel,
        toggleButton,
        buttonContents,
        closeButton,
        title,
        icon,
        closeModalIcon,
        closeModal,
        header,
        headerContent,
        listContainer,
        subTitle,
    };
});