{"id":342931,"date":"2026-07-20T11:15:19","date_gmt":"2026-07-20T11:15:19","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/arts-horizontal-scroll-for-elementor\/"},"modified":"2026-08-20T12:31:52","modified_gmt":"2026-08-20T12:31:52","slug":"horizontal-scroll-for-elementor","status":"publish","type":"plugin","link":"https:\/\/test.wordpress.org\/plugins\/horizontal-scroll-for-elementor\/","author":23271239,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2.0","stable_tag":"1.2.0","tested":"7.1","requires":"6.5","requires_php":"8.0","requires_plugins":null,"header_name":"Arts Horizontal Scroll for Elementor","header_author":"Artem Semkin","header_description":"Pinned horizontal-scroll sections \u2014 every panel is a real nested Container you design inline. Vertical re-layout on touch. No GSAP, no jQuery.","assets_banners_color":"4c4c4c","last_updated":"2026-08-20 12:31:52","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/buymeacoffee.com\/artemsemkin","header_plugin_uri":"https:\/\/artemsemkin.com\/plugins\/horizontal-scroll-for-elementor\/","header_author_uri":"https:\/\/artemsemkin.com","rating":0,"author_block_rating":0,"active_installs":10,"downloads":282,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"artemsemkin","date":"2026-07-20 12:12:25"},"1.0.1":{"tag":"1.0.1","author":"artemsemkin","date":"2026-08-13 07:48:36"},"1.0.2":{"tag":"1.0.2","author":"artemsemkin","date":"2026-08-20 03:44:38"},"1.0.3":{"tag":"1.0.3","author":"artemsemkin","date":"2026-08-20 04:29:55"},"1.1.0":{"tag":"1.1.0","author":"artemsemkin","date":"2026-08-20 08:57:19"},"1.2.0":{"tag":"1.2.0","author":"artemsemkin","date":"2026-08-20 12:31:52"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3614622,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3614622,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3614622,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3614622,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3614622,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3656834,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/post.php?post=9911&action=elementor\",\"preferredVersions\":{\"php\":\"8.1\",\"wp\":\"latest\"},\"features\":{\"networking\":true},\"login\":true,\"steps\":[{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"elementor\"},\"options\":{\"activate\":true}},{\"step\":\"installTheme\",\"themeData\":{\"resource\":\"wordpress.org\\\/themes\",\"slug\":\"hello-elementor\"},\"options\":{\"activate\":true}},{\"step\":\"writeFile\",\"path\":\"\\\/wordpress\\\/wp-content\\\/horizontal-scroll-for-elementor-demo-seed.php\",\"data\":\"<?php\\n\\\/**\\n * Seeds the \\\"Arts Horizontal Scroll \\u2014 Demo\\\" feature-tour page.\\n *\\n * Run against the Local dev site:\\n *   wp eval-file dev\\\/seed\\\/demo-page.php --user=1\\n *\\n * Also inlined into .wordpress-org\\\/blueprints\\\/blueprint.json as a writeFile\\n * step by `arts-wp blueprint build`, then required from the runPHP step that\\n * follows it (no wp-cli context there \\u2014 the WP_CLI:: calls below are guarded\\n * for that reason). Idempotent: finds the page by slug and rewrites it\\n * wholesale. All styling is hard-coded (no kit globals, no fluid presets)\\n * because the blueprint boots bare hello-elementor + free Elementor. The two\\n * Motion FX garnishes are Elementor Pro settings that stay inert without Pro.\\n *\\\/\\n\\nif ( ! defined( 'ABSPATH' ) ) {\\n\\texit;\\n}\\n\\n\\\/**\\n * Pinned so the blueprint's landingPage can address the page without guessing.\\n * The blueprint generator regexes this constant out of the file \\u2014 keep the\\n * literal on one line.\\n *\\\/\\ndefine( 'AHS_DEMO_PAGE_ID', 9911 );\\n\\n\\\/\\\/ Elementor otherwise hijacks the first admin request with its onboarding\\n\\\/\\\/ wizard, which would land the Playground visitor somewhere other than the\\n\\\/\\\/ editor. Harmless on an already-onboarded dev site.\\nupdate_option( 'elementor_onboarded', true );\\ndelete_transient( 'elementor_activation_redirect' );\\n\\nconst AHS_HAIRLINE       = 'rgba(255,255,255,0.08)';\\nconst AHS_TEXT           = '#F4F4F2';\\nconst AHS_MUTED          = '#8A8A8E';\\nconst AHS_BODY_MUTED     = '#9A9AA0';\\nconst AHS_PADDING        = array(\\n\\t'unit'     => 'px',\\n\\t'top'      => '40',\\n\\t'right'    => '44',\\n\\t'bottom'   => '40',\\n\\t'left'     => '44',\\n\\t'isLinked' => false,\\n);\\nconst AHS_PADDING_MOBILE = array(\\n\\t'unit'     => 'px',\\n\\t'top'      => '24',\\n\\t'right'    => '20',\\n\\t'bottom'   => '24',\\n\\t'left'     => '20',\\n\\t'isLinked' => false,\\n);\\n\\\/\\\/ Readability caps (act as max-width: narrow panels still win).\\nconst AHS_TITLE_CAP    = array(\\n\\t'_element_width'        => 'initial',\\n\\t'_element_custom_width' => array(\\n\\t\\t'unit' => 'custom',\\n\\t\\t'size' => 'min(900px, 100%)',\\n\\t),\\n);\\nconst AHS_SUBTITLE_CAP = array(\\n\\t'_element_width'        => 'initial',\\n\\t'_element_custom_width' => array(\\n\\t\\t'unit' => 'custom',\\n\\t\\t'size' => 'min(700px, 100%)',\\n\\t),\\n);\\n\\nfunction ahs_seed_id(): string {\\n\\treturn substr( bin2hex( random_bytes( 4 ) ), 0, 7 );\\n}\\n\\n\\\/** fadeIn entrance with a stagger slot (1-6 \\u2192 80..580ms). *\\\/\\nfunction ahs_anim( int $slot ): array {\\n\\treturn array(\\n\\t\\t'_animation'       => 'fadeIn',\\n\\t\\t'_animation_delay' => 80 + ( $slot - 1 ) * 100,\\n\\t);\\n}\\n\\nfunction ahs_zero_gap(): array {\\n\\treturn array(\\n\\t\\t'unit'     => 'px',\\n\\t\\t'column'   => '0',\\n\\t\\t'row'      => '0',\\n\\t\\t'isLinked' => true,\\n\\t);\\n}\\n\\nfunction ahs_gap( int $px ): array {\\n\\treturn array(\\n\\t\\t'unit'     => 'px',\\n\\t\\t'column'   => (string) $px,\\n\\t\\t'row'      => (string) $px,\\n\\t\\t'isLinked' => true,\\n\\t);\\n}\\n\\n\\\/** Small uppercase meta label. *\\\/\\nfunction ahs_mono_label( string $title, array $extra = array() ): array {\\n\\treturn array(\\n\\t\\t'id'         => ahs_seed_id(),\\n\\t\\t'elType'     => 'widget',\\n\\t\\t'widgetType' => 'heading',\\n\\t\\t'settings'   => array_merge(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'title'                     => $title,\\n\\t\\t\\t\\t'header_size'               => 'p',\\n\\t\\t\\t\\t'title_color'               => AHS_MUTED,\\n\\t\\t\\t\\t'typography_typography'     => 'custom',\\n\\t\\t\\t\\t'typography_font_family'    => 'Space Grotesk',\\n\\t\\t\\t\\t'typography_font_size'      => array(\\n\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t'size'  => 11,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_letter_spacing' => array(\\n\\t\\t\\t\\t\\t'unit'  => 'em',\\n\\t\\t\\t\\t\\t'size'  => 0.12,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_text_transform' => 'uppercase',\\n\\t\\t\\t),\\n\\t\\t\\t$extra\\n\\t\\t),\\n\\t\\t'elements'   => array(),\\n\\t);\\n}\\n\\n\\\/** Oversized display heading (Space Grotesk 500). *\\\/\\nfunction ahs_display_heading( string $title, string $tag, string $font_size, array $extra = array() ): array {\\n\\treturn array(\\n\\t\\t'id'         => ahs_seed_id(),\\n\\t\\t'elType'     => 'widget',\\n\\t\\t'widgetType' => 'heading',\\n\\t\\t'settings'   => array_merge(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'title'                     => $title,\\n\\t\\t\\t\\t'header_size'               => $tag,\\n\\t\\t\\t\\t'title_color'               => AHS_TEXT,\\n\\t\\t\\t\\t'typography_typography'     => 'custom',\\n\\t\\t\\t\\t'typography_font_family'    => 'Space Grotesk',\\n\\t\\t\\t\\t'typography_font_weight'    => '500',\\n\\t\\t\\t\\t'typography_font_size'      => array(\\n\\t\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t\\t'size' => $font_size,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_line_height'    => array(\\n\\t\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t\\t'size' => '0.92',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_letter_spacing' => array(\\n\\t\\t\\t\\t\\t'unit'  => 'em',\\n\\t\\t\\t\\t\\t'size'  => -0.02,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t$extra\\n\\t\\t),\\n\\t\\t'elements'   => array(),\\n\\t);\\n}\\n\\n\\\/** Muted body paragraph (Space Grotesk regular). *\\\/\\nfunction ahs_body_text( string $title, array $extra = array() ): array {\\n\\treturn array(\\n\\t\\t'id'         => ahs_seed_id(),\\n\\t\\t'elType'     => 'widget',\\n\\t\\t'widgetType' => 'heading',\\n\\t\\t'settings'   => array_merge(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'title'                  => $title,\\n\\t\\t\\t\\t'header_size'            => 'p',\\n\\t\\t\\t\\t'title_color'            => AHS_BODY_MUTED,\\n\\t\\t\\t\\t'typography_typography'  => 'custom',\\n\\t\\t\\t\\t'typography_font_family' => 'Space Grotesk',\\n\\t\\t\\t\\t'typography_font_size'   => array(\\n\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t'size'  => 16,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_line_height' => array(\\n\\t\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t\\t'size' => '1.5',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t$extra\\n\\t\\t),\\n\\t\\t'elements'   => array(),\\n\\t);\\n}\\n\\n\\\/** Pill button (transparent, hairline border, fully rounded). *\\\/\\nfunction ahs_pill_button( string $text, string $url, array $extra = array() ): array {\\n\\treturn array(\\n\\t\\t'id'         => ahs_seed_id(),\\n\\t\\t'elType'     => 'widget',\\n\\t\\t'widgetType' => 'button',\\n\\t\\t'settings'   => array_merge(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'text'                     => $text,\\n\\t\\t\\t\\t'link'                     => array(\\n\\t\\t\\t\\t\\t'url'         => $url,\\n\\t\\t\\t\\t\\t'is_external' => '',\\n\\t\\t\\t\\t\\t'nofollow'    => '',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'button_text_color'        => AHS_TEXT,\\n\\t\\t\\t\\t\\\/\\\/ Group_Control_Background defaults to the kit's global accent\\n\\t\\t\\t\\t\\\/\\\/ color when unset \\u2014 explicit here so the pill stays transparent\\n\\t\\t\\t\\t\\\/\\\/ regardless of which kit\\\/theme the demo boots against.\\n\\t\\t\\t\\t'background_background'    => 'classic',\\n\\t\\t\\t\\t'background_color'         => 'transparent',\\n\\t\\t\\t\\t'border_border'            => 'solid',\\n\\t\\t\\t\\t'border_width'             => array(\\n\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t'top'      => '1',\\n\\t\\t\\t\\t\\t'right'    => '1',\\n\\t\\t\\t\\t\\t'bottom'   => '1',\\n\\t\\t\\t\\t\\t'left'     => '1',\\n\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'border_color'             => 'rgba(255,255,255,0.2)',\\n\\t\\t\\t\\t'border_radius'            => array(\\n\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t'top'      => '999',\\n\\t\\t\\t\\t\\t'right'    => '999',\\n\\t\\t\\t\\t\\t'bottom'   => '999',\\n\\t\\t\\t\\t\\t'left'     => '999',\\n\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'text_padding'             => array(\\n\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t'top'      => '12',\\n\\t\\t\\t\\t\\t'right'    => '22',\\n\\t\\t\\t\\t\\t'bottom'   => '12',\\n\\t\\t\\t\\t\\t'left'     => '22',\\n\\t\\t\\t\\t\\t'isLinked' => false,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_typography'    => 'custom',\\n\\t\\t\\t\\t'typography_font_family'   => 'Space Grotesk',\\n\\t\\t\\t\\t'typography_font_size'     => array(\\n\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t'size'  => 15,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'typography_font_weight'   => '500',\\n\\t\\t\\t\\t'hover_color'              => AHS_TEXT,\\n\\t\\t\\t\\t'button_background_hover_background' => 'classic',\\n\\t\\t\\t\\t'button_background_hover_color'      => 'transparent',\\n\\t\\t\\t\\t'button_hover_border_color' => AHS_TEXT,\\n\\t\\t\\t),\\n\\t\\t\\t$extra\\n\\t\\t),\\n\\t\\t'elements'   => array(),\\n\\t);\\n}\\n\\n\\\/**\\n * Inner structural container. Explicit zero padding + gap: the kit's default\\n * container padding and --widgets-spacing (20px) would leak in otherwise.\\n *\\\/\\nfunction ahs_row( array $settings, array $children ): array {\\n\\treturn array(\\n\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t'elType'   => 'container',\\n\\t\\t'settings' => array_merge(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'content_width' => 'full',\\n\\t\\t\\t\\t'padding'       => array(\\n\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t'top'      => '0',\\n\\t\\t\\t\\t\\t'right'    => '0',\\n\\t\\t\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t\\t\\t'left'     => '0',\\n\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'flex_gap'      => ahs_zero_gap(),\\n\\t\\t\\t),\\n\\t\\t\\t$settings\\n\\t\\t),\\n\\t\\t'elements' => $children,\\n\\t);\\n}\\n\\n\\\/** Ghost numeral: huge, faint, right side, vertically centered. *\\\/\\nfunction ahs_ghost( string $index ): array {\\n\\treturn ahs_display_heading(\\n\\t\\t$index,\\n\\t\\t'p',\\n\\t\\t'42vh',\\n\\t\\tarray(\\n\\t\\t\\t'title_color'                  => 'rgba(255,255,255,0.035)',\\n\\t\\t\\t'typography_font_weight'       => '700',\\n\\t\\t\\t'typography_font_size_mobile'  => array(\\n\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t'size' => '22vh',\\n\\t\\t\\t),\\n\\t\\t\\t'typography_line_height'       => array(\\n\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t'size' => '1',\\n\\t\\t\\t),\\n\\t\\t\\t'_position'                    => 'absolute',\\n\\t\\t\\t'_offset_orientation_h'        => 'end',\\n\\t\\t\\t'_offset_x_end'                => array(\\n\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t'size'  => 24,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'_offset_orientation_v'        => 'start',\\n\\t\\t\\t'_offset_y'                    => array(\\n\\t\\t\\t\\t'unit'  => '%',\\n\\t\\t\\t\\t'size'  => 50,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'_transform_translate_popover' => 'transform',\\n\\t\\t\\t'_transform_translateY_effect' => array(\\n\\t\\t\\t\\t'unit'  => '%',\\n\\t\\t\\t\\t'size'  => -50,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t)\\n\\t);\\n}\\n\\n\\\/** Meta row: mono index left, mono label right. *\\\/\\nfunction ahs_meta_row( string $index, string $label ): array {\\n\\treturn ahs_row(\\n\\t\\tarray(\\n\\t\\t\\t'flex_direction'       => 'row',\\n\\t\\t\\t'flex_justify_content' => 'space-between',\\n\\t\\t\\t'flex_align_items'     => 'center',\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\tahs_mono_label( $index, array( '_element_width' => 'auto' ) ),\\n\\t\\t\\tahs_mono_label( $label, array( '_element_width' => 'auto' ) ),\\n\\t\\t)\\n\\t);\\n}\\n\\n\\\/** Body group: display name + blurb, pinned to the panel bottom. *\\\/\\nfunction ahs_body_group( string $name, string $blurb ): array {\\n\\treturn ahs_row(\\n\\t\\tarray(\\n\\t\\t\\t'flex_direction' => 'column',\\n\\t\\t\\t'flex_gap'       => ahs_gap( 16 ),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\tahs_display_heading( $name, 'h2', 'clamp(44px, 5.4vw, 104px)', array_merge( ahs_anim( 1 ), AHS_TITLE_CAP ) ),\\n\\t\\t\\tahs_body_text( $blurb, array_merge( ahs_anim( 2 ), AHS_SUBTITLE_CAP ) ),\\n\\t\\t)\\n\\t);\\n}\\n\\n\\\/** Common panel container settings. *\\\/\\nfunction ahs_panel_settings( string $title, int $width_vw, string $bg, array $extra = array() ): array {\\n\\treturn array_merge(\\n\\t\\tarray(\\n\\t\\t\\t'_title'                => $title,\\n\\t\\t\\t'content_width'         => 'full',\\n\\t\\t\\t'width'                 => array(\\n\\t\\t\\t\\t'unit'  => 'vw',\\n\\t\\t\\t\\t'size'  => $width_vw,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t\\\/\\\/ Core's 100% width default is mobile-only; without this,\\n\\t\\t\\t\\\/\\\/ tablet-width touch stacking leaves ragged right edges. vw, not %:\\n\\t\\t\\t\\\/\\\/ percentages resolve against the max-content track in the\\n\\t\\t\\t\\\/\\\/ horizontal state and blow the panels up.\\n\\t\\t\\t'width_tablet'          => array(\\n\\t\\t\\t\\t'unit'  => 'vw',\\n\\t\\t\\t\\t'size'  => 100,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'flex_direction'        => 'column',\\n\\t\\t\\t'flex_justify_content'  => 'space-between',\\n\\t\\t\\t'flex_gap'              => ahs_zero_gap(),\\n\\t\\t\\t'min_height_mobile'     => array(\\n\\t\\t\\t\\t'unit'  => 'vh',\\n\\t\\t\\t\\t'size'  => 72,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'padding'               => AHS_PADDING,\\n\\t\\t\\t'padding_mobile'        => AHS_PADDING_MOBILE,\\n\\t\\t\\t'background_background' => 'classic',\\n\\t\\t\\t'background_color'      => $bg,\\n\\t\\t\\t'border_border'         => 'solid',\\n\\t\\t\\t'border_width'          => array(\\n\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t'top'      => '0',\\n\\t\\t\\t\\t'right'    => '1',\\n\\t\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t\\t'left'     => '0',\\n\\t\\t\\t\\t'isLinked' => false,\\n\\t\\t\\t),\\n\\t\\t\\t'border_color'          => AHS_HAIRLINE,\\n\\t\\t),\\n\\t\\t$extra\\n\\t);\\n}\\n\\nfunction ahs_panel( array $settings, array $children ): array {\\n\\treturn array(\\n\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t'elType'   => 'container',\\n\\t\\t'isLocked' => true,\\n\\t\\t'settings' => $settings,\\n\\t\\t'elements' => $children,\\n\\t);\\n}\\n\\n\\\/\\\/ --- Fixed header -------------------------------------------------------------\\n\\n$header = array(\\n\\t'id'       => ahs_seed_id(),\\n\\t'elType'   => 'container',\\n\\t'isInner'  => false,\\n\\t'settings' => array(\\n\\t\\t'_title'                => 'Header',\\n\\t\\t'content_width'         => 'full',\\n\\t\\t'position'              => 'fixed',\\n\\t\\t'_offset_orientation_v' => 'start',\\n\\t\\t\\\/\\\/ Clears the WP admin bar when present; 0 otherwise. The plugin's own\\n\\t\\t\\\/\\\/ --arts-hs-admin-bar is scoped to the widget wrapper and can't reach\\n\\t\\t\\\/\\\/ this sibling, so the header reads WP's raw var (cosmetic side\\n\\t\\t\\\/\\\/ effects: 32px editor-preview offset; 600-767px logged-in overlap).\\n\\t\\t'_offset_y'             => array(\\n\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t'size' => 'var(--wp-admin--admin-bar--height, 0px)',\\n\\t\\t),\\n\\t\\t\\\/\\\/ WP's bar unpins below 600px \\u2014 don't reserve room for it on phones.\\n\\t\\t'_offset_y_mobile'      => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 0,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'_offset_orientation_h' => 'start',\\n\\t\\t'_offset_x'             => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 0,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'z_index'               => 100,\\n\\t\\t'flex_direction'        => 'row',\\n\\t\\t'flex_justify_content'  => 'space-between',\\n\\t\\t'flex_align_items'      => 'center',\\n\\t\\t'flex_gap'              => ahs_zero_gap(),\\n\\t\\t'min_height'            => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 56,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'min_height_mobile'     => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 48,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'padding'               => array(\\n\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t'top'      => '0',\\n\\t\\t\\t'right'    => '44',\\n\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t'left'     => '44',\\n\\t\\t\\t'isLinked' => false,\\n\\t\\t),\\n\\t\\t'padding_mobile'        => array(\\n\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t'top'      => '0',\\n\\t\\t\\t'right'    => '20',\\n\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t'left'     => '20',\\n\\t\\t\\t'isLinked' => false,\\n\\t\\t),\\n\\t\\t'background_background' => 'classic',\\n\\t\\t'background_color'      => '#0A0A0B',\\n\\t\\t'border_border'         => 'solid',\\n\\t\\t'border_width'          => array(\\n\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t'top'      => '0',\\n\\t\\t\\t'right'    => '0',\\n\\t\\t\\t'bottom'   => '1',\\n\\t\\t\\t'left'     => '0',\\n\\t\\t\\t'isLinked' => false,\\n\\t\\t),\\n\\t\\t'border_color'          => AHS_HAIRLINE,\\n\\t),\\n\\t'elements' => array(\\n\\t\\tahs_mono_label(\\n\\t\\t\\t'Arts Horizontal Scroll',\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'title_color'    => AHS_TEXT,\\n\\t\\t\\t\\t'_element_width' => 'auto',\\n\\t\\t\\t)\\n\\t\\t),\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'width'            => array(\\n\\t\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t\\t'size' => 'auto',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'flex_direction'   => 'row',\\n\\t\\t\\t\\t'flex_align_items' => 'center',\\n\\t\\t\\t\\t'flex_gap'         => ahs_gap( 28 ),\\n\\t\\t\\t\\t'flex_gap_mobile'  => ahs_gap( 16 ),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_mono_label(\\n\\t\\t\\t\\t\\t'Start',\\n\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t'link'              => array( 'url' => '#start', 'is_external' => '', 'nofollow' => '' ),\\n\\t\\t\\t\\t\\t\\t'title_hover_color' => AHS_TEXT,\\n\\t\\t\\t\\t\\t\\t'_element_width'    => 'auto',\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\tahs_mono_label(\\n\\t\\t\\t\\t\\t'Features',\\n\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t'link'              => array( 'url' => '#features', 'is_external' => '', 'nofollow' => '' ),\\n\\t\\t\\t\\t\\t\\t'title_hover_color' => AHS_TEXT,\\n\\t\\t\\t\\t\\t\\t'_element_width'    => 'auto',\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\tahs_mono_label(\\n\\t\\t\\t\\t\\t'Install',\\n\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t'link'              => array( 'url' => '#install', 'is_external' => '', 'nofollow' => '' ),\\n\\t\\t\\t\\t\\t\\t'title_hover_color' => AHS_TEXT,\\n\\t\\t\\t\\t\\t\\t'_element_width'    => 'auto',\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t),\\n);\\n\\n\\\/\\\/ --- Lane panels --------------------------------------------------------------\\n\\n$hero = ahs_panel(\\n\\tahs_panel_settings(\\n\\t\\t'Hero',\\n\\t\\t100,\\n\\t\\t'#0A0A0B',\\n\\t\\tarray( '_element_id' => 'start' )\\n\\t),\\n\\tarray(\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'flex_direction'       => 'row',\\n\\t\\t\\t\\t'flex_justify_content' => 'flex-end',\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_mono_label( 'Free plugin \\u00b7 wordpress.org', array( '_element_width' => 'auto' ) ),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'flex_direction' => 'column',\\n\\t\\t\\t\\t'flex_gap'       => ahs_gap( 40 ),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_display_heading(\\n\\t\\t\\t\\t\\t'Arts Horizontal<br>Scroll <span style=\\\"color:#9A9AA0\\\">for&nbsp;Elementor<\\\/span>',\\n\\t\\t\\t\\t\\t'h1',\\n\\t\\t\\t\\t\\t'clamp(52px, 8.6vw, 150px)',\\n\\t\\t\\t\\t\\tahs_anim( 1 )\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\tahs_row(\\n\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t'flex_direction'       => 'row',\\n\\t\\t\\t\\t\\t\\t'flex_justify_content' => 'space-between',\\n\\t\\t\\t\\t\\t\\t'flex_align_items'     => 'flex-end',\\n\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\tahs_body_text(\\n\\t\\t\\t\\t\\t\\t\\t\\\"Pin a section and the page's own scroll moves it sideways. You're inside it right now.\\\",\\n\\t\\t\\t\\t\\t\\t\\tarray_merge(\\n\\t\\t\\t\\t\\t\\t\\t\\tahs_anim( 2 ),\\n\\t\\t\\t\\t\\t\\t\\t\\tAHS_SUBTITLE_CAP,\\n\\t\\t\\t\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t'typography_font_size' => array(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'size'  => 17,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\tahs_mono_label( 'Scroll \\u2192', array_merge( ahs_anim( 3 ), array( '_element_width' => 'auto' ) ) ),\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t)\\n);\\n\\n$panel_containers = ahs_panel(\\n\\tahs_panel_settings(\\n\\t\\t'01 \\u2014 Containers',\\n\\t\\t85,\\n\\t\\t'#0E0E10',\\n\\t\\tarray( '_element_id' => 'features' )\\n\\t),\\n\\tarray(\\n\\t\\tahs_meta_row( '01', 'Any content' ),\\n\\t\\tahs_ghost( '01' ),\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'flex_direction'   => 'column',\\n\\t\\t\\t\\t'flex_align_items' => 'flex-start',\\n\\t\\t\\t\\t'flex_gap'         => ahs_gap( 14 ),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_pill_button( 'A real button', '#', ahs_anim( 1 ) ),\\n\\t\\t\\t\\tahs_body_text( '\\u2713 Headings, buttons, forms, images', array_merge( ahs_anim( 2 ), array( 'typography_font_size' => array( 'unit' => 'px', 'size' => 15, 'sizes' => array() ) ) ) ),\\n\\t\\t\\t\\tahs_body_text( '\\u2713 Nested layouts work', array_merge( ahs_anim( 3 ), array( 'typography_font_size' => array( 'unit' => 'px', 'size' => 15, 'sizes' => array() ) ) ) ),\\n\\t\\t\\t\\tahs_body_text( '\\u2713 Styled with the usual controls', array_merge( ahs_anim( 4 ), array( 'typography_font_size' => array( 'unit' => 'px', 'size' => 15, 'sizes' => array() ) ) ) ),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t\\tahs_body_group(\\n\\t\\t\\t'Real Containers',\\n\\t\\t\\t'Every panel is a normal Elementor Container. Drop in whatever widgets you use, nest layouts if you want. Nothing new to learn.'\\n\\t\\t),\\n\\t)\\n);\\n\\n$grid_cells = array();\\nfor ( $i = 1; $i <= 6; $i++ ) {\\n\\t$grid_cells[] = array(\\n\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t'elType'   => 'container',\\n\\t\\t'settings' => array(\\n\\t\\t\\t'content_width'         => 'full',\\n\\t\\t\\t'animation'             => 'fadeIn',\\n\\t\\t\\t'animation_delay'       => 80 + ( $i - 1 ) * 100,\\n\\t\\t\\t'min_height'            => array(\\n\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t'size'  => 96,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'flex_direction'        => 'row',\\n\\t\\t\\t'flex_justify_content'  => 'center',\\n\\t\\t\\t'flex_align_items'      => 'center',\\n\\t\\t\\t'flex_gap'              => ahs_zero_gap(),\\n\\t\\t\\t'padding'               => array(\\n\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t'top'      => '0',\\n\\t\\t\\t\\t'right'    => '0',\\n\\t\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t\\t'left'     => '0',\\n\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t),\\n\\t\\t\\t'background_background' => 'classic',\\n\\t\\t\\t'background_color'      => 'rgba(255,255,255,0.02)',\\n\\t\\t\\t'border_border'         => 'solid',\\n\\t\\t\\t'border_width'          => array(\\n\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t'top'      => '1',\\n\\t\\t\\t\\t'right'    => '1',\\n\\t\\t\\t\\t'bottom'   => '1',\\n\\t\\t\\t\\t'left'     => '1',\\n\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t),\\n\\t\\t\\t'border_color'          => 'rgba(255,255,255,0.1)',\\n\\t\\t),\\n\\t\\t'elements' => array(\\n\\t\\t\\tahs_mono_label( (string) $i, array( '_element_width' => 'auto' ) ),\\n\\t\\t),\\n\\t);\\n}\\n\\n$panel_grid = ahs_panel(\\n\\tahs_panel_settings( '02 \\u2014 Grid', 65, '#101013' ),\\n\\tarray(\\n\\t\\tahs_meta_row( '02', 'Grid' ),\\n\\t\\tahs_ghost( '02' ),\\n\\t\\tarray(\\n\\t\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t\\t'elType'   => 'container',\\n\\t\\t\\t'settings' => array(\\n\\t\\t\\t\\t'container_type'    => 'grid',\\n\\t\\t\\t\\t'content_width'     => 'full',\\n\\t\\t\\t\\t'width'             => array(\\n\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t'size'  => 560,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'width_mobile'      => array(\\n\\t\\t\\t\\t\\t'unit'  => '%',\\n\\t\\t\\t\\t\\t'size'  => 100,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'grid_columns_grid' => array(\\n\\t\\t\\t\\t\\t'unit' => 'fr',\\n\\t\\t\\t\\t\\t'size' => 3,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'grid_columns_grid_mobile' => array(\\n\\t\\t\\t\\t\\t'unit' => 'fr',\\n\\t\\t\\t\\t\\t'size' => 2,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'grid_rows_grid'    => array(\\n\\t\\t\\t\\t\\t'unit' => 'fr',\\n\\t\\t\\t\\t\\t'size' => 2,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'grid_gaps'         => array(\\n\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t'column'   => '12',\\n\\t\\t\\t\\t\\t'row'      => '12',\\n\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'padding'           => array(\\n\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t'top'      => '0',\\n\\t\\t\\t\\t\\t'right'    => '0',\\n\\t\\t\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t\\t\\t'left'     => '0',\\n\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t'elements' => $grid_cells,\\n\\t\\t),\\n\\t\\tahs_body_group(\\n\\t\\t\\t'Grids work in here',\\n\\t\\t\\t\\\"This is Elementor's Grid container, living inside a panel. Flex or Grid, containers behave the same in the track as anywhere else.\\\"\\n\\t\\t),\\n\\t)\\n);\\n\\n$panel_widths = ahs_panel(\\n\\tahs_panel_settings( '03 \\u2014 Widths', 50, '#0E0E10' ),\\n\\tarray(\\n\\t\\tahs_meta_row( '03', 'Layout' ),\\n\\t\\tahs_ghost( '03' ),\\n\\t\\tahs_body_group(\\n\\t\\t\\t'This panel is 50vw',\\n\\t\\t\\t'The grid before was 65. A panel is whatever width you give it, and the track adds them up.'\\n\\t\\t),\\n\\t)\\n);\\n\\nfunction ahs_pro_layer( string $width, string $height, string $left, string $top, string $bg, int $speed, int $slot ): array {\\n\\treturn array(\\n\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t'elType'   => 'container',\\n\\t\\t'settings' => array(\\n\\t\\t\\t'content_width'         => 'full',\\n\\t\\t\\t'position'              => 'absolute',\\n\\t\\t\\t'_offset_orientation_h' => 'start',\\n\\t\\t\\t'_offset_x'             => array(\\n\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t'size' => $left,\\n\\t\\t\\t),\\n\\t\\t\\t'_offset_orientation_v' => 'start',\\n\\t\\t\\t'_offset_y'             => array(\\n\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t'size' => $top,\\n\\t\\t\\t),\\n\\t\\t\\t'width'                 => array(\\n\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t'size' => $width,\\n\\t\\t\\t),\\n\\t\\t\\t'min_height'            => array(\\n\\t\\t\\t\\t'unit' => 'custom',\\n\\t\\t\\t\\t'size' => $height,\\n\\t\\t\\t),\\n\\t\\t\\t'animation'             => 'fadeIn',\\n\\t\\t\\t'animation_delay'       => 80 + ( $slot - 1 ) * 100,\\n\\t\\t\\t'background_background' => 'classic',\\n\\t\\t\\t'background_color'      => $bg,\\n\\t\\t\\t'border_border'         => 'solid',\\n\\t\\t\\t'border_width'          => array(\\n\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t'top'      => '1',\\n\\t\\t\\t\\t'right'    => '1',\\n\\t\\t\\t\\t'bottom'   => '1',\\n\\t\\t\\t\\t'left'     => '1',\\n\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t),\\n\\t\\t\\t'border_color'          => 'rgba(255,255,255,0.1)',\\n\\t\\t\\t\\\/\\\/ Elementor Pro Motion FX \\u2014 inert without Pro.\\n\\t\\t\\t'motion_fx_motion_fx_scrolling'      => 'yes',\\n\\t\\t\\t'motion_fx_translateX_effect'        => 'yes',\\n\\t\\t\\t'motion_fx_translateX_speed'         => array(\\n\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t'size'  => $speed,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'motion_fx_translateX_affectedRange' => array(\\n\\t\\t\\t\\t'unit'  => '%',\\n\\t\\t\\t\\t'size'  => '',\\n\\t\\t\\t\\t'sizes' => array(\\n\\t\\t\\t\\t\\t'start' => 0,\\n\\t\\t\\t\\t\\t'end'   => 100,\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'elements' => array(),\\n\\t);\\n}\\n\\n$panel_pro = ahs_panel(\\n\\tahs_panel_settings( '04 \\u2014 With Elementor Pro', 75, '#101013' ),\\n\\tarray(\\n\\t\\tahs_meta_row( '04', 'With Elementor Pro' ),\\n\\t\\tahs_ghost( '04' ),\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'min_height' => array(\\n\\t\\t\\t\\t\\t'unit'  => 'vh',\\n\\t\\t\\t\\t\\t'size'  => 30,\\n\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_pro_layer( '44%', '72%', '0%', '14%', 'rgba(255,255,255,0.03)', 2, 1 ),\\n\\t\\t\\t\\tahs_pro_layer( '34%', '52%', '30%', '0%', 'rgba(255,255,255,0.05)', 4, 2 ),\\n\\t\\t\\t\\tahs_pro_layer( '28%', '44%', '58%', '36%', 'rgba(255,255,255,0.08)', 6, 3 ),\\n\\t\\t\\t\\tahs_mono_label(\\n\\t\\t\\t\\t\\t'Motion FX \\u00b7 parallax layers',\\n\\t\\t\\t\\t\\tarray_merge(\\n\\t\\t\\t\\t\\t\\tahs_anim( 4 ),\\n\\t\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t\\t'_position'             => 'absolute',\\n\\t\\t\\t\\t\\t\\t\\t'_offset_orientation_h' => 'end',\\n\\t\\t\\t\\t\\t\\t\\t'_offset_x_end'         => array(\\n\\t\\t\\t\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t\\t\\t\\t'size'  => 0,\\n\\t\\t\\t\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t\\t'_offset_orientation_v' => 'end',\\n\\t\\t\\t\\t\\t\\t\\t'_offset_y_end'         => array(\\n\\t\\t\\t\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t\\t\\t\\t'size'  => 0,\\n\\t\\t\\t\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t\\tahs_body_group(\\n\\t\\t\\t'Motion FX keeps moving',\\n\\t\\t\\t'Have Elementor Pro? Scrolling Effects keep working in here. Element and background parallax follow the sideways motion instead of freezing.'\\n\\t\\t),\\n\\t)\\n);\\n\\n$phone_bars = array();\\nfor ( $i = 0; $i < 3; $i++ ) {\\n\\t$phone_bars[] = array(\\n\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t'elType'   => 'container',\\n\\t\\t'settings' => array(\\n\\t\\t\\t'content_width'         => 'full',\\n\\t\\t\\t'min_height'            => array(\\n\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t'size'  => 80,\\n\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t),\\n\\t\\t\\t'padding'               => array(\\n\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t'top'      => '0',\\n\\t\\t\\t\\t'right'    => '0',\\n\\t\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t\\t'left'     => '0',\\n\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t),\\n\\t\\t\\t'background_background' => 'classic',\\n\\t\\t\\t'background_color'      => 'rgba(255,255,255,0.03)',\\n\\t\\t\\t'border_border'         => 'solid',\\n\\t\\t\\t'border_width'          => array(\\n\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t'top'      => '1',\\n\\t\\t\\t\\t'right'    => '1',\\n\\t\\t\\t\\t'bottom'   => '1',\\n\\t\\t\\t\\t'left'     => '1',\\n\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t),\\n\\t\\t\\t'border_color'          => AHS_HAIRLINE,\\n\\t\\t),\\n\\t\\t'elements' => array(),\\n\\t);\\n}\\n\\n$panel_touch = ahs_panel(\\n\\tahs_panel_settings( '05 \\u2014 Touch screens', 60, '#0E0E10' ),\\n\\tarray(\\n\\t\\tahs_meta_row( '05', 'Touch screens' ),\\n\\t\\tahs_ghost( '05' ),\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'flex_direction'   => 'row',\\n\\t\\t\\t\\t'flex_align_items' => 'flex-end',\\n\\t\\t\\t\\t'flex_gap'         => ahs_gap( 20 ),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'id'       => ahs_seed_id(),\\n\\t\\t\\t\\t\\t'elType'   => 'container',\\n\\t\\t\\t\\t\\t'settings' => array(\\n\\t\\t\\t\\t\\t\\t'content_width'  => 'full',\\n\\t\\t\\t\\t\\t\\t'width'          => array(\\n\\t\\t\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t\\t\\t'size'  => 150,\\n\\t\\t\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t'animation'       => 'fadeIn',\\n\\t\\t\\t\\t\\t\\t'animation_delay' => 80,\\n\\t\\t\\t\\t\\t\\t'min_height'     => array(\\n\\t\\t\\t\\t\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t\\t\\t\\t\\t'size'  => 280,\\n\\t\\t\\t\\t\\t\\t\\t'sizes' => array(),\\n\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t'flex_direction' => 'column',\\n\\t\\t\\t\\t\\t\\t'flex_gap'       => ahs_gap( 8 ),\\n\\t\\t\\t\\t\\t\\t'padding'        => array(\\n\\t\\t\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t\\t\\t'top'      => '10',\\n\\t\\t\\t\\t\\t\\t\\t'right'    => '10',\\n\\t\\t\\t\\t\\t\\t\\t'bottom'   => '10',\\n\\t\\t\\t\\t\\t\\t\\t'left'     => '10',\\n\\t\\t\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t'border_border'  => 'solid',\\n\\t\\t\\t\\t\\t\\t'border_width'   => array(\\n\\t\\t\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t\\t\\t'top'      => '1',\\n\\t\\t\\t\\t\\t\\t\\t'right'    => '1',\\n\\t\\t\\t\\t\\t\\t\\t'bottom'   => '1',\\n\\t\\t\\t\\t\\t\\t\\t'left'     => '1',\\n\\t\\t\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t\\t'border_color'   => 'rgba(255,255,255,0.15)',\\n\\t\\t\\t\\t\\t\\t'border_radius'  => array(\\n\\t\\t\\t\\t\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t\\t\\t\\t\\t'top'      => '18',\\n\\t\\t\\t\\t\\t\\t\\t'right'    => '18',\\n\\t\\t\\t\\t\\t\\t\\t'bottom'   => '18',\\n\\t\\t\\t\\t\\t\\t\\t'left'     => '18',\\n\\t\\t\\t\\t\\t\\t\\t'isLinked' => true,\\n\\t\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\t'elements' => $phone_bars,\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\tahs_mono_label( 'Stack on touch \\u00b7 on by default', array_merge( ahs_anim( 2 ), array( '_element_width' => 'auto' ) ) ),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t\\tahs_body_group(\\n\\t\\t\\t'Phones get a column',\\n\\t\\t\\t\\\"Open this page on a phone: the panels stack into a normal vertical page, because fingers scroll down. It's a default, not a rule. One switch keeps the section horizontal on touch screens too, if your design needs that.\\\"\\n\\t\\t),\\n\\t)\\n);\\n\\n$endcap = ahs_panel(\\n\\tarray_merge(\\n\\t\\tahs_panel_settings(\\n\\t\\t\\t'06 \\u2014 Install',\\n\\t\\t\\t40,\\n\\t\\t\\t'#15151A',\\n\\t\\t\\tarray( '_element_id' => 'install' )\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'flex_justify_content' => 'center',\\n\\t\\t\\t'flex_align_items'     => 'flex-start',\\n\\t\\t\\t'flex_gap'             => ahs_gap( 20 ),\\n\\t\\t)\\n\\t),\\n\\tarray(\\n\\t\\tahs_display_heading( 'Add it to your WordPress web site', 'h2', 'clamp(28px, 3vw, 48px)', array_merge( ahs_anim( 2 ), AHS_TITLE_CAP ) ),\\n\\t\\tahs_pill_button(\\n\\t\\t\\t'Install Plugin',\\n\\t\\t\\t'https:\\\/\\\/wordpress.org\\\/plugins\\\/horizontal-scroll-for-elementor\\\/',\\n\\t\\t\\tarray_merge( ahs_anim( 3 ), array( '_element_width' => 'auto' ) )\\n\\t\\t),\\n\\t)\\n);\\n\\n$panel_children = array( $hero, $panel_containers, $panel_grid, $panel_widths, $panel_pro, $panel_touch, $endcap );\\n\\n$widget = array(\\n\\t'id'         => ahs_seed_id(),\\n\\t'elType'     => 'widget',\\n\\t'widgetType' => 'arts-horizontal-scroll',\\n\\t'settings'   => array(\\n\\t\\t\\\/\\\/ Row count MUST equal child-container count \\u2014 linkage is positional.\\n\\t\\t'panels'           => array_map(\\n\\t\\t\\tstatic function ( array $panel ): array {\\n\\t\\t\\t\\treturn array(\\n\\t\\t\\t\\t\\t'_id'         => ahs_seed_id(),\\n\\t\\t\\t\\t\\t'panel_title' => $panel['settings']['_title'],\\n\\t\\t\\t\\t);\\n\\t\\t\\t},\\n\\t\\t\\t$panel_children\\n\\t\\t),\\n\\t\\t'layout'           => 'horizontal',\\n\\t\\t'layout_mobile'    => 'vertical',\\n\\t\\t'touch_vertical'   => 'yes',\\n\\t\\t'panels_gap'       => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 0,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'viewport_height'  => array(\\n\\t\\t\\t'unit'  => 'vh',\\n\\t\\t\\t'size'  => 100,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'pin_offset'       => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 56,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'pin_offset_mobile' => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 48,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'scroll_direction' => 'ltr',\\n\\t\\t'scroll_factor'    => array(\\n\\t\\t\\t'unit'  => 'px',\\n\\t\\t\\t'size'  => 1.2,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t),\\n\\t'elements'   => $panel_children,\\n);\\n\\n$widget_wrap = array(\\n\\t'id'       => ahs_seed_id(),\\n\\t'elType'   => 'container',\\n\\t'isInner'  => false,\\n\\t'settings' => array(\\n\\t\\t'_title'         => 'Demo Lane',\\n\\t\\t'content_width'  => 'full',\\n\\t\\t'padding'        => array(\\n\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t'top'      => '56',\\n\\t\\t\\t'right'    => '0',\\n\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t'left'     => '0',\\n\\t\\t\\t'isLinked' => false,\\n\\t\\t),\\n\\t\\t'padding_mobile' => array(\\n\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t'top'      => '48',\\n\\t\\t\\t'right'    => '0',\\n\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t'left'     => '0',\\n\\t\\t\\t'isLinked' => false,\\n\\t\\t),\\n\\t\\t'flex_gap'       => ahs_zero_gap(),\\n\\t),\\n\\t'elements' => array( $widget ),\\n);\\n\\n\\\/\\\/ --- Outro --------------------------------------------------------------------\\n\\n$outro = array(\\n\\t'id'       => ahs_seed_id(),\\n\\t'elType'   => 'container',\\n\\t'isInner'  => false,\\n\\t'settings' => array(\\n\\t\\t'_title'               => 'Outro',\\n\\t\\t'content_width'        => 'full',\\n\\t\\t'min_height'           => array(\\n\\t\\t\\t'unit'  => 'vh',\\n\\t\\t\\t'size'  => 64,\\n\\t\\t\\t'sizes' => array(),\\n\\t\\t),\\n\\t\\t'flex_direction'       => 'column',\\n\\t\\t'flex_justify_content' => 'space-between',\\n\\t\\t'flex_gap'             => ahs_gap( 48 ),\\n\\t\\t'padding'              => AHS_PADDING,\\n\\t\\t'padding_mobile'       => AHS_PADDING_MOBILE,\\n\\t\\t'border_border'        => 'solid',\\n\\t\\t'border_width'         => array(\\n\\t\\t\\t'unit'     => 'px',\\n\\t\\t\\t'top'      => '1',\\n\\t\\t\\t'right'    => '0',\\n\\t\\t\\t'bottom'   => '0',\\n\\t\\t\\t'left'     => '0',\\n\\t\\t\\t'isLinked' => false,\\n\\t\\t),\\n\\t\\t'border_color'         => AHS_HAIRLINE,\\n\\t),\\n\\t'elements' => array(\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'flex_direction' => 'column',\\n\\t\\t\\t\\t'flex_gap'       => ahs_gap( 20 ),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_mono_label( \\\"That's the whole tour\\\", ahs_anim( 1 ) ),\\n\\t\\t\\t\\tahs_display_heading( 'Now build yours', 'h2', 'clamp(28px, 4.6vw, 88px)', array_merge( ahs_anim( 2 ), AHS_TITLE_CAP ) ),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t\\tahs_row(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'flex_direction'       => 'row',\\n\\t\\t\\t\\t'flex_justify_content' => 'space-between',\\n\\t\\t\\t\\t'flex_align_items'     => 'center',\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tahs_mono_label( '\\u00a9 2026 Artem Semkin', array( '_element_width' => 'auto' ) ),\\n\\t\\t\\t)\\n\\t\\t),\\n\\t),\\n);\\n\\n\\\/\\\/ --- Persist ------------------------------------------------------------------\\n\\n$slug     = 'ahs-demo';\\n$existing = get_page_by_path( $slug );\\n\\n$post_id = $existing ? $existing->ID : wp_insert_post(\\n\\tarray(\\n\\t\\t'import_id'   => AHS_DEMO_PAGE_ID,\\n\\t\\t'post_type'   => 'page',\\n\\t\\t'post_status' => 'publish',\\n\\t\\t'post_title'  => 'Arts Horizontal Scroll \\u2014 Demo',\\n\\t\\t'post_name'   => $slug,\\n\\t),\\n\\ttrue\\n);\\n\\nif ( is_wp_error( $post_id ) ) {\\n\\tif ( defined( 'WP_CLI' ) && WP_CLI ) {\\n\\t\\tWP_CLI::error( $post_id->get_error_message() );\\n\\t}\\n\\treturn;\\n}\\n\\n$elements = array( $header, $widget_wrap, $outro );\\n\\n$page_settings = array(\\n\\t'template'              => 'elementor_canvas',\\n\\t'hide_title'            => 'yes',\\n\\t'background_background' => 'classic',\\n\\t'background_color'      => '#0A0A0B',\\n);\\n\\n\\\/\\\/ Mirrors Document::save()'s sequence (elementor\\\/core\\\/base\\\/document.php).\\nupdate_post_meta( $post_id, '_elementor_page_settings', wp_slash( $page_settings ) );\\nupdate_post_meta( $post_id, '_elementor_data', wp_slash( wp_json_encode( $elements, JSON_UNESCAPED_UNICODE ) ) );\\nupdate_post_meta( $post_id, '_elementor_edit_mode', 'builder' );\\nupdate_post_meta( $post_id, '_elementor_template_type', 'wp-page' );\\nupdate_post_meta( $post_id, '_wp_page_template', 'elementor_canvas' );\\nupdate_post_meta( $post_id, '_elementor_version', ELEMENTOR_VERSION );\\n\\n\\\/\\\/ Post CSS never diffs (is_update_required() is hard-coded false) \\u2014 delete to regen.\\n\\\\Elementor\\\\Core\\\\Files\\\\CSS\\\\Post::create( $post_id )->delete();\\ndelete_post_meta( $post_id, '_elementor_element_cache' );\\n\\n\\\/\\\/ The editor prefers newer autosave revisions over raw meta \\u2014 remove them all.\\nforeach ( wp_get_post_revisions( $post_id, array( 'fields' => 'ids' ) ) as $revision_id ) {\\n\\twp_delete_post_revision( $revision_id );\\n}\\n\\n\\\/\\\/ Retire the superseded portfolio draft (design pivot 2026-07-18).\\n$obsolete = get_page_by_path( 'atelier-mono' );\\nif ( $obsolete && 'trash' !== $obsolete->post_status ) {\\n\\twp_trash_post( $obsolete->ID );\\n\\tif ( defined( 'WP_CLI' ) && WP_CLI ) {\\n\\t\\tWP_CLI::log( sprintf( 'Trashed superseded page %d (atelier-mono).', $obsolete->ID ) );\\n\\t}\\n}\\n\\nif ( defined( 'WP_CLI' ) && WP_CLI ) {\\n\\tWP_CLI::success( sprintf( 'Demo page seeded: post_id=%d %s', $post_id, get_permalink( $post_id ) ) );\\n}\\n\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; require '\\\/wordpress\\\/wp-content\\\/horizontal-scroll-for-elementor-demo-seed.php';\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"horizontal-scroll-for-elementor\"},\"options\":{\"activate\":true}}]}"}},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.0.2","1.0.3","1.1.0","1.2.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3655720,"resolution":"1","location":"assets","locale":"","width":1520,"height":1520},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3655720,"resolution":"2","location":"assets","locale":"","width":1520,"height":1520},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3655720,"resolution":"3","location":"assets","locale":"","width":1520,"height":1520},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3655720,"resolution":"4","location":"assets","locale":"","width":1520,"height":1520}},"screenshots":{"1":"The Horizontal Scroll widget in Elementor's Layout category, next to Container and Grid.","2":"Panels are real Elementor Containers \u2013 add or remove them in the widget, design them in the canvas.","3":"Layout: stack panels vertically on touch devices or at any breakpoint, and set the gap between them.","4":"Scroll: pinned section height, direction, how much page scroll the section consumes, and a pin offset for sticky headers."}},"plugin_section":[],"plugin_tags":[76538,133096,71952,250933,160076],"plugin_category":[],"plugin_contributors":[241532],"plugin_business_model":[],"class_list":["post-342931","plugin","type-plugin","status-publish","hentry","plugin_tags-elementor","plugin_tags-horizontal-scroll","plugin_tags-scroll-animation","plugin_tags-scroll-effects","plugin_tags-sticky-section","plugin_contributors-artemsemkin","plugin_committers-artemsemkin"],"banners":{"banner":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/banner-772x250.png?rev=3614622","banner_2x":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/banner-1544x500.png?rev=3614622","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/icon.svg?rev=3614622","icon":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/icon.svg?rev=3614622","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/screenshot-1.png?rev=3655720","caption":"The Horizontal Scroll widget in Elementor's Layout category, next to Container and Grid."},{"src":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/screenshot-2.png?rev=3655720","caption":"Panels are real Elementor Containers \u2013 add or remove them in the widget, design them in the canvas."},{"src":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/screenshot-3.png?rev=3655720","caption":"Layout: stack panels vertically on touch devices or at any breakpoint, and set the gap between them."},{"src":"https:\/\/ps.w.org\/horizontal-scroll-for-elementor\/assets\/screenshot-4.png?rev=3655720","caption":"Scroll: pinned section height, direction, how much page scroll the section consumes, and a pin offset for sticky headers."}],"raw_content":"<!--section=description-->\n<p>One widget that adds a pinned horizontal scroll section to Elementor: the section holds still while its panels travel sideways as the page scrolls. Panels are free-form content \u2013 real Elementor Containers, on the same nested-elements foundation as Elementor's own Mega Menu \u2013 so you design them right in the canvas, like any other layout. And there's no Pro version: this is the whole thing.<\/p>\n\n<h4>Free-form panels<\/h4>\n\n<p>Most ways to get horizontal scrolling in Elementor make you author the content somewhere else: a saved template picked from a dropdown, a section elsewhere on the page wired up by CSS ID, or a repeater with fixed image-and-text fields. Here a panel is a real Container. Drop widgets into it, nest layouts inside it, style it directly in the editor, next to the rest of your page. The pin runs live in the canvas too: scroll the editor and the section scrubs exactly like the frontend.<\/p>\n\n<h4>How it behaves on phones and tablets<\/h4>\n\n<p>On phones and tablets the section becomes a vertical stack by default: panels flow as normal full-width blocks, nothing to swipe against. You can keep horizontal scrolling on touch if you want it, and the responsive Layout control switches any breakpoint to the vertical stack \u2013 using your site's own Elementor breakpoints, not a hardcoded list. If a visitor's browser can't run the effect at all, it shows the same designed vertical layout \u2013 content is never trapped.<\/p>\n\n<h4>Part of the page, not the whole page<\/h4>\n\n<p>The widget is a normal section in your page's vertical flow, not a whole-page takeover. Open the page with one, drop another between regular sections, use several on the same page \u2013 each pins and scrubs independently, and the page scrolls vertically as usual before, between, and after. You choose how much page scroll each section consumes, and the reveal can run right-to-left. Mixed vertical and horizontal scrolling, wherever it fits your layout.<\/p>\n\n<h4>Works with Elementor Pro's effects and one-page menus<\/h4>\n\n<p>Elementor Pro's Scrolling Effects keep working inside the section \u2013 element and background effects follow each panel's ride across the stage instead of freezing while the section is pinned. One-page navigation works too: anchor links and shared URLs scroll to the exact panel, and with Elementor Pro's menu widget the highlighted menu item follows the panel on stage. Entrance animations, lazy-loaded media, and visibility-triggered widgets fire as their panel comes into view, and Pro's page Scroll Snap keeps working around the section.<\/p>\n\n<h4>RTL and multilingual sites<\/h4>\n\n<p>On a right-to-left page the section mirrors itself \u2013 panels lay out right-to-left and the ride runs the other way, with the first panel still shown first. Nothing to configure, and either direction can be forced per section. WPML, Polylang, TranslatePress, and Weglot need no setup either: panels translate like the rest of the page, and every language keeps its own scroll direction.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin. The free Elementor plugin is the only requirement.<\/li>\n<li>IMPORTANT: Activate \"Nested Elements\" under Elementor \u2192 Settings \u2192 Features.<\/li>\n<li>Edit a page with Elementor.<\/li>\n<li>Find the \"Horizontal Scroll\" widget under Layout in the widget panel and drop it on the page.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20it%20really%20free%3F\"><h3>Is it really free?<\/h3><\/dt>\n<dd><p>Yes. There is no Pro version and nothing in the widget is locked \u2013 what you install is the whole product. If it earns its keep, there's a donate link.<\/p><\/dd>\n<dt id=\"does%20it%20require%20elementor%20pro%3F\"><h3>Does it require Elementor Pro?<\/h3><\/dt>\n<dd><p>No. The free Elementor plugin is the only requirement, and the horizontal scroll behaves identically with or without Pro \u2013 nothing about the effect is gated behind it.<\/p>\n\n<p>Pro is supported alongside it rather than required by it. Its Scrolling Effects and one-page menu highlighting keep working inside the section; page Scroll Snap keeps working around it, since the section takes itself out of the snap sequence instead of fighting the pin. The questions further down cover exactly how.<\/p><\/dd>\n<dt id=\"how%20is%20this%20different%20from%20elementor%20pro%27s%20horizontal%20scroll%20effect%3F\"><h3>How is this different from Elementor Pro's Horizontal Scroll effect?<\/h3><\/dt>\n<dd><p>Pro's Horizontal Scroll is a motion effect, not a section. It slides one element sideways as the page scrolls past it, and the total distance it can travel is the Speed value times 100 pixels \u2013 so even at the maximum Speed of 10, the element moves 1000px in all. A four-panel full-width track needs several times that. The effect also never pins anything: the page keeps scrolling normally while the element slides, and the motion eases toward its target on a one-second transition rather than tracking the scroll position exactly.<\/p>\n\n<p>Which is why the tutorials for building a real horizontal section don't use it. They give each panel 100vw, make the container holding them sticky inside an over-tall wrapper, and paste in a JavaScript snippet that measures the track and maps scroll onto it \u2013 and you re-tune that whenever the content changes. This widget is the same arrangement as a real element: panels are Containers you add and remove, the travel is measured from the actual track width so it stays correct as the content changes, and Pro's own effects keep working on elements inside the panels.<\/p><\/dd>\n<dt id=\"will%20it%20slow%20down%20my%20site%3F\"><h3>Will it slow down my site?<\/h3><\/dt>\n<dd><p>No. The browser itself moves the panels \u2013 the plugin doesn't run animation code on every scroll step and doesn't load a heavy animation library. Its whole frontend footprint is a few kilobytes of CSS and JavaScript. Browsers that don't support the underlying CSS feature yet \u2013 Firefox today, older Safari \u2013 load a small polyfill on demand; everywhere else the motion is pure CSS.<\/p><\/dd>\n<dt id=\"what%20happens%20on%20phones%20and%20tablets%3F\"><h3>What happens on phones and tablets?<\/h3><\/dt>\n<dd><p>By default the section switches to a vertical stack on touch devices \u2013 panels become normal full-width blocks in the page flow. You can turn that off to keep the horizontal scroll, or force the vertical layout below any breakpoint with the responsive Layout control.<\/p><\/dd>\n<dt id=\"can%20i%20put%20any%20widget%20inside%20a%20panel%3F\"><h3>Can I put any widget inside a panel?<\/h3><\/dt>\n<dd><p>Yes \u2013 panels are real Elementor Containers, Flexbox or Grid alike. Anything you can build in a Container works, including nested layouts.<\/p><\/dd>\n<dt id=\"the%20scroll%20feels%20too%20fast%20%E2%80%93%20what%20do%20i%20change%3F\"><h3>The scroll feels too fast \u2013 what do I change?<\/h3><\/dt>\n<dd><p>Scroll Length. It sets how much page scroll the section consumes, so raising it stretches the same journey over more scrolling. Height is a different thing: it's the pinned viewport the panels fill, not the distance they travel. Adding panels doesn't speed anything up either \u2013 the section simply gets taller, and each panel still takes the same amount of scroll to cross.<\/p><\/dd>\n<dt id=\"i%20have%20a%20sticky%20header%20%E2%80%93%20will%20it%20get%20in%20the%20way%3F\"><h3>I have a sticky header \u2013 will it get in the way?<\/h3><\/dt>\n<dd><p>No. The pin offset control sets where the section sticks, so it pins below your header instead of sliding behind it. The WordPress admin bar is accounted for automatically.<\/p><\/dd>\n<dt id=\"can%20i%20mix%20horizontal%20and%20vertical%20scrolling%20on%20the%20same%20page%3F\"><h3>Can I mix horizontal and vertical scrolling on the same page?<\/h3><\/dt>\n<dd><p>Yes \u2013 that's the default way to use it. The widget is a regular section in the page flow: place it anywhere between normal vertical content, and the page scrolls as usual before and after it. Several sections on one page work too; each runs independently.<\/p><\/dd>\n<dt id=\"is%20this%20scroll%20hijacking%3F\"><h3>Is this scroll hijacking?<\/h3><\/dt>\n<dd><p>No. The plugin never intercepts wheel, touch, or keyboard input. The page scrolls exactly as it always did; the section maps a stretch of that scroll to horizontal movement.<\/p><\/dd>\n<dt id=\"will%20it%20conflict%20with%20my%20theme%20or%20other%20plugins%3F\"><h3>Will it conflict with my theme or other plugins?<\/h3><\/dt>\n<dd><p>It's built to stay out of the way. It doesn't bundle an animation library that could collide with your theme's scripts. Scroll snap is neutralized on the section itself, so Elementor Pro's Scroll Snap keeps working on the rest of the page. Smooth-scrolling libraries like Lenis are picked up automatically \u2013 the engine reads the native scroll position, which is exactly what they animate.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20right-to-left%20and%20multilingual%20sites%3F\"><h3>Does it work on right-to-left and multilingual sites?<\/h3><\/dt>\n<dd><p>Yes. On an RTL page the section mirrors on its own \u2013 panels lay out right-to-left and the first panel is still the one on stage \u2013 and the Direction control forces either direction when you don't want that. WPML, Polylang, TranslatePress, and Weglot all work without setup: panels are real Elementor Containers with no widget text to register, so they translate like the rest of the page. If translated RTL text doesn't mirror the section, the language's pack is missing \u2013 install it or set Direction to Right to Left.<\/p><\/dd>\n<dt id=\"which%20elementor%20effects%20work%20on%20widgets%20inside%20the%20panels%3F\"><h3>Which Elementor effects work on widgets inside the panels?<\/h3><\/dt>\n<dd><p>Effects that fire on becoming visible work as-is: entrance animations, lazy-loaded images and backgrounds, video autoplay-on-visible, counters and progress bars all trigger as their panel scrolls into view. Elementor Pro's Scrolling Effects \u2013 on elements and on backgrounds \u2013 are corrected automatically: instead of freezing while the section is pinned, they follow the element's ride across the stage, from entering on one side to leaving on the other. Effects set to \"Entire Page\" read the page's own scroll, as always. Pro Sticky and Position: Fixed still don't apply inside the panels \u2013 a moving track can't hold a fixed element.<\/p><\/dd>\n<dt id=\"can%20i%20put%20motion%20effects%20or%20an%20entrance%20animation%20on%20the%20widget%20itself%3F\"><h3>Can I put Motion Effects or an entrance animation on the widget itself?<\/h3><\/dt>\n<dd><p>An entrance animation works fine \u2013 the section fades or slides in, then pins and scrubs as usual. Elementor Pro's Scrolling and Mouse Effects on the widget itself also run, but they move the whole pinned scene as one block \u2013 usually you want them on elements inside the panels instead, where they follow the horizontal ride. Two settings do break the pin: Pro's Sticky, and Position set to absolute or fixed. The section visibly stops working the moment either is applied, and switching it back off restores everything.<\/p><\/dd>\n<dt id=\"do%20anchor%20links%20work%20with%20the%20section%3F\"><h3>Do anchor links work with the section?<\/h3><\/dt>\n<dd><p>Yes. Link to any element inside a panel \u2013 the panel's own container or anything nested in it \u2013 with a normal CSS ID, and the page scrolls to the position where that panel is on stage: on click, and when the page loads with the link already in the URL. Where the pinned scroll isn't running (touch stacking, a vertical Layout breakpoint, a browser without support), anchors scroll normally instead \u2013 nothing to configure.<\/p><\/dd>\n<dt id=\"do%20one-page%20menus%20highlight%20the%20current%20panel%3F\"><h3>Do one-page menus highlight the current panel?<\/h3><\/dt>\n<dd><p>With Elementor Pro's menu widget, yes. Point menu items at panels \u2013 or anything inside them \u2013 with normal <code>#<\/code> links: clicking scrolls to that panel on stage, and while the section scrubs, exactly one menu item stays highlighted: the one whose panel is in view. Elementor Pro on its own toggles items independently and often lights two at once; inside the section the plugin arbitrates that down to a single, correct highlight. Your vertical anchors before and after the section behave as usual.<\/p><\/dd>\n<dt id=\"can%20my%20own%20animations%20follow%20the%20horizontal%20scroll%3F\"><h3>Can my own animations follow the horizontal scroll?<\/h3><\/dt>\n<dd><p>Yes. The section publishes a small stable surface: a named CSS scroll timeline, state variables to gate on, per-panel range variables, and a JavaScript timeline API that works the same whether the browser is native or polyfilled. Your own scroll-driven animations can ride the same scroll as the track \u2013 the README in the GitHub repository documents the full contract.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>improved: the pinned section now lives inside Elementor's standard widget wrapper instead of replacing it \u2013 themes and add-ons that expect regular widget markup see it.<\/li>\n<li>fixed: the Advanced tab works again \u2013 margin, padding, background, border, shadow, and transform apply to the section on sites where Elementor's Optimized Markup experiment is off.<\/li>\n<li>fixed: pages saved with earlier versions refresh on their own \u2013 the plugin clears Elementor's CSS and element cache once after updating, no \"Regenerate CSS &amp; Data\" needed.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>added: an Auto option for the Direction control, now the default \u2013 the section follows the page's language direction, so right-to-left sites mirror automatically.<\/li>\n<li>improved: the plugin page now covers right-to-left and multilingual support \u2013 WPML, Polylang, TranslatePress, and Weglot work without setup.<\/li>\n<li>fixed: right-to-left pages no longer pin a blank section \u2013 panels lay out and travel the correct way.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>improved: documentation only \u2013 the plugin page now covers what works without Elementor Pro, how the widget differs from Pro's Horizontal Scroll motion effect, and which control sets the scroll pacing.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>improved: the widget now sits in Elementor's Layout category, next to Container and Grid.<\/li>\n<li>improved: a clearer widget icon in the Elementor panel.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>improved: confirmed compatibility with WordPress 7.1.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<p>Initial release.<\/p>","raw_excerpt":"Pinned horizontal scroll sections for Elementor. Panels are real Containers you design inline \u2013 no templates or shortcodes. CSS-driven, responsive.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/342931","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=342931"}],"author":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/artemsemkin"}],"wp:attachment":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=342931"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=342931"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=342931"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=342931"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=342931"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=342931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}