]> _ Git - ccv-wordpress.git/commitdiff
WIP #3053 @7.5
authorStephen Cameron <stephen@cubedesigners.com>
Mon, 30 Sep 2019 16:38:26 +0000 (18:38 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Mon, 30 Sep 2019 16:38:26 +0000 (18:38 +0200)
15 files changed:
wp-content/mu-plugins/cube-loader.php [new file with mode: 0644]
wp-content/mu-plugins/cube/composer.json [new file with mode: 0644]
wp-content/mu-plugins/cube/src/Common/Setup.php [new file with mode: 0644]
wp-content/mu-plugins/cube/src/Elementor/Setup.php [new file with mode: 0644]
wp-content/mu-plugins/cube/src/Elementor/Widgets/BackgroundImage.php [new file with mode: 0644]
wp-content/mu-plugins/cube/src/Elementor/Widgets/TextBlock.php [new file with mode: 0644]
wp-content/mu-plugins/cube/src/Init.php [new file with mode: 0644]
wp-content/themes/CCV/app/setup.php
wp-content/themes/CCV/resources/assets/styles/app.styl
wp-content/themes/CCV/resources/assets/styles/components/buttons.styl [new file with mode: 0644]
wp-content/themes/CCV/resources/assets/styles/components/headings.styl [new file with mode: 0644]
wp-content/themes/CCV/resources/assets/styles/widgets/background-image.styl [new file with mode: 0644]
wp-content/themes/CCV/resources/assets/styles/widgets/text-block.styl [new file with mode: 0644]
wp-content/themes/CCV/resources/views/partials/footer.blade.php
wp-content/themes/CCV/tailwind.config.js

diff --git a/wp-content/mu-plugins/cube-loader.php b/wp-content/mu-plugins/cube-loader.php
new file mode 100644 (file)
index 0000000..ede46dd
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Plugin Name: Custom theme features
+ * Description: Loads all custom functionality such as new post types and taxonomies.
+ * Version:  1.0
+ * Author: Cubedesigners
+ * Author URI: https://www.cubedesigners.com
+ */
+
+namespace Cube;
+
+defined('ABSPATH') or die('Direct access blocked');
+
+// Folder name for all plugin files (needed because MU-plugins can't be in folders so we need to put the loader outside)
+$plugin_dir = 'cube';
+$autoloader = __DIR__ . "/$plugin_dir/vendor/autoload.php";
+
+// Namespaced constants for easier path and URL references
+define(__NAMESPACE__ . '\NS', __NAMESPACE__ . '\\'); // Namespace shortcut: NS
+define(NS . 'PLUGIN_PATH', trailingslashit(plugin_dir_path(__FILE__) . $plugin_dir));
+define(NS . 'PLUGIN_URL', trailingslashit(plugin_dir_url(__FILE__) . $plugin_dir));
+
+// Load Composer libraries
+if (file_exists($autoloader)) {
+    require_once $autoloader;
+}
+
+if (class_exists(NS . 'Init')) {
+    Init::register_classes();
+}
diff --git a/wp-content/mu-plugins/cube/composer.json b/wp-content/mu-plugins/cube/composer.json
new file mode 100644 (file)
index 0000000..cda4e82
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "require": {
+
+    },
+    "autoload": {
+        "psr-4": {
+            "Cube\\": "./src"
+        }
+    }
+}
diff --git a/wp-content/mu-plugins/cube/src/Common/Setup.php b/wp-content/mu-plugins/cube/src/Common/Setup.php
new file mode 100644 (file)
index 0000000..5f5ff09
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+namespace Cube\Common;
+
+use Carbon_Fields\Carbon_Fields;
+
+class Setup {
+
+    /**
+     * Common setup, will be automatically triggered by Init class if included
+     */
+    public function register() {
+
+    }
+
+}
diff --git a/wp-content/mu-plugins/cube/src/Elementor/Setup.php b/wp-content/mu-plugins/cube/src/Elementor/Setup.php
new file mode 100644 (file)
index 0000000..b2168f0
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+
+namespace Cube\Elementor;
+
+use Elementor\Element_Base;
+use Elementor\Controls_Manager;
+use Elementor\Plugin;
+
+class Setup {
+
+    public function register() {
+
+        // Customise Elementor "section" element to allow layout options (via CSS classes applied to main section element)
+        $this->register_customisations();
+
+        // Register widgets with Elementor
+        add_action('elementor/widgets/widgets_registered', [$this, 'register_widgets']);
+    }
+
+
+    public function register_customisations() {
+
+        $this->_customise_sections();
+        $this->_customise_image_widget();
+
+    }
+
+
+    public function register_widgets() {
+
+        $elementor = Plugin::$instance;
+
+        $elementor->widgets_manager->register_widget_type( new Widgets\BackgroundImage() );
+        $elementor->widgets_manager->register_widget_type( new Widgets\TextBlock() );
+    }
+
+    protected function _customise_sections() {
+
+        // Override the main Elementor section element to allow custom controls to be added to the editor
+        // This allows us to set specific CSS classes on the section wrapper, thereby centralising control
+        // of necessary settings for each section layout (column width, padding etc)
+        //
+        // References:
+        // https://www.ibenic.com/extending-elementor-custom-button-field-skin/
+        // https://blogs.devforum.ro/customizing-elementor-default-widgets/
+        // https://github.com/pojome/elementor/issues/3495
+
+        // Add controls to section element in editor
+        add_action( 'elementor/element/section/section_layout/after_section_start', function( $element, $args ) {
+            /** @var \Elementor\Element_Base $element */
+            $element->add_control(
+                'block_layout',
+                [
+                    'label' => __('Custom Layout', 'cube'),
+                    'type' => Controls_Manager::SELECT,
+                    'options' => [
+                        'layout-default' => __( 'Default', 'cube' ),
+                        'layout-overlap-above' => __( 'Overlap Above', 'cube' ),
+                        'layout-overlap-below' => __( 'Overlap Below', 'cube' ),
+                    ],
+                    'default' => 'layout-default',
+                    'prefix_class' => '', // Use the full value as the classname (too late to change values after many pages have been built)
+                ]
+            );
+
+            $element->add_control(
+                'layout_reversed',
+                [
+                    'label' => __('Reverse layout?', 'cube'),
+                    'type' => Controls_Manager::SWITCHER,
+                    'default' => '',
+                    'return_value' => 'layout-reversed',
+                    'prefix_class' => '',
+                ]
+            );
+
+            $element->add_control(
+                'padding_top',
+                [
+                    'label' => __('Disable padding top', 'cube'),
+                    'type' => Controls_Manager::SWITCHER,
+                    'default' => '',
+                    'return_value' => 'pt0',
+                    'prefix_class' => '',
+                ]
+            );
+
+            $element->add_control(
+                'padding_bottom',
+                [
+                    'label' => __('Disable padding bottom', 'cube'),
+                    'type' => Controls_Manager::SWITCHER,
+                    'default' => '',
+                    'return_value' => 'pb0',
+                    'prefix_class' => '',
+                ]
+            );
+
+            $element->add_control(
+                'stacking_margins',
+                [
+                    'label' => __('Disable margins when stacking columns?', 'cube'),
+                    'type' => Controls_Manager::SWITCHER,
+                    'default' => '',
+                    'return_value' => 'no-column-stacking-gap',
+                    'prefix_class' => '',
+                ]
+            );
+
+        }, 10, 2 );
+
+
+        //--- Section shape divider
+        // Add a CSS class based on the shape divider type so we can style accordingly
+        // (extra padding needed when a divider is present)
+        add_action( 'elementor/element/section/section_shape_divider/before_section_end', function( $element, $args ) {
+            $elementor = Plugin::instance();
+
+            // Get the shape divider controls for updating
+            $divider_top = $elementor->controls_manager->get_control_from_stack( $element->get_name(), 'shape_divider_top' );
+            $divider_bottom = $elementor->controls_manager->get_control_from_stack( $element->get_name(), 'shape_divider_bottom' );
+
+            if (is_wp_error($divider_top) || is_wp_error($divider_top)) {
+                return;
+            }
+
+            // Add a prefix class so section will have a class that matches the divider type(s)
+            $divider_top['prefix_class'] = 'divider-top-';
+            $divider_top['render_type'] = 'template'; // Needed so class will be applied immediately in the editor
+            $element->update_control( 'shape_divider_top', $divider_top );
+            $divider_bottom['prefix_class'] = 'divider-bottom-';
+            $divider_bottom['render_type'] = 'template'; // Needed so class will be applied immediately in the editor
+            $element->update_control( 'shape_divider_bottom', $divider_bottom );
+        }, 10, 2);
+
+    }
+
+    protected function _customise_image_widget() {
+
+        // Add controls to image widget in editor
+        add_action( 'elementor/element/image/section_image/before_section_end', function( $element, $args ) {
+
+            /** @var \Elementor\Element_Base $element */
+            $element->add_control(
+                'link_icon',
+                [
+                    'label' => __( 'Link Icon', 'cube' ),
+                    'type' => Controls_Manager::SELECT,
+                    'options' => [
+                        '' => __( 'None', 'cube' ),
+                        'tour-360' => __( '360 Tour', 'cube' ),
+                        'enlarge' => __( 'Enlarge', 'cube' ),
+                    ],
+                    'default' => '',
+                    'prefix_class' => 'icon-',
+                    'condition' => [
+                        'link_to!' => 'none',
+                    ],
+                ]
+            );
+        }, 10, 2);
+
+    }
+
+}
diff --git a/wp-content/mu-plugins/cube/src/Elementor/Widgets/BackgroundImage.php b/wp-content/mu-plugins/cube/src/Elementor/Widgets/BackgroundImage.php
new file mode 100644 (file)
index 0000000..34780f9
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+namespace Cube\Elementor\Widgets;
+
+use Elementor\Widget_Base;
+use Elementor\Controls_Manager;
+use Elementor\Utils;
+
+
+class BackgroundImage extends Widget_Base {
+
+    protected $_has_template_content = false; // Tell Elementor that content is all rendered dynamically
+
+    // Widget name / ID
+    public function get_name() {
+        return 'cube-bg-image';
+    }
+
+    // Elementor widget title
+    public function get_title() {
+        return __( 'Flexible Image', 'cube' );
+    }
+
+    // Elementor interface icon
+    public function get_icon() {
+        return 'eicon-image';
+    }
+
+    // Where to display the widget in the Elementor interface
+    public function get_categories() {
+        return [ 'theme-elements' ];
+    }
+
+    /**
+     * List of scripts the widget depends on.
+     * Used to set scripts dependencies required to run the widget.
+     *
+     * @since 1.0.0
+     * @access public
+     * @return array Widget scripts dependencies.
+     */
+    public function get_script_depends() {
+        return [];
+    }
+    /**
+     * Register the widget controls.
+     * Adds different input fields to allow the user to change and customize the widget settings.
+     *
+     * @since 1.0.0
+     * @access protected
+     */
+    protected function _register_controls() {
+
+        $this->start_controls_section(
+            'section_image',
+            [
+                'label' => __( 'Flexible Background Image', 'cube' ),
+            ]
+        );
+        
+        $this->add_control(
+                       'image',
+                       [
+                               'label' => __( 'Choose Image', 'elementor' ),
+                               'type' => Controls_Manager::MEDIA,
+                               'default' => [
+                                       'url' => Utils::get_placeholder_image_src(),
+                               ],
+                       ]
+               );
+
+        $this->add_control(
+            'background_position',
+            [
+                'label' => __( 'Background Position', 'cube' ),
+                'type' => Controls_Manager::SELECT,
+                'default' => 'center',
+                'options' => [
+                    'top left' => __( 'Top Left', 'cube' ),
+                    'top center' => __( 'Top Center', 'cube' ),
+                    'top right' => __( 'Top Right', 'cube' ),
+                    'center' => __( 'Center', 'cube' ),
+                    'bottom left' => __( 'Bottom Left', 'cube' ),
+                    'bottom center' => __( 'Bottom Center', 'cube' ),
+                    'bottom right' => __( 'Bottom Right', 'cube' ),
+                ],
+            ]
+        );
+        
+        $this->end_controls_section();
+    }
+    /**
+     * Render the widget output on the frontend.
+     * Written in PHP and used to generate the final HTML.
+     *
+     * @since 1.0.0
+     * @access protected
+     */
+    protected function render() {
+
+        $image = $this->get_settings('image');
+        $bg_position = $this->get_settings('background_position');
+        $meta = wp_get_attachment_metadata($image['id']);
+        $ratio = $meta['height'] / $meta['width'] * 100 .'%';
+
+        echo '<div class="bg-image" style="background-image: url('. $image['url'] .'); background-position: '. $bg_position .'"><div class="bg-image-sizer" style="padding-bottom: '. $ratio .'"></div></div>';
+
+    }
+}
diff --git a/wp-content/mu-plugins/cube/src/Elementor/Widgets/TextBlock.php b/wp-content/mu-plugins/cube/src/Elementor/Widgets/TextBlock.php
new file mode 100644 (file)
index 0000000..d551029
--- /dev/null
@@ -0,0 +1,323 @@
+<?php
+
+namespace Cube\Elementor\Widgets;
+
+use Elementor\Widget_Base;
+use Elementor\Controls_Manager;
+
+
+class TextBlock extends Widget_Base {
+
+    // Widget name / ID
+    public function get_name() {
+        return 'cube-text';
+    }
+
+    // Elementor widget title
+    public function get_title() {
+        return __( 'Formatted Text', 'cube' );
+    }
+
+    // Elementor interface icon
+    public function get_icon() {
+        return 'eicon-align-left';
+    }
+
+    // Where to display the widget in the Elementor interface
+    public function get_categories() {
+        return [ 'theme-elements' ];
+    }
+
+    /**
+     * List of scripts the widget depends on.
+     * Used to set scripts dependencies required to run the widget.
+     *
+     * @since 1.0.0
+     * @access public
+     * @return array Widget scripts dependencies.
+     */
+    public function get_script_depends() {
+        return [];
+    }
+    /**
+     * Register the widget controls.
+     * Adds different input fields to allow the user to change and customize the widget settings.
+     *
+     * @since 1.0.0
+     * @access protected
+     */
+    protected function _register_controls() {
+
+        $this->start_controls_section(
+            'section_content',
+            [
+                'label' => __( 'Content', 'cube' ),
+            ]
+        );
+
+        $this->add_control(
+                       'title',
+                       [
+                               'label' => __( 'Title', 'elementor' ),
+                               'type' => Controls_Manager::TEXTAREA,
+                               'placeholder' => __( 'Enter your title', 'elementor' ),
+                               'default' => '',
+                       ]
+        );
+
+        $this->add_control(
+                       'body',
+                       [
+                               'label' => __('Body', 'cube'),
+                               'type' => Controls_Manager::WYSIWYG,
+                               'default' => '',
+                       ]
+        );
+
+        $this->add_control(
+            'cta_text',
+            [
+                'label' => __('Call to Action text', 'cube'),
+                'type' => Controls_Manager::TEXT,
+                'default' => ''
+            ]
+        );
+
+        $this->add_control(
+            'cta_link',
+            [
+                'label' => __('Call to Action link', 'cube'),
+                'type' => Controls_Manager::URL,
+                'default' => [
+                    'url' => '',
+                    'is_external' => false,
+                ],
+                   'show_external' => true
+            ]
+        );
+       
+        $this->end_controls_section();
+
+
+        $this->start_controls_section(
+            'section_formatting',
+            [
+                'label' => __( 'Colours & Formatting', 'cube' ),
+            ]
+        );
+
+        $this->add_control(
+            'padding_top',
+            [
+                'label' => __('Disable padding top', 'cube'),
+                'type' => Controls_Manager::SWITCHER,
+                'default' => '',
+                'return_value' => 'pt-0',
+                'prefix_class' => '',
+            ]
+        );
+
+        $this->add_control(
+            'padding_bottom',
+            [
+                'label' => __('Disable padding bottom', 'cube'),
+                'type' => Controls_Manager::SWITCHER,
+                'default' => '',
+                'return_value' => 'pb-0',
+                'prefix_class' => '',
+            ]
+        );
+
+        $this->add_control(
+                       'title_size',
+                       [
+                               'label' => __( 'Title Size', 'cube' ),
+                'type' => Controls_Manager::SELECT,
+                'options' => [
+                    '' => __( 'Default', 'cube' ),
+                    'medium' => __( 'Medium', 'cube' ),
+                ],
+                'default' => '',
+                       ]
+        );
+
+        $this->add_control(
+                       'title_color',
+                       [
+                               'label' => __( 'Title Colour', 'cube' ),
+                               'type' => Controls_Manager::COLOR,
+                               'default' => '',
+                               'selectors' => [
+                                       '{{WRAPPER}} .text-block-title' => 'color: {{VALUE}};',
+                               ],
+                       ]
+        );
+
+
+        $this->add_control(
+                       'body_color',
+                       [
+                               'label' => __( 'Body Colour', 'cube' ),
+                               'type' => Controls_Manager::COLOR,
+                               'default' => '',
+                               'selectors' => [
+                                       '{{WRAPPER}} .text-block-body' => 'color: {{VALUE}};',
+                               ],
+                       ]
+        );
+
+
+        $this->add_responsive_control(
+                       'align',
+                       [
+                               'label' => __( 'Alignment', 'elementor' ),
+                               'type' => Controls_Manager::CHOOSE,
+                               'options' => [
+                                       'left' => [
+                                               'title' => __( 'Left', 'elementor' ),
+                                               'icon' => 'fa fa-align-left',
+                                       ],
+                                       'center' => [
+                                               'title' => __( 'Center', 'elementor' ),
+                                               'icon' => 'fa fa-align-center',
+                                       ],
+                                       'right' => [
+                                               'title' => __( 'Right', 'elementor' ),
+                                               'icon' => 'fa fa-align-right',
+                                       ],
+                                       'justify' => [
+                                               'title' => __( 'Justified', 'elementor' ),
+                                               'icon' => 'fa fa-align-justify',
+                                       ],
+                               ],
+                               'default' => '',
+                               'selectors' => [
+                                       '{{WRAPPER}}' => 'text-align: {{VALUE}}; margin: 0 auto;',
+                               ],
+                       ]
+        );
+        
+        $this->add_control(
+                       'max_width',
+                       [
+                               'label' => __( 'Maximum Width', 'cube' ),
+                               'type' => Controls_Manager::SLIDER,
+                               // 'default' => [
+                               //      'size' => 400,
+                               // ],
+                               'range' => [
+                                       'px' => [
+                                               'min' => 400,
+                        'max' => 1600,
+                        'step' => 10,
+                                       ],
+                                       '%' => [
+                                               'min' => 0,
+                                               'max' => 100,
+                                       ],
+                               ],
+                               'selectors' => [
+                                       '{{WRAPPER}} .text-block' => 'max-width: {{SIZE}}{{UNIT}};',
+                               ],
+                       ]
+               );
+
+        $this->end_controls_section();
+    }
+    /**
+     * Render the widget output on the frontend.
+     * Written in PHP and used to generate the final HTML.
+     *
+     * @since 1.0.0
+     * @access protected
+     */
+    protected function render() {
+
+        $title = $this->get_settings('title');
+        $title_size = $this->get_settings('title_size');
+        $body = $this->parse_text_editor($this->get_settings('body'));
+        $cta_text = $this->get_settings('cta_text');
+        $cta_link = $this->get_settings('cta_link');
+
+        if ( ! empty( $cta_link['url'] ) ) {
+            $this->add_render_attribute( 'cta_text', 'href', $cta_link['url'] );
+
+            if ( $cta_link['is_external'] ) {
+                $this->add_render_attribute( 'cta_text', 'target', '_blank' );
+            }
+
+            if ( $cta_link['nofollow'] ) {
+                $this->add_render_attribute( 'cta_text', 'rel', 'nofollow' );
+            }
+        }
+
+        // Inline Editing settings
+        $this->add_inline_editing_attributes('title', 'none');
+        $this->add_inline_editing_attributes('body', 'advanced');
+        $this->add_inline_editing_attributes('cta_text', 'none');
+
+        // CSS Classes for elements
+        $this->add_render_attribute('title', 'class', ['text-block-title h2 decorated']);
+        $this->add_render_attribute('body', 'class', ['text-block-body']);
+        $this->add_render_attribute('cta_text', 'class', ['text-block-cta arrow-link']);
+
+        if (!empty($title_size)) {
+            $this->add_render_attribute('title', 'class', ["text-block-title-size-{$title_size}"]);
+        }
+
+        // Rendered content
+        echo '<div class="text-block">';
+        if (!empty($title)) echo "<h2 {$this->get_render_attribute_string('title')}>$title</h2>";
+        if (!empty($body)) echo "<div {$this->get_render_attribute_string('body')}>$body</div>";
+        if (!empty($cta_text)) {
+            echo '<a '. $this->get_render_attribute_string('cta_text') .'>';
+            echo $cta_text;
+            echo '</a>';
+        }
+        echo '</div>';
+    }
+
+    /**
+        * Render text editor widget output in the editor.
+        *
+        * Written as a Backbone JavaScript template and used to generate the live preview.
+        *
+        * @since 1.0.0
+        * @access protected
+        */
+       protected function _content_template() {
+    ?>
+               <#
+               view.addRenderAttribute( 'title', 'class', ['text-block-title h2 decorated']);
+               view.addRenderAttribute( 'body', 'class', ['text-block-body']);
+               view.addRenderAttribute( 'cta_text', 'class', ['text-block-cta arrow-link']);
+
+        if ('' !== settings.title_size) {
+            view.addRenderAttribute('title', 'class', ['text-block-title-size-' + settings.title_size]);
+        }
+
+        view.addInlineEditingAttributes( 'title', 'none' );
+               view.addInlineEditingAttributes( 'body', 'advanced' );
+               view.addInlineEditingAttributes( 'cta_text', 'none' );
+        #>
+        <div class="text-block">
+
+            <# if ('' !== settings.title) { #>
+                <h2 {{{ view.getRenderAttributeString( 'title' ) }}}>{{{ settings.title }}}</h2>
+            <# } #>
+
+            <# if ('' !== settings.body) { #>
+                <div {{{ view.getRenderAttributeString( 'body' ) }}}>{{{ settings.body }}}</div>
+            <# } #>
+
+            <# if ('' !== settings.cta_text) { #>
+                <a {{{ view.getRenderAttributeString( 'cta_text' ) }}}>
+                    {{{ settings.cta_text }}}
+                </a>
+            <# } #>
+
+        </div>
+    <?php
+       }
+
+}
diff --git a/wp-content/mu-plugins/cube/src/Init.php b/wp-content/mu-plugins/cube/src/Init.php
new file mode 100644 (file)
index 0000000..e93ae26
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+// Setup reference: https://www.youtube.com/watch?v=NdDRNiIfYDw
+
+namespace Cube;
+
+
+final class Init { // Marked as final because this class should never be extended (single init only!)
+
+    /**
+     * List of service classes to be used
+     * @return array Array of classes to be instantiated
+     */
+    public static function classes() {
+        return [
+            Common\Setup::class,
+            Elementor\Setup::class,
+        ];
+    }
+
+    /**
+     * Register all services (custom post types, custom fields, shortcodes etc)
+     */
+    public static function register_classes() {
+        foreach (self::classes() as $class) {
+            $service = self::instantiate($class);
+
+            // If the class has a register method, call it.
+            if (method_exists($service, 'register')) {
+                $service->register();
+            }
+        }
+    }
+
+    /**
+     * @param class $class Class from the services array
+     * @return class instance New instance of the class
+     */
+    private static function instantiate($class) {
+        return new $class();
+    }
+}
index 9785ff0d8ea94a287af7c3f2ecc6ee6f3dfe77e8..7e15ea69317d9fbd64a9cb53e770583f3024288f 100755 (executable)
@@ -88,7 +88,7 @@ add_action('widgets_init', function () {
     $config = [
         'before_widget' => '<section class="widget %1$s %2$s">',
         'after_widget' => '</section>',
-        'before_title' => '<h3>',
+        'before_title' => '<h3 class="widget-title h3 decorated uppercase mb-3">',
         'after_title' => '</h3>'
     ];
 
index d3bcac71cbeb43e57333eceec170320fc15201f9..8dc55226095a41ccaad17189c9eeb5c001124bf5 100644 (file)
@@ -12,6 +12,7 @@
 
 // Extracted components or custom styles that can't be done with utilities
 @import 'components/*'
+@import 'widgets/*'
 //@import 'pages/*'
 
 // Utilities go last in source order so they can
diff --git a/wp-content/themes/CCV/resources/assets/styles/components/buttons.styl b/wp-content/themes/CCV/resources/assets/styles/components/buttons.styl
new file mode 100644 (file)
index 0000000..8527e28
--- /dev/null
@@ -0,0 +1,52 @@
+// Buttons
+
+.btn
+  @apply relative inline-block overflow-hidden
+  @apply bg-pink text-white
+  @apply font-bold text-xs uppercase
+  @apply px-10 py-3
+  font-smoothing()
+
+  &-text
+    @apply z-10 relative
+
+  &-no-hover:before
+    display: none
+
+  &:hover:before
+    transform: scaleX(1)
+    opacity: 1
+
+  //&:before
+  //  content: ''
+  //  position: absolute
+  //  top: 0
+  //  left: 0
+  //  width: 100%
+  //  height: 100%
+  //  z-index: 1
+  //  background-color: rgba(#fff, 0.2)
+  //  transform: scaleX(0)
+  //  transform-origin: left
+  //  transition: transform 0.2s ease-out
+
+  // Circle hover effect
+  &:hover:before
+    transform: scale(1.1) translateY(-50%)
+    opacity: 1
+
+  &:before
+    content: ''
+    position: absolute
+    top: 50%
+    left: 0
+    z-index: 1
+    background-color: rgba(#fff, 0.15)
+    width: 100%
+    padding-bottom: 100%
+    border-radius: 50%
+    transform: scale(0) translateY(-50%)
+    transform-origin: top center
+    transition: all 0.2s ease-out
+    opacity: 0
+
diff --git a/wp-content/themes/CCV/resources/assets/styles/components/headings.styl b/wp-content/themes/CCV/resources/assets/styles/components/headings.styl
new file mode 100644 (file)
index 0000000..1e0272f
--- /dev/null
@@ -0,0 +1,34 @@
+h1, .h1, h2, .h2
+  @apply font-display font-medium mb-2 uppercase
+  line-height: 1.1
+
+h1, .h1
+  @apply text-3xl
+
+h2, .h2
+  @apply text-2xl
+
+// Pink dash
+h1, .h1, h2, .h2, .decorated
+  @apply relative
+
+  &:before
+    content: ''
+    display: block
+    position: absolute
+    top: 0.6em
+    constrain(left, -5vw)
+    constrain(width, 2.5vw)
+    height: 5px
+    background: theme('colors.pink')
+
+
+h3, .h3, h4, .h4
+  @apply font-medium
+  line-height: 1.4
+
+h3, .h3
+  @apply font-display text-xl
+
+h4, .h4
+  @apply text-lg
diff --git a/wp-content/themes/CCV/resources/assets/styles/widgets/background-image.styl b/wp-content/themes/CCV/resources/assets/styles/widgets/background-image.styl
new file mode 100644 (file)
index 0000000..8600bbf
--- /dev/null
@@ -0,0 +1,15 @@
+.bg-image
+  background-size: cover
+  background-repeat: no-repeat
+  background-position: center
+
+  &-sizer
+    // The sizer is only needed when in one column mode.
+    // The rest of the time it should just fill the height
+    // required by the other column's content...
+    +above($breakpoint-columns)
+      display: none
+
+// Ensure full height on element so the image always covers the full area
+.elementor-widget-cube-bg-image, .elementor-widget-container, .bg-image
+  height: 100%
diff --git a/wp-content/themes/CCV/resources/assets/styles/widgets/text-block.styl b/wp-content/themes/CCV/resources/assets/styles/widgets/text-block.styl
new file mode 100644 (file)
index 0000000..e0b987a
--- /dev/null
@@ -0,0 +1,51 @@
+// Text block widget (Elementor defaults)
+.elementor-widget-cube-text //.elementor-widget-container
+  vertical-spacing(5vw)
+  constrain(padding-left, 10vw)
+  constrain(padding-right, 7.5vw)
+  max-width: 640px
+  width: 100%
+  box-sizing: content-box // So padding doesn't influence max-width
+
+  +below(450px)
+    horizontal-spacing(2.5vw)
+
+.text-block
+
+  &-title
+    @apply text-2xl antialiased
+    white-space: pre-line
+
+    +below(1600px)
+      white-space: normal // Avoid strange gaps caused by pre-line breaks wrapping
+      font-size: 4.25vw // Using vw units so headings scale instead of wrapping further
+    +below(795px) // Cap font size to medium once the vw size matches medium size
+      @apply text-xl // Note: also affected by the base HTML font size since it is converted rems
+
+    // No bottom margin if it's the last element (ie. no body below)
+    &:last-child
+      margin-bottom: 0
+
+  &-body
+    font-weight: 400
+    margin-top: r(40px)
+
+    // If the body is the first child, there's no title
+    // so we don't want the top margin...
+    &:first-child
+      margin-top: 0
+
+    h3
+      @apply font-medium text-lg
+
+    a
+      color: theme('colors.pink')
+
+  &-cta
+    @apply antialiased
+    margin-top: r(30px)
+
+    // If the CTA is the first child, it means it is the only element
+    // in the text block so we don't want the top margin...
+    &:first-child
+      margin-top: 0
index e9dd92ae794f2c3bd016f3ed58963da6164da7cb..90a450a527e3ae56ff25a448cf0d5d842584b2f0 100644 (file)
@@ -1,16 +1,16 @@
-<footer class="bg-purple-dark text-white pt-3v pb-1v">
-  <div class="container">
+<footer class="bg-purple-dark text-white antialiased pt-2v pb-1v">
+  <div class="container pl-0 pr-0">
     <div class="flex pb-2v">
-      <div class="w-1/2 text-block">
+      <div class="w-1/2 px-4v">
         @php(dynamic_sidebar('sidebar-footer-1'))
       </div>
-      <div class="w-1/2 text-block">
+      <div class="w-1/2 px-4v">
       @php(dynamic_sidebar('sidebar-footer-2'))
       </div>
     </div>
 
     {{-- Copyright message and links --}}
-    <div class="pl-2v text-sm opacity-50">
+    <div class="pl-4v text-sm opacity-50">
       @php(dynamic_sidebar('sidebar-footer-copyright'))
     </div>
   </div>
index 3fd5860facad905185482adcce5843cb4758f427..099a81df10e7dc77c3f6f42b10e1db957cf9368a 100644 (file)
@@ -16,7 +16,11 @@ module.exports = {
       },
       fontSize: {
         'xs': '0.8181rem', // 18px
-        'sm': '0.9090rem', // 20px
+        'sm': '0.9091rem', // 20px
+        'lg': '1.3636rem', // 30px
+        'xl': '1.9091rem', // 42px
+        '2xl': '2.4545rem', // 54px
+        '3xl': '3.0909rem', // 68px
       }
     },
   },