From 3241a281b1f854dd848156cd9ca54de0e607f08c Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 10 Nov 2025 21:05:17 +0000
Subject: [PATCH] =Update

---
 forms/partner.php         |  104 ++++
 taxonomies/person.php     |   24 +
 temp.php                  |    2 
 forms/_setup.php          |   30 +
 forms/contact.php         |   60 ++
 taxonomies/theme.php      |    2 
 taxonomies/_setup.php     |    4 
 email/_setup.php          |  289 +++++++++++++
 login/_setup.php          |   40 +
 content/faq.php           |  119 +++++
 taxonomies/section.php    |   29 +
 forms/get-an-estimate.php |   92 ++++
 content/progress.php      |  115 ++++
 forms/nlp.php             |  123 +++++
 alegacy.php               |  118 +++++
 dashboard/_setup.php      |   82 +++
 content/terms.php         |   44 +
 users/client.php          |   20 
 18 files changed, 1,251 insertions(+), 46 deletions(-)

diff --git a/alegacy.php b/alegacy.php
index cc46d58..557f2ee 100644
--- a/alegacy.php
+++ b/alegacy.php
@@ -54,11 +54,12 @@
 define('AJV_URL', plugin_dir_url(__FILE__));
 
 require(AJV_DIR . '/content/_setup.php');
-//require(AJV_DIR . '/dashboard/_setup.php');
-//require(AJV_DIR . '/forms/_setup.php');
+require(AJV_DIR . '/dashboard/_setup.php');
+require(AJV_DIR . '/email/_setup.php');
+require(AJV_DIR . '/forms/_setup.php');
 require(AJV_DIR . '/login/_setup.php');
 require(AJV_DIR . '/taxonomies/_setup.php');
-//require(AJV_DIR . '/users/_setup.php');
+require(AJV_DIR . '/users/_setup.php');
 //require(AJV_DIR . '/files/fileManagement.php');
 
 
@@ -87,6 +88,8 @@
         'has_membership'      => false,
         'has_map'             => true,
         'dashboard'           => true,
+        'referrals'           => true,
+        'magicLink'           => true,
         'support'         => false,
         'feed_block'      => true,
         'email_notifications' => false,
@@ -97,6 +100,7 @@
             'maps'        => true,
             'gmb'         => true,
             'helcim'      => false,
+            'postmark'    => true,
             'instagram'   => true,
             'square'      => false,
             'umami'       => true,
@@ -140,3 +144,111 @@
 //{
 //    return [];
 //}
+
+
+add_filter('jvbAboveHeader', 'altr_legacy_header');
+function altr_legacy_header(string $header):string
+{
+    return '<p><b>WED - SUN</b> <span class="hide-small">&emsp;</span>10<span class="hide-small">:00</span>AM - 6<span class="hide-small">:00</span>PM</p><p>By Appointment<span class="hide-small"> Only</span></p>';
+}
+
+
+
+add_filter('jvbMenuExtra', 'altr_contact_nav', 10, 3);
+function altr_contact_nav(string $nav, string $menuName, array $block):string
+{
+    if (array_key_exists('attrs', $block)
+        && array_key_exists('className', $block['attrs'])
+        && $block['attrs']['className'] === 'is-style-fixed'
+        && $nav === '') {
+        $call = '<li class="call"><a href="'.jvbPhoneLink(8259257398).'" title="Call Us">'.jvbIcon('phone').'<span class="screen-reader-text">Call Us</span></a></li>';
+        $text = '<li><a href="'.jvbTextLink(8259257398).'" title="Text Us">'.jvbIcon('chat').'<span class="hide-small">825.925.7398</span><sup class="hide-small">PEWU</sup></a></li>';
+        $email = '<li><a href="'.jvbMailToLink(
+            'info@legacytattooremoval.ca',
+                'Contact from Our Website'
+            ).'" title="Email Us">'.jvbIcon('envelope').'<span class="hide-small">info@legacytattooremoval.ca</span></a></li>';
+
+        return $call.$text.$email;
+    }
+    if (array_key_exists('attrs', $block)
+        && array_key_exists('className', $block['attrs'])
+        && $block['attrs']['className'] === 'is-style-floating'
+    ) {
+        return $nav.'<li><ul class="socials">
+            <li>
+                <a href="https://www.facebook.com/LegacyTattooRemoval/" target="_blank" rel="nofollow" title="Find us on Facebook">
+                    '.jvbIcon('facebook-logo').'
+                    <span class="screen-reader-text">
+                        Find us on Facebook
+                    </span>
+                </a>
+            </li>
+            <li>
+                <a href="https://www.instagram.com/LegacyTattooRemoval/" target="_blank" rel="nofollow" title="Find us on Instagram">
+                    '.jvbIcon('instagram-logo').'
+                    <span class="screen-reader-text">
+                        Find us on Instagram
+                    </span>
+                </a>
+            </li>
+            <li>
+                <a href="https://bsky.app/profile/legacyrebrand.test" target="_blank" rel="nofollow" title="Find us on Bluesky">
+                    '.jvbIcon('butterfly').'
+                    <span class="screen-reader-text">
+                        Find us on Bluesky
+                    </span>
+                </a>
+            </li>
+        </ul></li>';
+    }
+
+    return $nav;
+}
+
+add_filter('jvbBeforeFooter', 'alyns_acknowledgement');
+function alyns_acknowledgement():string
+{
+
+    return '<p>amiskwacîwâskahikan ᐊᒥᐢᑲᐧᒋᐋᐧᐢᑲᐦᐃᑲᐣ</p><p><a href="https://www.treatysix.org/#comp-lkljqlw1" title="Learn More">Treaty 6 territory</a></p><p>Edmonton, Alberta, Canada</p>';
+}
+
+
+add_action('jvbBlockStyles', 'altr_blockStyles');
+function altr_blockStyles()
+{
+    register_block_style(
+        'core/list',
+        [
+            'name'=>'blocky',
+            'label' => __('Blocky', 'altr')
+        ]
+    );
+    register_block_style(
+        'core/group',
+        [
+            'name'=>'triangle',
+            'label' => __('Triangle', 'altr')
+        ]
+    );
+}
+
+
+
+function altr_render_core_post_excerpt(array $block, string $content)
+{
+
+    global $post;
+    if (!has_excerpt($post)) {
+        return '';
+    }
+    $excerpt = $post->post_excerpt;
+
+    $before = is_singular() ? '<span class="tldr" title="Too Long, Didn\'t Read">TLDR:</span>' : '';
+    $excerpt = $before.$excerpt;
+    return '<div class="excerpt">'.apply_filters('the_content', $excerpt).'</div>';
+}
+
+add_action( 'init', 'altr_add_excerpts_to_pages' );
+function altr_add_excerpts_to_pages() {
+    add_post_type_support( 'page', 'excerpt' );
+}
\ No newline at end of file
diff --git a/content/faq.php b/content/faq.php
index 645ed34..505b842 100644
--- a/content/faq.php
+++ b/content/faq.php
@@ -1,14 +1,16 @@
 <?php
-// /content/art.php
+// /content/faq.php
 function altr_faq():array
 {
     return [
         'singular'       => 'Frequently Asked Question',
         'plural'       => 'Frequently Asked Questions',
         'dash_description' => 'Manage your answers',
+        'capability_type' => ['faq', 'faqs'],
         'breadcrumb'    => 'FAQ',
-        'hide_single'  => true,
+        'dash_title'    => 'FAQs',
         'icon'         => 'question',
+        'rewrite_taxonomy' => 'section',
         'rewrite'      => [
             'slug'       => 'faq',
             'with_front' => false,
@@ -18,7 +20,18 @@
                 'type'  => 'text',
                 'label' => 'Question',
             ],
-            'answer'        => [
+            'post_status'         => [
+                'type'      => 'radio',
+                'label'     => 'Status',
+                'hidden'    => true,
+                'options'   => [
+                    'publish'   => 'Show',
+                    'draft'     => 'Hide',
+                    'trash'     => 'Scrap',
+                    'delete'    => 'Permanently Delete'
+                ]
+            ],
+            'post_content'        => [
                 'type'  => 'textarea',
                 'label' => 'Answer',
                 'quill' => true,
@@ -28,3 +41,103 @@
         'upload_title' => 'Upload Before & Afters',
     ];
 }
+
+
+add_action('wp_enqueue_scripts', 'nebDashScripts', 9999);
+function nebDashScripts() {
+    global $wp;
+    $page = str_replace('dash/', '', $wp->request);
+    if ($page === 'settings') {
+        wp_enqueue_script('jvb-form');
+        wp_enqueue_script('jvb-tabs');
+        wp_enqueue_script('jvb-populate-form');
+        wp_enqueue_script('jvb-copy-hours');
+        wp_enqueue_script('jvb-quill');
+        wp_enqueue_script('jvb-store');
+        $script = 'function loadSettingsPage() {
+            let tabs = new window.jvbTabs(document.querySelector(".replace"));
+						let store = new window.jvbStore({
+							name: "options",
+							endpoint: "options",
+							headers: {
+				                "action_nonce": jvbSettings.dash,
+                            }
+						});
+						
+						let form = new window.jvbForm(store);
+						let forms = [ "#hours", "#menu-sections"];
+						let setForms = {};
+						forms.forEach(f => {
+						    let gotF = document.querySelector(`form${f}`);
+						    setForms[f] = form.registerForm(gotF);
+						    
+						});						
+						
+						form.subscribe((event, data) => {
+                            switch (event) {
+                                case "form-submit":
+                                case "form-autosave":
+                                    window.jvbQueue.addToQueue({
+                                        endpoint: "options",
+                                        headers: {
+                                            "action_nonce": jvbSettings.dash,
+                                        },
+                                        data: data.changes,
+                                        popup: `Saving options...`,
+                                        title: "Saving Options"
+                                    });
+                                    break;
+                            }
+                        });
+					}
+					document.addEventListener("DOMContentLoaded", ()=>{
+                       loadSettingsPage()
+                    });
+					';
+        $output = wp_add_inline_script('jvb-form', $script, 'after');
+    } elseif ($page === 'dash') {
+        wp_enqueue_script('jvb-form');
+        wp_enqueue_script('jvb-store');
+        $script = 'function loadDashPage() {
+            
+                let store = new window.jvbStore({
+                    name: "options",
+                    endpoint: "options",
+                    headers: {
+                        "action_nonce": jvbSettings.dash,
+                    }
+                });
+                
+                let form = new window.jvbForm(store);
+                let forms = [ "#options"];
+                let setForms = {};
+                forms.forEach(f => {
+                    let gotF = document.querySelector(`form${f}`);
+                    setForms[f] = form.registerForm(gotF);
+                    
+                });						
+                
+                form.subscribe((event, data) => {
+                    switch (event) {
+                        case "form-submit":
+                        case "form-autosave":
+                            window.jvbQueue.addToQueue({
+                                endpoint: "options",
+                                headers: {
+                                    "action_nonce": jvbSettings.dash,
+                                },
+                                data: data.changes,
+                                popup: `Saving options...`,
+                                title: "Saving Options"
+                            });
+                            break;
+                    }
+                });
+            }
+            document.addEventListener("DOMContentLoaded", ()=>{
+               loadDashPage()
+            });
+            ';
+//        $output = wp_add_inline_script('jvb-form', $script, 'after');
+    }
+}
\ No newline at end of file
diff --git a/content/progress.php b/content/progress.php
index e06ef9b..0900884 100644
--- a/content/progress.php
+++ b/content/progress.php
@@ -1,46 +1,129 @@
 <?php
-// /content/art.php
+// /content/progress.php
 function altr_progress():array
 {
     return [
         'singular'       => 'Before & After',
         'plural'       => 'Before & Afters',
-        'dash_title'    => 'Before & Afters',
+        'dash_title'    => 'Progress',
         'dash_description' => 'Manage your before and after posts',
         'breadcrumb'    => 'Before & Afters',
-        'hide_single'  => false,
+        'capability_type' => ['progress', 'progress'],
+        'hide_children' => true,
+        'is_timeline'   => true,
         'show_feed'    => true,
-        'favouritable' => false,
-        'karma'        => false,
+        'hierarchical'  => true,
         'icon'         => 'arrows-left-right',
         'rewrite'      => [
             'slug'       => 'before-and-after',
             'with_front' => false,
         ],
+        'sections'  => [
+            'progression'   => [
+                'label' => 'Progression',
+            ]
+        ],
         'fields'       => [
             'post_title'     => [
                 'type'  => 'text',
                 'label' => 'Title',
+                'quickEdit' => true,
+                'section'   => 'progression',
+                'for_all'   => true,
             ],
-            'featured_image' => [
-                'type'  => 'image',
-                'label' => 'Image',
+            'post_status'         => [
+                'type'      => 'radio',
+                'label'     => 'Status',
+                'hidden'    => true,
+                'options'   => [
+                    'publish'   => 'Show',
+                    'draft'     => 'Hide',
+                    'trash'     => 'Scrap',
+                    'delete'    => 'Permanently Delete'
+                ],
+                'section'   => 'progression',
+                'for_all'   => true,
             ],
-            'gallery'        => [
-                'type'  => 'gallery',
-                'label' => 'Gallery',
+            'post_thumbnail'                => [
+                'type'      => 'image',
+                'label'     => 'Image',
+                'quickEdit' => true,
+                'section'   => 'progression',
+                'for_all'   => true,
             ],
-            'price'          => [
-                'type'  => 'number',
-                'label' => 'Price',
+            'person' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'person',
+                'autocomplete' => true,
+                'label' => 'Person',
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression',
+                'hint'      => 'Not public, just to make it easier to find'
+            ],
+            'goal' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'goal',
+                'autocomplete' => true,
+                'label' => 'Goal',
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression'
+            ],
+            'timeline' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'timeline',
+                'autocomplete' => true,
+                'label' => 'Timeline',
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression',
+                'for_all'   => true,
+            ],
+            'body-part' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'body-part',
+                'label' => 'Body Part',
+                'autocomplete' => true,
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression'
+            ],
+            'style' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'style',
+                'autocomplete' => true,
+                'label' => 'Tattoo Style',
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression'
+            ],
+            'skin-type' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'skin-type',
+                'label' => 'Skin Type',
+                'autocomplete' => true,
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression'
+            ],
+            'age' => [
+                'type'  => 'taxonomy',
+                'taxonomy'  => 'age',
+                'autocomplete'      => true,
+                'label' => 'Age of Tattoo',
+                'quickEdit' => true,
+                'createNew' => true,
+                'section'   => 'progression'
             ],
             'post_content'   => [
                 'type'  => 'textarea',
                 'quill' => true,
-                'label' => 'Notes'
+                'label' => 'Notes',
+                'section'   => 'progression',
+                'for_all'   => true,
             ]
         ],
-        'single_image' => false,
         'upload_title' => 'Upload Before & Afters',
     ];
 }
diff --git a/content/terms.php b/content/terms.php
index 10e0e0f..7507ccf 100644
--- a/content/terms.php
+++ b/content/terms.php
@@ -1,17 +1,18 @@
 <?php
-// /content/art.php
+// /content/terms.php
 function altr_terms():array
 {
     return [
         'singular'       => 'Term',
         'plural'       => 'Terms',
-        'dash_title'    => 'Glossary Terms',
+        'dash_title'    => 'Glossary',
         'dash_description' => 'Manage your terms',
         'breadcrumb'    => 'Glossary',
         'hide_single'  => true,
         'icon'         => 'asterisk',
+        'is_gallery'    => true,
         'rewrite'      => [
-            'slug'       => 'glossary-of-terms',
+            'slug'       => 'glossary',
             'with_front' => false,
         ],
         'fields'       => [
@@ -19,13 +20,48 @@
                 'type'  => 'text',
                 'label' => 'Title',
             ],
-            'definition'        => [
+            'post_status'         => [
+                'type'      => 'radio',
+                'label'     => 'Status',
+                'hidden'    => true,
+                'options'   => [
+                    'publish'   => 'Show',
+                    'draft'     => 'Hide',
+                    'trash'     => 'Scrap',
+                    'delete'    => 'Permanently Delete'
+                ]
+            ],
+            'post_slug' => [
+                'type'  => 'text',
+                'label' => 'Slug'
+            ],
+            'post_content'        => [
                 'type'  => 'textarea',
                 'label' => 'Definition',
                 'quill' => true,
             ],
+            'pronunciation' => [
+                'type'  => 'repeater',
+                'label' => 'Pronunciation',
+                'fields' => [
+                    'part'  => [
+                        'type'  => 'text',
+                        'label' => 'Part',
+                    ]
+                ]
+            ],
+            'type'  => [
+                'type'  => 'radio',
+                'label' => 'Type',
+                'options' => [
+                    'adjective',
+                    'noun',
+                    'verb'
+                ]
+            ]
         ],
         'single_image' => false,
         'upload_title' => 'Upload Before & Afters',
     ];
 }
+
diff --git a/dashboard/_setup.php b/dashboard/_setup.php
index b3d9bbc..f0cf3ad 100644
--- a/dashboard/_setup.php
+++ b/dashboard/_setup.php
@@ -1 +1,83 @@
 <?php
+add_filter('jvb_options', function() {
+    return [
+        'fields' => [
+            'today_hours'  => [
+                'type'  => 'group',
+                'label' => 'Hours',
+                'fields' => [
+                    'time_start'    => [
+                        'type'   => 'time',
+                        'label' => 'Open'
+                    ],
+                    'time_end'    => [
+                        'type'   => 'time',
+                        'label' => 'Closed'
+                    ],
+                ]
+            ],
+            'common' => ['hours'],
+            'open_to_public' => [
+                'type'   => 'true_false',
+                'label' => 'Open to Public?'
+            ],
+        ]
+    ];
+});
+
+add_filter('jvbAdminDashboard', 'nebAdminDashboard');
+function nebAdminDashboard(string $content):string
+{
+    $user = wp_get_current_user()->display_name;
+    $meta = new JVBase\meta\MetaManager(null, 'options');
+
+    $fields = ['today_hours', 'open_to_public'];
+    $temp = [];
+    $saved = jvbGetFields('options', 'options');
+    foreach ($fields as $field) {
+        $temp[$field] = $saved[$field];
+
+    }
+    $fields = $temp;
+
+    return $meta->renderForm(
+        'options',
+        [
+            'heading' => 'Hi '.$user.'!',
+            'description'   => 'Do you have availability today?',
+            'submit'    => true,
+            'classes'   => ['col']
+        ],
+        $fields,
+        false,
+        true
+    );
+
+}
+
+
+add_filter('jvbDashboardSettings', 'nebDashboardSettings');
+function nebDashboardSettings(string $content):string
+{
+    $meta = new JVBase\meta\MetaManager(null, 'options');
+    ob_start();
+    $meta->render('render', 'hours');
+    ?>
+
+    <form id="hours" data-save="options" data-form-id="set-hours">
+        <?php
+        $meta->render('form', 'hours',null,false,false);
+        ?>
+    </form>
+    <?php
+
+    $hours = ob_get_clean();
+    $tabs = [
+        'hours' => [
+            'title'         => 'Hours',
+            'description'   => 'If you are open regular hours you can list your hours here. When you log in to set your location, it pulls from this record first. Updates your Google Business Listing automatically.',
+            'content'       => $hours,
+        ],
+    ];
+    return jvbRenderTabs($tabs, true);
+}
\ No newline at end of file
diff --git a/email/_setup.php b/email/_setup.php
new file mode 100644
index 0000000..2e0f02b
--- /dev/null
+++ b/email/_setup.php
@@ -0,0 +1,289 @@
+<?php
+
+$jvbEmail = add_filter('jvb_email', 'altr_email');
+
+function altr_email(array $defaults):array
+{
+    return [
+        'colours'		=> [
+            'action-0'		=> '#ff0080',
+            'action-50'		=> '#ff2492',
+            'action-100'	=> '#ff47a4',
+            'action-200'	=> '#ff6bb5',
+            'secondary-0'	=> '#D69121',
+            'secondary-50'	=> '#ffc421',
+            'secondary-100'	=> '#ffcd44',
+            'secondary-200'	=> '#ffd768',
+            'light'			=> '#efefef',
+            'light-50'		=> '#e2e2e2',
+            'light-100'		=> '#d5d5d5',
+            'light-200'		=> '#c9c9c9',
+            'dark'			=> '#151515',
+            'dark-50'		=> '#222222',
+            'dark-100'		=> '#2e2e2e',
+            'dark-200'		=> '#3b3b3b',
+            'action-contrast'=> '',
+            'secondary-contrast'=> '',
+        ],
+        'content'		=> [
+            'title'				=> get_bloginfo('name'),
+            'subjectPrefix'		=> '['.get_bloginfo('name').']',
+            'signature'			=> '<p>&emsp; —  ♡ the edmonton.ink crew</p>',
+            'footer'	=> [
+                '<p>&copy; ' . date('Y') . ' edmonton.ink — Your tattoo scene on your screen.</p>',
+                '<p><a href="' . get_home_url() . '" class="text-link">edmonton.ink</a></p>'
+            ]
+        ],
+        'types' => [
+            'newUser' => [
+                'subject'       => 'Welcome to Legacy! Finish creating your account.',
+                'showPrefix'    => true,
+            ],
+            'resetPass' => [
+                'subject'   => 'Reset your Password'
+            ],
+            'emailChange'   => [
+                'subject'   => 'Successfully Changed Email'
+            ],
+            'passwordChange'    => [
+                'subject'   => 'Successfully Changed Password',
+            ]
+        ]
+    ];
+}
+/*
+ * EXTEND WITH:
+ *      {string} $message: email content
+*       {WP_User} $user: user
+ * apply_filters
+ * 		jvbNewUserEmail			-> 	New user email content
+ *          add_filter('jvbNewUserEmail', 'customFunction', 10, 2);
+ * 		jvbNewUserAdminEmail	-> 	New User notification for admin
+ *          add_filter('jvbNewUserAdminEmail', 'customFunction', 10, 2);
+ * 		jvbPasswordResetEmail	->	Password Reset Email
+ *          {string} $message: email content
+ *          {string} $key
+ *          {string} $user_login,
+ *          {WP_User} $user_data
+ *          add_filter('jvbPasswordResetEmail', 'customFunction', 10, 4);
+ * 		jvbEmailChangeRequestEmail		->	Request for email change
+ *          {string} $message
+ *          {array} $oldUser
+ *          {array} newUser
+ *          add_filter('jvbEmailChangeRequestEmail', 'customFunction', 10, 3);
+ * 		jvbEmailChangedEmail	->	Notification that email successfully changed
+ *          {string} $message
+ *          {string} $confirm_url
+            add_filter('jvbEmailChangedEmail', 'customFunction', 10, 2);
+ * 		jvbPasswordChangeEmail	->	Request for password change
+ *          {string} $message
+ *          {array} $oldUser
+ *          {array} $newUser
+ *          add_filter('jvbPasswordChangeEmail', 'customFunction', 10, 3);
+ * 		jvbPersonalDataExport	->	Request for User Data
+ *          {string} $message
+ *          {string} $request_type
+ *          {string} $confirmation_url
+ *          {array} $emailData, from the original filter
+ *          add_filter('jvbPersonalDataExport', 'customFunction', 10, 4);
+ * 		jvbPersonalDataExported	->	Notification that data is ready for download
+ *          {string} $message
+ *          {string} $downloadURL
+ *          {string} $expiresAt
+ *          {array} $emailData, from the original filter
+ *          add_filter('jvbPersonalDataExported', 'customFunction', 10, );
+ *
+ */
+
+add_filter('jvbNewUserEmail', 'altr_new_user_email', 10, 2);
+function altr_new_user_email(string $message, WP_User $user):string
+{
+
+    $user_login = $user->user_login;
+
+    // Only create the password key if the user can change their password
+    $key = get_password_reset_key($user);
+    if (!is_wp_error($key)) {
+        $reset_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
+
+        $message = sprintf(
+            '<p>Hey %s!</p>
+            <p>Thanks for signing up for our referral program at Legacy.</p>
+            <p><b>Login with your email: </b> %s</p>
+            <p>To set your password and access your account, click the button below:</p>%s
+            <p>Or copy and paste this link into your browser: %s</p>
+            <p>Or go passwordless, and just sign on with a magic link.</p>
+            <div class="divider"></div>
+            <p>If you didn\'t create this account, just ignore this email and the link will expire.</p>',
+            $user->display_name,
+            $user->user_login,
+            jvbMailButton($reset_url, 'Set Your Password'),
+            jvbEmailLink($reset_url)
+        );
+    }
+    return $message;
+}
+
+
+/*** EDMONTON INK VERSIONS: ***/
+function eink_new_user_email(string $message, WP_User $user):string
+{
+    $user_login = $user->user_login;
+
+    // Only create the password key if the user can change their password
+    $key = get_password_reset_key($user);
+    if (!is_wp_error($key)) {
+        $reset_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
+
+        $message = sprintf('<p>Hey %s!</p>', $user->first_name);
+        $message .= '<p>Thanks for joining Edmonton\'s tattoo scene. Here\'s your login information:</p>';
+        $message .= sprintf('<p><strong>Username:</strong> %s</p>', $user_login);
+        $message .= '<p>To set your password and access your account, click the button below:</p>';
+        $message .= sprintf('<p style="text-align: center;"><a href="%s" class="button">Set Your Password</a></p>', $reset_url);
+        $message .= '<p>Or copy and paste this link into your browser:</p>';
+        $message .= sprintf('<p style="user-select:all;">%s</p>', $reset_url);
+        $message .= '<p>This link will expire in 24 hours, for security reasons.</p>';
+        if (in_array('jvb_artist', array_values($user->roles))) {
+            $message .= '<div class="divider"></div>';
+            $message .= '<h3>NOTE:</h3>
+                    <p>Once you set your password, you\'ll have access to your custom dashboard where you can:</p>
+                    <ul>
+                        <li>Manage your profile information</li>
+                        <li>Upload tattoos/piercings, and artwork</li>
+                    </ul>
+                    <p>Nothing will be published until you\'ve been approved by 3 already approved artists, or the admin.</p>
+                    <p>Admins check every day or three, but, if you are in a rush, you can contact us directly by replying to this email, or texting us at 825-925-9916.</p>';
+        } elseif (in_array('jvb_partner', array_values($user->roles))) {
+            $message .= '<div class="divider"></div>';
+            $message .= '<h3>NOTE:</h3>
+                    <p>Once you set your password, you\'ll have access to your custom dashboard where you can:</p>
+                    <ul>
+                        <li>Manage your profile information</li>
+                        <li>Create offers for enthusiasts or partners or both</li>
+                    </ul>
+                    <p>Nothing will be published until you\'ve been approved by the admin.</p>
+                    <p>Admins check every day or three, but, if you are in a rush, you can contact us directly by replying to this email, or texting us at 825-925-9916.</p>
+                    <p><strong>Note:</strong>Even after approval by admin, your ability to publish depends on your karmic standing by artists. Artists each have a vote they can cast (UP or DOWN) - if your karmic score dips too far in the negative, you account is subject to reconsideration or even a ban.</p>';
+        }
+        $message .= '<div class="divider"></div>';
+
+
+        $message .= '<p>If you didn\'t create this account, please ignore this email and the link will expire.</p>';
+        $message .= sprintf('<p>Ink on, %s</p>', $user->first_name);
+    }
+
+    return $message;
+}
+
+function eink_new_user_admin_email(string $message, WP_User $user):string
+{
+    $message .= sprintf(
+        '<p><strong>Role:</strong> %s</p>',
+        str_replace(BASE, '', array_values($user->roles)[0])
+    );
+    return $message;
+}
+function eink_password_reset_email(string $message, string $user_login, WP_User $user, string $resetUrl):string
+{
+    return sprintf(
+        '<p>Hi bud,</p>
+			<p>We received a request to reset the password for an account associated with this email:</p>
+			<p><strong>Username:</strong> %s</p>
+			<p>If you didn\'t make this request, you can safely ignore this email and nothing will happen to your account.</p>
+			<p>To reset your password, click the button below:</p>
+			%s
+			<p>Or copy and paste this link into your browser:</p>
+			%s
+			<div class="divider"></div>
+			<p>This password reset link is only valid for 24 hours.</p>',
+        $user_login,
+        jvbMailButton($resetUrl,'Reset Password'),
+        jvbEmailLink($resetUrl)
+    );
+}
+
+function eink_email_change_request_email(string $message, array $oldUser, array $newUser)
+{
+    return sprintf(
+        '<p>Hi %s,</p>
+        <p>Ideally you already know this: someone asked to change your email, and here we are.</p>
+        <p><strong>Old Email:</strong> %s</p>
+        <p><strong>New Email:</strong> %s</p>
+        <div class="divider"></div>
+        <p>If this is news to you, or you did not request this - please contact us immediately. You can <a href="sms:+18258239916">text us</a> or reply to this email."></a></p>
+        %s',
+        $newUser['first_name'],
+        $oldUser['user_email'],
+        $newUser['user_email'],
+        jvbMailButton(wp_login_url(), 'Log In To Your Account')
+    );
+}
+
+function eink_email_changed_email(string $message, string $confirmURL):string
+{
+    return sprintf(
+        '<p>Hey human,</p>
+			<p>Seems you want to change the email associated with your account.</p>
+			<p>If you really want this, please confirm this change by clicking the button below:</p>
+			%s
+			<p>Or copy and paste this link into your browser:</p>
+			%s',
+        jvbMailButton($confirmURL, 'Confirm this Email'),
+        jvbEmailLink($confirmURL)
+    );
+}
+
+function eink_password_changed_email(string $message, array $oldUser, array $newUser):string
+{
+    return sprintf(
+        '<p>Hey bud,</p>
+			<p>This is a confirmation email to let you know your password has successfully been changed.</p>
+			<p>Ideally, you\'re expecting this email. You wanted to change your password, and this is to let you know that it\'s definitely updated.</p>
+			<p>If you\'re not expecting this email, and did not change your password - please <strong>contact us immediately</strong></p>
+			<p>You can <a href="sms:+18259257398">text us</a>, or reply to this email.</p>
+			%s',
+        jvbMailButton(wp_login_url(), 'Log In to Your Account')
+    );
+}
+
+function eink_personal_data_export(string $message, string $requestType, string $confirmURL, array $emailData):string
+{
+    switch ($requestType) {
+        case 'export_personal_data':
+            $request_name = 'Export Personal Data';
+            break;
+        case 'remove_personal_data':
+            $request_name = 'Erase Personal Data';
+            break;
+        default:
+            $request_name = 'Data Request';
+    }
+    return sprintf(
+        '<p>Hi privacy enthusiast,</p>
+			<p>You\'re receiving this email because a request has been made to <strong>%s</strong></p>
+			<p>If you\'re the one who made this request, you can confirm it by clicking the button below:</p>
+			%s
+			<p>Or copy and paste this link into your browser:</p>
+			%s',
+        $request_name,
+        jvbMailButton($confirmURL, 'Confirm'),
+        jvbEmailLink($confirmURL)
+    );
+}
+
+function eink_personal_data_exported_email(string $message, string $downloadURL, string $expiresAt, array $emailData):string
+{
+    return sprintf(
+        '<p>Hi again,</p>
+			<p>You\'re receiving this email because you requested an export of your personal data.</p>
+			<p>You can download your personal data by clicking the button below:</p>
+			%s
+			<p>Or you can copy and paste this link into your browser:</p>
+			%s
+			<div class="divider"></div>
+			<p><strong>Important:</strong> For privacy and security, this link will expire at %s.</p>',
+        jvbMailButton($downloadURL, 'Download Your Data'),
+        jvbEmailLink($downloadURL),
+        $expiresAt
+    );
+}
\ No newline at end of file
diff --git a/forms/_setup.php b/forms/_setup.php
index b3d9bbc..bb62db1 100644
--- a/forms/_setup.php
+++ b/forms/_setup.php
@@ -1 +1,31 @@
 <?php
+
+/*************************************************************
+ *
+ *  Filters the forms for the form block
+ *      Must contain an array with:
+ *          'title'         => {string} optional
+ *          'description    => {array} of strings, each entry becoming its own <p></p>
+ *          'submit'        => {string} submit button text
+ *          'success_title' => {string} a custom heading for the success message
+ *          'success_message'=> {array} of strings, each entry becoming its own <p></p>
+ *          'email_subject' => {string} subject for admin's email
+ *          'fields'        => {array} as per MetaManager.php
+ *          'sections'      => {array} optional array of sections, as per MetaManager.php, for a tabbed form
+ *
+ ************************************************************/
+
+require(AJV_DIR . '/forms/get-an-estimate.php');
+require(AJV_DIR . '/forms/nlp.php');
+require(AJV_DIR . '/forms/contact.php');
+require(AJV_DIR . '/forms/partner.php');
+
+add_filter('jvb_register_forms', 'altr_register_forms');
+
+function altr_register_forms($forms) {
+    $forms['get_an_estimate']   = altr_get_an_estimate();
+    $forms['nlp']               = altr_nlp();
+    $forms['contact']           = altr_contact();
+    $forms['partner']           = altr_nlp_partner();
+    return $forms;
+}
\ No newline at end of file
diff --git a/forms/contact.php b/forms/contact.php
new file mode 100644
index 0000000..d636f99
--- /dev/null
+++ b/forms/contact.php
@@ -0,0 +1,60 @@
+<?php
+
+function altr_contact():array
+{
+    return [
+        'title'         => 'Contact',
+        'description'   => [
+            'You can always text, call, or email.',
+            'Or you can fill out this form and we\'ll get back to you as soon as we can.',
+        ],
+        'submit'        => 'Contact',
+        'success_title' => 'Success!',
+        'success_description'   => [
+            'We got it.',
+            'We\'ll get back to you as soon as we can - usually pretty quick (unless it\'s a Monday or a Tuesday)'
+        ],
+        'email_subject' => '[CONTACT]',
+        'fields'        => [
+            'first_name'    => [
+                'type'  => 'text',
+                'label' => 'First Name',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'last_name'     => [
+                'type'  => 'text',
+                'label' => 'Last Name',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'email'         => [
+                'type'  => 'email',
+                'label' => 'Email',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'phone'         => [
+                'type'  => 'tel',
+                'label' => 'Phone',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'contact'       => [
+                'type'  => 'checkbox',
+                'label' => 'Preferred Contact',
+                'options'   => [
+                    'text'      => 'Text',
+                    'email'     => 'Email',
+                    'call'      => 'Call',
+                ],
+                'section'   => 'about_you',
+            ],
+            'message'   => [
+                'type'  => 'textarea',
+                'quill' => true,
+                'label' => 'What do you want to say?'
+            ]
+        ]
+    ];
+}
\ No newline at end of file
diff --git a/forms/get-an-estimate.php b/forms/get-an-estimate.php
new file mode 100644
index 0000000..1a8db32
--- /dev/null
+++ b/forms/get-an-estimate.php
@@ -0,0 +1,92 @@
+<?php
+
+function altr_get_an_estimate():array
+{
+    return [
+        'title'         => 'Get an Estimate',
+        'submit'        => 'Get your estimate',
+        'success_title' => 'Success!',
+        'success_description'   => [
+            'We got it.',
+            'We\'ll get back to you as soon as we can - usually pretty quick (unless it\'s a Monday or a Tuesday)'
+        ],
+        'email_subject' => 'New Estimate Request',
+        'fields'        => [
+            'first_name'    => [
+                'type'  => 'text',
+                'label' => 'First Name',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'last_name'     => [
+                'type'  => 'text',
+                'label' => 'Last Name',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'email'         => [
+                'type'  => 'email',
+                'label' => 'Email',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'phone'         => [
+                'type'  => 'tel',
+                'label' => 'Phone',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'contact'       => [
+                'type'  => 'checkbox',
+                'label' => 'Preferred Contact',
+                'options'   => [
+                    'text'      => 'Text',
+                    'email'     => 'Email',
+                    'call'      => 'Call',
+                ],
+                'section'   => 'about_you',
+            ],
+            'age'   => [
+                'type'      => 'text',
+                'subtype'   => 'number',
+                'label'     => 'How old is your tattoo?',
+                'section'   => 'tattoo',
+            ],
+            'location'  => [
+                'type'      => 'radio',
+                'label'     => 'Location on Body',
+                'options'   => [
+                    'face'      => 'Face',
+                    'neck'      => 'Neck',
+                    'scalp'     => 'Scalp',
+                    'chest'     => 'Chest',
+                    'back'      => 'Back',
+                    'arm'       => 'Arm',
+                    'hand'      => 'Hand',
+                    'finger'    => 'Finger',
+                    'butt'      => 'Butt',
+                    'genitals'  => 'Genitals',
+                    'leg'       => 'Leg',
+                    'foot'      => 'Foot'
+                ],
+                'section'   => 'tattoo',
+            ],
+            'goal'      => [
+                'type'      => 'radio',
+                'label'     => 'Removal Goal',
+                'options'   => [
+                    'cover_up'          => 'Fading for a Cover Up Tattoo',
+                    'complete_removal'  => 'Complete Removal',
+                    'clean_up'          => 'Clean Up',
+                ],
+                'section'   => 'tattoo',
+            ],
+            'photos'        => [
+                'type'  => 'gallery',
+                'label' => 'Photo(s) of Tattoo',
+                'section'   => 'tattoo',
+                'description'   => 'Make sure we can get a sense of scale.'
+            ]
+        ]
+    ];
+}
\ No newline at end of file
diff --git a/forms/nlp.php b/forms/nlp.php
new file mode 100644
index 0000000..5bf3ede
--- /dev/null
+++ b/forms/nlp.php
@@ -0,0 +1,123 @@
+<?php
+
+function altr_nlp():array
+{
+    return [
+        'title'         => 'New Legacy Program',
+//        'description'   => '',
+        'submit'        => 'Apply Now',
+        'success_title' => 'Success!',
+        'success_description'   => [
+            'We got it.',
+            'We\'ll get back to you as soon as we can - usually pretty quick (unless it\'s a Monday or a Tuesday)'
+        ],
+        'email_subject' => '[NLP] Application',
+        'fields'        => [
+            'first_name'    => [
+                'type'  => 'text',
+                'label' => 'First Name',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'last_name'     => [
+                'type'  => 'text',
+                'label' => 'Last Name',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'email'         => [
+                'type'  => 'email',
+                'label' => 'Email',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'phone'         => [
+                'type'  => 'tel',
+                'label' => 'Phone',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'contact'       => [
+                'type'  => 'checkbox',
+                'label' => 'Preferred Contact',
+                'options'   => [
+                    'text'      => 'Text',
+                    'email'     => 'Email',
+                    'call'      => 'Call',
+                ],
+                'section'   => 'about_you',
+            ],
+            'type'   => [
+                'type'      => 'checkbox',
+                'label'     => 'Type of Tattoo',
+                'options'   => [
+                    'gang'  => 'Gang Affiliated',
+                    'hate'  => 'Hateful Symbolism',
+                    'dv'    => 'Domestic Violence',
+                    'trafficking'   => 'Human Trafficking',
+                    'prison'        => 'Prison or Jail',
+                    'other'
+                ],
+                'section'   => 'tattoo',
+            ],
+            'referred'   => [
+                'type'      => 'checkbox',
+                'label'     => 'Referred By',
+                'options'   => [
+                    'po'        => 'Parole Officer',
+                    'sw'  => 'Social Worker',
+                    'cow'    => 'Community Outreach Worker',
+                    'doctor'   => 'Doctor',
+                    'mental_health' => 'Mental Health Worker',
+                    'sponsor' => 'Sponsor',
+                    'other'
+                ],
+                'section'   => 'tattoo',
+            ],
+            'age'   => [
+                'type'      => 'text',
+                'subtype'   => 'number',
+                'label'     => 'How old is your tattoo?',
+                'section'   => 'tattoo',
+            ],
+            'location'  => [
+                'type'      => 'radio',
+                'label'     => 'Location on Body',
+                'options'   => [
+                    'face'      => 'Face',
+                    'neck'      => 'Neck',
+                    'scalp'     => 'Scalp',
+                    'chest'     => 'Chest',
+                    'back'      => 'Back',
+                    'arm'       => 'Arm',
+                    'hand'      => 'Hand',
+                    'finger'    => 'Finger',
+                    'butt'      => 'Butt',
+                    'genitals'  => 'Genitals',
+                    'leg'       => 'Leg',
+                    'foot'      => 'Foot'
+                ],
+                'section'   => 'tattoo',
+            ],
+            'photos'        => [
+                'type'  => 'gallery',
+                'label' => 'Photo(s) of Tattoo',
+                'section'   => 'tattoo',
+                'hint'   => 'Make sure we can get a sense of scale.'
+            ],
+            'docs'        => [
+                'type'  => 'files',
+                'subtype'   => '.doc,.pdf,.txt,.jpg',
+                'label' => 'Letter of Support',
+                'section'   => 'tattoo',
+                'hint'   => 'Please provide a letter written by one of the above mentioned people that referred you who are working alongside you building your New Legacy.'
+            ],
+            'notes' => [
+                'type'  => 'textarea',
+                'label' => 'Anything else to add?',
+                'quill' => true,
+                'section'   => 'tattoo',
+            ]
+        ]
+    ];
+}
\ No newline at end of file
diff --git a/forms/partner.php b/forms/partner.php
new file mode 100644
index 0000000..2e1cd76
--- /dev/null
+++ b/forms/partner.php
@@ -0,0 +1,104 @@
+<?php
+
+function altr_nlp_partner():array
+{
+    return [
+        'title'         => 'Partner with Us',
+//        'description'   => '',
+        'submit'        => 'Submit Form',
+        'success_title' => 'Success!',
+        'success_description'   => [
+            'We got it.',
+            'We\'ll get back to you as soon as we can - usually pretty quick (unless it\'s a Monday or a Tuesday)'
+        ],
+        'email_subject' => '[Partner] Inquiry',
+        'fields'        => [
+            'your_name'     => [
+                'type'  => 'text',
+                'label' => 'Your Name',
+                'required'=> true,
+                'section'   => 'about_you',
+            ],
+            'your_role'     => [
+                'type'  => 'text',
+                'label' => 'Your Role/Title',
+                'required'=> true,
+                'section'   => 'about_you',
+            ],
+            'email'         => [
+                'type'  => 'email',
+                'label' => 'Email',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'phone'         => [
+                'type'  => 'tel',
+                'label' => 'Phone',
+                'required' => true,
+                'section'   => 'about_you',
+            ],
+            'contact'       => [
+                'type'  => 'checkbox',
+                'label' => 'Preferred Contact',
+                'options'   => [
+                    'text'      => 'Text',
+                    'email'     => 'Email',
+                    'call'      => 'Call',
+                ],
+                'section'   => 'about_you',
+            ],
+            'organization_name'    => [
+                'type'  => 'text',
+                'label' => 'Organization Name',
+                'required' => true,
+                'section'   => 'organization',
+            ],
+            'website'     => [
+                'type'  => 'url',
+                'label' => 'Organization Website',
+                'section'   => 'organization',
+            ],
+            'type'   => [
+                'type'      => 'checkbox',
+                'label'     => 'Organization Type',
+                'options'   => [
+                    'po'        => 'Parole Officer',
+                    'sw'  => 'Social Services',
+                    'cow'    => 'Community Outreach',
+                    'doctor'   => 'Healthcare Provider',
+                    'mental_health' => 'Mental Health Services',
+                    'indigenous' => 'Indigenous Services',
+                    'other'
+                ],
+                'section' => 'organization'
+            ],
+            'location'  => [
+                'type'      => 'radio',
+                'label'     => 'Where are your clients located?',
+                'options'   => [
+                    'yeg'      => 'Edmonton Area',
+                    'elsewhere'=> 'Elsewhere in Alberta',
+                    'other'=> 'Other'
+                ],
+                'section'   => 'organization',
+            ],
+            'intent'        => [
+                'type'  => 'radio',
+                'label' => 'Are you',
+                'options'   => [
+                    'individual'    => 'Referring a specific individual right now',
+                    'partner'       => 'Exploring partnership opportunities',
+                    'both'          => 'Both',
+                ],
+                'section'   => 'referrals',
+            ],
+            'notes' => [
+                'type'  => 'textarea',
+                'label' => 'Tell us more',
+                'quill' => true,
+                'section'   => 'referrals',
+                'hint'  => 'What would be most helpful for us to know about your organization and the people you serve?'
+            ]
+        ]
+    ];
+}
\ No newline at end of file
diff --git a/login/_setup.php b/login/_setup.php
index 3cc76a7..a25781f 100644
--- a/login/_setup.php
+++ b/login/_setup.php
@@ -4,15 +4,37 @@
 function altr_setup_login():array
 {
     return [
-        'login_from_favourite_header' => 'Join the scene; <small>keep your collection.</small>',
-        'login_header'                => 'Log in',
-        'join_header'                 => 'Join in',
-        'from_favourites_benefits'    => [
-            'Save designs you love',
-            'Get personalized recommendations',
-            'Connect with artists',
-            'Build your inspiration collection',
-            'Bonus: It\'s all free!'
+        'login' => [
+            'title'        => 'Log in',
+            'description'   => ['Log in to your account to see your referral balance and get your unique code!'],
+            'submit'        => 'Log in',
+        ],
+        'favourites'    => [
+            'title'         => 'Save your favourites'
+        ],
+        'lostpassword' => [
+            'title'    => 'Forgot Your Password?',
+            'description'   => 'No worries, we\'ll send you a reset link to your email.'
+        ],
+        'register'  => [
+            'title'        => 'Create your Account',
+            'submit'        => 'Create Account',
+            'email'     => [
+                'subject'   => '[Legacy] Finish Creating Your Account'
+            ],
+            'success'       => [
+                'title' => 'Success!',
+                'description' => [
+                    'See your email for next steps.',
+                    '(If you can\'t find it, check your junk!)',
+                ],
+            ]
+        ],
+        'magic' => [
+            'title' => 'Log in, auto-magically!',
+            'description' => [
+                'Enter your email, click the link in your email, and bibbity bobbity boo - you\'re logged in!'
+            ],
         ]
     ];
 }
diff --git a/taxonomies/_setup.php b/taxonomies/_setup.php
index 8979a2b..0467d9b 100644
--- a/taxonomies/_setup.php
+++ b/taxonomies/_setup.php
@@ -23,6 +23,8 @@
 require(AJV_DIR . '/taxonomies/age.php');
 require(AJV_DIR . '/taxonomies/body-part.php');
 require(AJV_DIR . '/taxonomies/goal.php');
+require(AJV_DIR . '/taxonomies/person.php');
+require(AJV_DIR . '/taxonomies/section.php');
 require(AJV_DIR . '/taxonomies/skin-type.php');
 require(AJV_DIR . '/taxonomies/style.php');
 require(AJV_DIR . '/taxonomies/theme.php');
@@ -35,9 +37,11 @@
         'age'       => altr_age(),
         'body-part' => altr_body_part(),
         'goal'      => altr_goal(),
+        'person'    => altr_person(),
         'skin-type' => altr_skin_type(),
         'timeline'  => altr_timeline(),
         'style'     => altr_style(),
         'theme'     => altr_theme(),
+        'section'   => altr_section(),
     ];
 }
\ No newline at end of file
diff --git a/taxonomies/person.php b/taxonomies/person.php
new file mode 100644
index 0000000..bb6b8e5
--- /dev/null
+++ b/taxonomies/person.php
@@ -0,0 +1,24 @@
+<?php
+// /taxonomies/target.php
+function altr_person():array
+{
+    return [
+        'singular'     => 'Person',
+        'plural'       => 'People',
+        'icon'         => 'user',
+        'show_feed'    => false,
+        'public'        => false,
+        'show_ui'       => true,
+        'hierarchical' => false,
+        'for_content'  => [
+            'progress',
+        ],
+        'fields'       => [
+            'term_name' => [
+                'label'     => 'Name',
+                'type'      => 'text',
+                'quickEdit' => true,
+            ]
+        ]
+    ];
+}
diff --git a/taxonomies/section.php b/taxonomies/section.php
new file mode 100644
index 0000000..3660bef
--- /dev/null
+++ b/taxonomies/section.php
@@ -0,0 +1,29 @@
+<?php
+// /taxonomies/target.php
+function altr_section():array
+{
+    return [
+        'singular'     => 'Section',
+        'plural'       => 'Sections',
+        'icon'         => 'folder',
+        'show_feed'    => false,
+        'rewrite'      => [
+            'slug'         => 'faq',
+            'with_front'   => false,
+            'hierarchical' => true,
+        ],
+        'hierarchical' => true,
+        'for_content'  => [
+            'faq',
+        ],
+        'fields'       => [
+            'term_name' => [
+                'label'     => 'Name',
+                'type'      => 'text',
+                'subtype'   => 'number',
+                'quickEdit' => true,
+            ],
+            'common'    => [ 'wiki' ]
+        ]
+    ];
+}
diff --git a/taxonomies/theme.php b/taxonomies/theme.php
index 64c6807..408fdad 100644
--- a/taxonomies/theme.php
+++ b/taxonomies/theme.php
@@ -12,7 +12,7 @@
         ],
         'singular'     => 'Theme',
         'plural'       => 'Themes',
-        'icon'         => 'hashtag',
+        'icon'         => 'hash',
         'show_feed'    => true,
         'rewrite'      => [
             'slug'         => 'themes',
diff --git a/temp.php b/temp.php
index 131fbc2..3dbedf8 100644
--- a/temp.php
+++ b/temp.php
@@ -721,7 +721,7 @@
         ],
         'singular' => 'Theme',
         'plural' => 'Themes',
-        'icon' => 'hashtag',
+        'icon' => 'hash',
         'favouritable' => true,
         'show_feed' => true,
         'approve_new' => false,
diff --git a/users/client.php b/users/client.php
index 4fae2d3..8a66db6 100644
--- a/users/client.php
+++ b/users/client.php
@@ -7,15 +7,17 @@
         'has_dashboard'    => true,
         'can_create'       => ['support'],
         'can_register'     => true,
-        'keep_stats'       => true,
-        'join_text'        => 'Save your favourites. Get Notified.',
-        'join_title'       => 'Welcome to the Scene.',
-        'join_description' => [
-            'Save your favourites for easy access',
-            'Get notified when your favourite artists add new content',
-            'Stay in the loop with local flash days and events',
-            'Discover styles and artists that match your vision'
+        'keep_stats'       => false,
+        'icon'             => 'user',
+        'register'          => [
+            'text'      => 'Refer your friends. Get rewarded.',
+            'title'     => 'Create Your Account',
+            'description'   => [
+                'Get your unique share code',
+                'Share it with your friends',
+                'Get notified when you get your credit'
+            ],
+            'submit'    => 'Create Your Account',
         ],
-        'join_bonus'       => '<strong>BONUS: </strong>Everything\'s free. And always will be. We work with partners vetted by the community to keep the lights on.',
     ];
 }

--
Gitblit v1.10.0