First commit

This commit is contained in:
2026-05-24 11:49:38 +02:00
commit 894845d3d3
61 changed files with 4543 additions and 0 deletions

1
assets.json Normal file
View File

@@ -0,0 +1 @@
[]

59
style_properties.less Normal file
View File

@@ -0,0 +1,59 @@
// ################## THIS IS A GENERATED FILE ##################
// DO NOT EDIT DIRECTLY. EDIT THE STYLE PROPERTIES IN THE CONTROL PANEL.
@xf-blockTabHeaderBg: @xf-paletteColor2;
@xf-blockTabHeaderTextColor: @xf-paletteNeutral1;
@xf-borderColor: @xf-paletteColor5;
@xf-borderColorAccentContent: @xf-paletteAccent2;
@xf-borderColorFaint: @xf-paletteColor5;
@xf-borderColorFeature: @xf-paletteAccent3;
@xf-borderColorHeavy: @xf-paletteColor5;
@xf-borderColorHighlight: @xf-paletteAccent3;
@xf-borderColorLight: @xf-paletteColor5;
@xf-borderRadiusLarge: 0px;
@xf-borderRadiusMedium: 0px;
@xf-borderRadiusSmall: 0px;
@xf-buttonBg: @xf-paletteColor3;
@xf-buttonPrimaryBg: @xf-paletteAccent3;
@xf-buttonTextColor: @xf-paletteNeutral1;
@xf-chromeBg: @xf-paletteColor1;
@xf-chromeTextColor: @xf-paletteNeutral1;
@xf-contentAltBg: @xf-paletteColor3;
@xf-contentBg: @xf-paletteColor2;
@xf-contentHighlightBg: @xf-paletteColor3;
@xf-errorBg: #e57373;
@xf-errorColor: @xf-paletteNeutral1;
@xf-fontFamilyBody: 'Segoe UI', 'San Francisco', 'Helvetica Neue', sans-serif;
@xf-fontFamilyUi: 'Segoe UI', 'San Francisco', 'Helvetica Neue', sans-serif;
@xf-linkColor: @xf-paletteAccent3;
@xf-linkHoverColor: @xf-paletteAccent2;
@xf-linkUgcColor: @xf-paletteAccent3;
@xf-linkUgcHoverColor: @xf-paletteAccent2;
@xf-pageBg: @xf-paletteColor1;
@xf-paletteAccent2: #e56700;
@xf-paletteAccent3: #ff7300;
@xf-paletteColor1: #1e1e1e;
@xf-paletteColor2: #252526;
@xf-paletteColor3: #2d2d30;
@xf-paletteColor4: #3e3e42;
@xf-paletteColor5: #3f3f46;
@xf-paletteNeutral1: #f1f1f1;
@xf-paletteNeutral2: #a1a1aa;
@xf-paletteNeutral3: #111111;
@xf-styleType: dark;
@xf-subNavBg: @xf-paletteColor2;
@xf-successBg: #81c784;
@xf-successColor: @xf-paletteNeutral1;
@xf-successFeatureColor: #388e3c;
@xf-textColor: @xf-paletteNeutral1;
@xf-textColorEmphasized: @xf-paletteAccent3;
@xf-textColorFeature: @xf-paletteNeutral1;
.xf-blockTabHeaderSelected()
{
color: @xf-linkColor;
border-color: @xf-paletteColor2;
}
@xf-blockTabHeaderSelected--color: @xf-linkColor;
@xf-blockTabHeaderSelected--border-color: @xf-paletteColor2;

View File

@@ -0,0 +1,146 @@
{
"blockTabHeaderBg.json": {
"hash": "5207750cec31f74935a0c209f2bb7d5d"
},
"blockTabHeaderSelected.json": {
"hash": "47eac3b302ad0fe474a0d0960d01e059"
},
"blockTabHeaderTextColor.json": {
"hash": "d2d647878d3725763debf391d47486db"
},
"borderColor.json": {
"hash": "d336471427f3a4028996bddb971f2afa"
},
"borderColorAccentContent.json": {
"hash": "f2aff3c91a3241c9203b07e0c574828c"
},
"borderColorFaint.json": {
"hash": "be6f17463760417b337cebbd89773430"
},
"borderColorFeature.json": {
"hash": "2d8206ba58e695a661d20712db761817"
},
"borderColorHeavy.json": {
"hash": "ad04822f5a3a42927dd967c341e45d63"
},
"borderColorHighlight.json": {
"hash": "2ab3fdc69004f2f6a50af84ad45cc7c2"
},
"borderColorLight.json": {
"hash": "aff3cdcedc1516d511dd6aca180a8236"
},
"borderRadiusLarge.json": {
"hash": "6c8e75e1fcedd0b096d7bf911230a1c4"
},
"borderRadiusMedium.json": {
"hash": "92a2a35fde5de0e90243768ad8e236ab"
},
"borderRadiusSmall.json": {
"hash": "03a46b0de545083de0e402a483ca6f1e"
},
"buttonBg.json": {
"hash": "a8535a0dff9ac6ed83955c83d73253a0"
},
"buttonPrimaryBg.json": {
"hash": "9d6e7069664536ec94ec4a9cb00ae102"
},
"buttonTextColor.json": {
"hash": "474dfe468f35e3a7f7f7744620b9aafa"
},
"chromeBg.json": {
"hash": "7fbcf3a7cfd4a1a7cf052382201f61c5"
},
"chromeTextColor.json": {
"hash": "7d59fddb50e545f6dc4ee746d57300f9"
},
"contentAltBg.json": {
"hash": "475dbbcaf0266619fc0013038f6e1e9e"
},
"contentBg.json": {
"hash": "d5e9973a4e83961dc45fdaaf6e81c83b"
},
"contentHighlightBg.json": {
"hash": "7ee9346c8d25ea473dacd9a9e21206e7"
},
"errorBg.json": {
"hash": "5b0fa167f49f5c9955d7946d5e102f4c"
},
"errorColor.json": {
"hash": "e4469cb3a0e2c9cdc3840008700d8742"
},
"fontFamilyBody.json": {
"hash": "b35da057353bb1469829ed98a90715fd"
},
"fontFamilyUi.json": {
"hash": "45a85d0b24fa4ea774734402210aaf2e"
},
"linkColor.json": {
"hash": "7ca02736780e9e4b47bf7d6d960bcffe"
},
"linkHoverColor.json": {
"hash": "24233df430149979043c3864a9e94d4d"
},
"linkUgcColor.json": {
"hash": "a092f48a4f951cf3e92ed461659ae894"
},
"linkUgcHoverColor.json": {
"hash": "2e1385c3bfe51e1874c0ec8805217d8d"
},
"pageBg.json": {
"hash": "3975020da986bf3e13a65be134449908"
},
"paletteAccent2.json": {
"hash": "00cb79f56e2ae668475327758cdd4ce2"
},
"paletteAccent3.json": {
"hash": "e9322fb2aa0043a573713fc3f96ca79a"
},
"paletteColor1.json": {
"hash": "976763c8be910c28f4c0008c9a277448"
},
"paletteColor2.json": {
"hash": "eecdd3bf62255ec43dfc912fb56ab08c"
},
"paletteColor3.json": {
"hash": "e1603121b3eee6f5c4518966d685ef69"
},
"paletteColor4.json": {
"hash": "c645a133d49ed59c98e33fe3cc17b5c4"
},
"paletteColor5.json": {
"hash": "23dedee0b4f9b9b88f3e99a5135dbfca"
},
"paletteNeutral1.json": {
"hash": "2a6c79989236ec6cbc8bf81344b52496"
},
"paletteNeutral2.json": {
"hash": "e6d5fa3553c3542a42c954eed332dc47"
},
"paletteNeutral3.json": {
"hash": "e08775923d2c98300549be6ed17147d8"
},
"styleType.json": {
"hash": "a06efd294967581901bd111dfe7511c2"
},
"subNavBg.json": {
"hash": "b61b38b236ab81ab58134cac3fa4963b"
},
"successBg.json": {
"hash": "1c9a192fe62a1bdbaf49d0d776919de8"
},
"successColor.json": {
"hash": "c17c8090edddc7a86df397787808c105"
},
"successFeatureColor.json": {
"hash": "25ab19e3c11c371f8b53ad56af94a5a0"
},
"textColor.json": {
"hash": "df26881141502f16be13b75b9903f48f"
},
"textColorEmphasized.json": {
"hash": "7069705f62fdf89df20fcc7eab85959e"
},
"textColorFeature.json": {
"hash": "f149f8945b9e6497264151339755a294"
}
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Block tab header background color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "blockTabHeader",
"property_value": {
"default": "@xf-paletteColor2",
"alternate": "@xf-paletteColor4"
},
"display_order": 6500
}

View File

@@ -0,0 +1,22 @@
{
"group_name": "block",
"title": "Block tab header - selected tab",
"description": "The selected tab in multi-part headers takes additional styling from here",
"property_type": "css",
"css_components": [
"text",
"background",
"border_color_simple",
"extra"
],
"value_type": "",
"value_parameters": "",
"has_variations": false,
"depends_on": "",
"value_group": "",
"property_value": {
"color": "@xf-linkColor",
"border-color": "@xf-paletteColor2"
},
"display_order": 20300
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Block tab header text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "blockTabHeader",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "@xf-paletteColor2"
},
"display_order": 6600
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Border color",
"description": "Structural borders around blocks of content generally use this color",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderBasic",
"property_value": {
"default": "@xf-paletteColor5",
"alternate": "xf-intensify(@xf-contentBg, 10%)"
},
"display_order": 4000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Accent content border color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderOther",
"property_value": {
"default": "@xf-paletteAccent2",
"alternate": "mix(@xf-paletteAccent3, @xf-paletteAccent2)"
},
"display_order": 5200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Faint border color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderBasic",
"property_value": {
"default": "@xf-paletteColor5",
"alternate": "xf-diminish(@xf-borderColor, 6%)"
},
"display_order": 4100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Feature border color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderOther",
"property_value": {
"default": "@xf-paletteAccent3",
"alternate": "@xf-paletteColor3"
},
"display_order": 5100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Heavy border color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderBasic",
"property_value": {
"default": "@xf-paletteColor5",
"alternate": "xf-intensify(@xf-borderColor, 4%)"
},
"display_order": 4300
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Highlight border color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderOther",
"property_value": {
"default": "@xf-paletteAccent3",
"alternate": "@xf-paletteColor4"
},
"display_order": 5000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Light border color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "borderBasic",
"property_value": {
"default": "@xf-paletteColor5",
"alternate": "xf-diminish(@xf-borderColor, 4%)"
},
"display_order": 4200
}

View File

@@ -0,0 +1,14 @@
{
"group_name": "borderSpacing",
"title": "Large border radius",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "unit",
"value_parameters": "",
"has_variations": false,
"depends_on": "",
"value_group": "borderRadius",
"property_value": "0px",
"display_order": 1200
}

View File

@@ -0,0 +1,14 @@
{
"group_name": "borderSpacing",
"title": "Medium border radius",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "unit",
"value_parameters": "",
"has_variations": false,
"depends_on": "",
"value_group": "borderRadius",
"property_value": "0px",
"display_order": 1100
}

View File

@@ -0,0 +1,14 @@
{
"group_name": "borderSpacing",
"title": "Small border radius",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "unit",
"value_parameters": "",
"has_variations": false,
"depends_on": "",
"value_group": "borderRadius",
"property_value": "0px",
"display_order": 1000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Default button background color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "buttons",
"property_value": {
"default": "@xf-paletteColor3",
"alternate": "@xf-paletteColor4"
},
"display_order": 8200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Primary button background color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "buttons",
"property_value": {
"default": "@xf-paletteAccent3",
"alternate": "@xf-paletteColor3"
},
"display_order": 8300
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Default button text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "buttons",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "@xf-paletteColor1"
},
"display_order": 8100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Page chrome background color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "chrome",
"property_value": {
"default": "@xf-paletteColor1",
"alternate": "@xf-paletteColor5"
},
"display_order": 6000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Page chrome text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "chrome",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "@xf-paletteColor2"
},
"display_order": 6050
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Alternate content background color",
"description": "In order to differentiate it, some content will be presented on this alternate background",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "contentBackground",
"property_value": {
"default": "@xf-paletteColor3",
"alternate": "darken(@xf-contentBg, 4%)"
},
"display_order": 2200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Content background color",
"description": "Most normal content will sit on this background",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "contentBackground",
"property_value": {
"default": "@xf-paletteColor2",
"alternate": "@xf-paletteNeutral3"
},
"display_order": 2000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Highlighted content background color",
"description": "When the standard background color is highlighted or selected, it will use this color",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "contentBackground",
"property_value": {
"default": "@xf-paletteColor3",
"alternate": "@xf-paletteColor5"
},
"display_order": 2300
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Error message background",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "errorMessage",
"property_value": {
"default": "#e57373",
"alternate": "hsl(358, 70%, 20%)"
},
"display_order": 10410
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Error message text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "errorMessage",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "hsl(358, 70%, 85%)"
},
"display_order": 10420
}

View File

@@ -0,0 +1,14 @@
{
"group_name": "fonts",
"title": "Body Text Font",
"description": "This font is used for the text of messages etc.",
"property_type": "value",
"css_components": [],
"value_type": "string",
"value_parameters": "",
"has_variations": false,
"depends_on": "",
"value_group": "font",
"property_value": "'Segoe UI', 'San Francisco', 'Helvetica Neue', sans-serif",
"display_order": 200
}

View File

@@ -0,0 +1,14 @@
{
"group_name": "fonts",
"title": "User Interface Font",
"description": "The font list for your main text",
"property_type": "value",
"css_components": [],
"value_type": "string",
"value_parameters": "",
"has_variations": false,
"depends_on": "",
"value_group": "font",
"property_value": "'Segoe UI', 'San Francisco', 'Helvetica Neue', sans-serif",
"display_order": 100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Link color",
"description": "Basic hyperlinks on standard background colors will use this style",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "links",
"property_value": {
"default": "@xf-paletteAccent3",
"alternate": "@xf-paletteColor2"
},
"display_order": 1000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Link hover color",
"description": "Basic hyperlinks will turn this color when hovered",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "links",
"property_value": {
"default": "@xf-paletteAccent2",
"alternate": "@xf-paletteColor1"
},
"display_order": 1100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "User-generated content link color",
"description": "Used to color links posted by users within posts etc.",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "links",
"property_value": {
"default": "@xf-paletteAccent3",
"alternate": "@xf-paletteColor2"
},
"display_order": 1200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "User-generated link hover color",
"description": "Hover state for links in UGC",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "links",
"property_value": {
"default": "@xf-paletteAccent2",
"alternate": "@xf-paletteColor1"
},
"display_order": 1300
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Page background color",
"description": "The background of the page itself, on which all other content rests",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "contentBackground",
"property_value": {
"default": "@xf-paletteColor1",
"alternate": "darken(@xf-contentBg, 8%)"
},
"display_order": 2100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Accent 2",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "accent",
"property_value": {
"default": "#e56700",
"alternate": "hsl(35, 85%, 45%)"
},
"display_order": 2100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Accent 3",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "accent",
"property_value": {
"default": "#ff7300",
"alternate": "hsl(35, 85%, 15%)"
},
"display_order": 2200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Color 1",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "primary",
"property_value": {
"default": "#1e1e1e",
"alternate": "hsl(206, 60%, 75%)"
},
"display_order": 1000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Color 2",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "primary",
"property_value": {
"default": "#252526",
"alternate": "hsl(204, 60%, 60%)"
},
"display_order": 1100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Color 3",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "primary",
"property_value": {
"default": "#2d2d30",
"alternate": "hsl(205, 60%, 40%)"
},
"display_order": 1200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Color 4",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "primary",
"property_value": {
"default": "#3e3e42",
"alternate": "hsl(205, 60%, 20%)"
},
"display_order": 1300
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Color 5",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "primary",
"property_value": {
"default": "#3f3f46",
"alternate": "hsl(205, 60%, 10%)"
},
"display_order": 1400
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Neutral 1",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "neutral",
"property_value": {
"default": "#f1f1f1",
"alternate": "hsl(0, 0%, 100%)"
},
"display_order": 3000
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Neutral 2",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "neutral",
"property_value": {
"default": "#a1a1aa",
"alternate": "hsl(0, 0%, 54%)"
},
"display_order": 3100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Neutral 3",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "hidePalette=true",
"has_variations": true,
"depends_on": "",
"value_group": "neutral",
"property_value": {
"default": "#111111",
"alternate": "hsl(0, 0%, 8%)"
},
"display_order": 3200
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "palette",
"title": "Style type",
"description": "This defines the general type of style in use based on whether the content is placed on a light or dark background. This may change how colors are selected in certain scenarios.",
"property_type": "value",
"css_components": [],
"value_type": "radio",
"value_parameters": "light={{ phrase('light') }}\ndark={{ phrase('dark') }}",
"has_variations": true,
"depends_on": "",
"value_group": "setup",
"property_value": {
"default": "dark",
"alternate": "light"
},
"display_order": 100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Page sub-navigation background",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "chrome",
"property_value": {
"default": "@xf-paletteColor2",
"alternate": "@xf-contentAltBg"
},
"display_order": 6080
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Success message background",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "successMessage",
"property_value": {
"default": "#81c784",
"alternate": "hsl(122, 70%, 20%)"
},
"display_order": 10210
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Success message text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "successMessage",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "hsl(116, 70%, 85%)"
},
"display_order": 10220
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Success message feature color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "successMessage",
"property_value": {
"default": "#388e3c",
"alternate": "hsl(122, 70%, 50%)"
},
"display_order": 10230
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Text color",
"description": "Unless otherwise specified, text will be this color",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "textBasic",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "darken(@xf-paletteNeutral1, 12%)"
},
"display_order": 100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Emphasized text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "textOther",
"property_value": {
"default": "@xf-paletteAccent3",
"alternate": "@xf-paletteColor1"
},
"display_order": 3100
}

View File

@@ -0,0 +1,17 @@
{
"group_name": "color",
"title": "Feature text color",
"description": "",
"property_type": "value",
"css_components": [],
"value_type": "color",
"value_parameters": "",
"has_variations": true,
"depends_on": "",
"value_group": "textOther",
"property_value": {
"default": "@xf-paletteNeutral1",
"alternate": "@xf-paletteColor2"
},
"display_order": 3000
}

56
templates/_metadata.json Normal file
View File

@@ -0,0 +1,56 @@
{
"public/PAGE_CONTAINER.html": {
"addon_id": "XF",
"version_id": 2031070,
"version_string": "2.3.10",
"hash": "92f8334dbbaac2af86e9e9de3b22fc45"
},
"public/account_alerts_popup.html": {
"addon_id": "XF",
"version_id": 2031070,
"version_string": "2.3.10",
"hash": "625739bb3c29b990a3dfc58e44fd24e8"
},
"public/alert_macros.html": {
"addon_id": "XF",
"version_id": 2031070,
"version_string": "2.3.10",
"hash": "0cb82ae0d5544911ac92db38a01cb211"
},
"public/extra.less": {
"addon_id": "XF",
"version_id": 2031070,
"version_string": "2.3.10",
"hash": "24d94c7353b843acb056656d00ea35d2"
},
"public/member_tooltip.html": {
"addon_id": "XF",
"version_id": 2031070,
"version_string": "2.3.10",
"hash": "37cecc7a45e8d605a28cc4cab18fd194"
},
"public/member_tooltip.less": {
"addon_id": "XF",
"version_id": 2031070,
"version_string": "2.3.10",
"hash": "5a95069e23fb2a8c740d3d380a0feb34"
},
"public/romhackplaza_css.html": {
"addon_id": "",
"version_id": 0,
"version_string": "",
"hash": "96718ec22da14ac5d4615109068a2dc2"
},
"public/romhackplaza_js.html": {
"addon_id": "",
"version_id": 0,
"version_string": "",
"hash": "30324ecf51ac365509fce5ef1db2ecd1"
},
"public/topbar_actions.html": {
"addon_id": "RomhackPlaza/Master",
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "b4d757a96108efbca01fb7e6b68f11b5"
}
}

View File

@@ -0,0 +1,968 @@
<!DOCTYPE html>
<html id="XF" lang="{$xf.language.language_code}" dir="{$xf.language.text_direction}"
data-xf="{$xf.versionVisible}"
data-app="public"
{{ ($xf.style.isVariationsEnabled() && $xf.visitor.style_variation) ? 'data-variation="' . $xf.visitor.style_variation . '"' : '' }}
{{ ($xf.style.isVariationsEnabled() && $xf.visitor.style_variation) ? 'data-color-scheme="' . property_variation('styleType', $xf.visitor.style_variation) . '"' : '' }}
data-template="{$template}"
data-container-key="{$containerKey}"
data-content-key="{$contentKey}"
data-logged-in="{{ $xf.visitor.user_id ? 'true' : 'false' }}"
data-cookie-prefix="{$xf.cookie.prefix}"
data-csrf="{{ csrf_token()|escape('js') }}"
class="has-no-js {{ $template ? 'template-' . $template : '' }}"
{{ $xf.runJobs ? ' data-run-jobs=""' : '' }}>
<head>
<xf:set var="$siteName" value="{$xf.options.boardTitle}" />
<xf:set var="$h1"><xf:h1 fallback="{$siteName}" /></xf:set>
<xf:set var="$description"><xf:description /></xf:set>
<meta charset="utf-8" />
<title><xf:title formatter="%s | %s" fallback="{$xf.options.boardTitle}" page="{$pageNumber}" /></title>
<link rel="manifest" href="{{ base_url('webmanifest.php') }}">
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<xf:if is="$xf.style.isVariationsEnabled()">
<xf:if is="$xf.visitor.style_variation">
<meta name="theme-color" content="{{ parse_less_color(property_variation('metaThemeColor', $xf.visitor.style_variation)) }}" />
<xf:else />
<xf:if is="$xf.style.hasAlternateStyleTypeVariation()">
<meta name="theme-color" media="(prefers-color-scheme: {{ $xf.style.getDefaultStyleType() }})" content="{{ parse_less_color(property_variation('metaThemeColor', 'default')) }}" />
<meta name="theme-color" media="(prefers-color-scheme: {{ $xf.style.getAlternateStyleType() }})" content="{{ parse_less_color(property_variation('metaThemeColor', $xf.style.getAlternateStyleTypeVariation())) }}" />
<xf:else />
<meta name="theme-color" content="{{ parse_less_color(property_variation('metaThemeColor', 'default')) }}" />
</xf:if>
</xf:if>
<xf:else />
<meta name="theme-color" content="{{ parse_less_color(property_variation('metaThemeColor', 'default')) }}" />
</xf:if>
<meta name="apple-mobile-web-app-title" content="{{ $xf.options.boardShortTitle ?: $xf.options.boardTitle }}">
<xf:if is="property('publicIconUrl')">
<link rel="apple-touch-icon" href="{{ base_url(property('publicIconUrl', true)) }}">
<xf:elseif is="property('publicMetadataLogoUrl')" />
<link rel="apple-touch-icon" href="{{ base_url(property('publicMetadataLogoUrl')) }}" />
</xf:if>
<xf:foreach loop="$head" value="$headTag">
{$headTag}
</xf:foreach>
<xf:if is="!$head.meta_site_name && $siteName is not empty">
<xf:macro id="metadata_macros::site_name" arg-siteName="{$siteName}" arg-output="{{ true }}" />
</xf:if>
<xf:if is="!$head.meta_type">
<xf:macro id="metadata_macros::type" arg-type="website" arg-output="{{ true }}" />
</xf:if>
<xf:if is="!$head.meta_title">
<xf:macro id="metadata_macros::title" arg-title="{{ page_title() ?: $siteName }}" arg-output="{{ true }}" />
</xf:if>
<xf:if is="!$head.meta_description && $description is not empty && $pageDescriptionMeta">
<xf:macro id="metadata_macros::description" arg-description="{$description}" arg-output="{{ true }}" />
</xf:if>
<xf:if is="!$head.meta_share_url">
<xf:macro id="metadata_macros::share_url" arg-shareUrl="{$xf.fullUri}" arg-output="{{ true }}" />
</xf:if>
<xf:if is="!$head.meta_image_url && property('publicMetadataLogoUrl')">
<xf:macro id="metadata_macros::image_url"
arg-imageUrl="{{ base_url(property('publicMetadataLogoUrl'), true) }}"
arg-output="{{ true }}" />
</xf:if>
<xf:macro id="helper_js_global::head" arg-app="public" arg-jsState="{$jsState}" />
<xf:if is="property('publicFaviconUrl')">
<link rel="icon" type="image/png" href="{{ base_url(property('publicFaviconUrl'), true) }}" sizes="32x32" />
</xf:if>
<xf:include template="google_analytics" />
<xf:include template="romhackplaza_css" />
</head>
<body data-template="{$template}">
<div id="app">
<nav id="menu">
<div class="$menu-header">
<div class="$menu-logo">
RP
</div>
<div class="$menu-title">
Romhack Plaza
</div>
</div>
<div class="$menu-navigation">
<div class="$menu-group">
<xf:foreach loop="$navTree" key="$navSection" value="$navEntry" i="$i" if="{{ $navSection != $xf.app.defaultNavigationId }}">
<div class="$menu-group-title">{{ $navEntry.title }}</div>
<xf:foreach loop="$navEntry.children" key="$childNavId" value="$childNavEntry" i="$j">
<a href="{{ $childNavEntry.href }}" class="$menu-item" >
<i data-lucide="{{ $childNavEntry.attributes.icon}}"></i><span>{{ $childNavEntry.title }}</span>
</a>
</xf:foreach>
</xf:foreach>
</div>
</div>
<div class="$menu-user">
<div class="$menu-user-avatar $xf-menu-user-avatar-fix">
<xf:avatar user="{$xf.visitor}" size="s" canonical="true" />
</div>
<div class="$menu-user-info">
<span class="$username">
<xf:username user="{$xf.visitor}" rich="true" defaultname="Guest" />
</span>
<span class="$user_role">
<xf:if is="$xf.visitor.user_id">
<a href="{{ link('logout', null, {'t': csrf_token()}) }}">
{{ phrase('logout') }}
</a>
<xf:else />
<a href="{{ link('login') }}">
{{ phrase('login') }}
</a>
</xf:if>
</span>
</div>
</div>
</nav>
<xf:comment>
<xf:if contentcheck="true">
<div class="p-staffBar">
<div class="p-staffBar-inner hScroller" data-xf-init="h-scroller">
<div class="hScroller-scroll">
<xf:contentcheck>
<xf:if is="$xf.visitor.is_moderator && $xf.session.unapprovedCounts.total">
<a href="{{ link('approval-queue') }}" class="p-staffBar-link badgeContainer badgeContainer--highlighted" data-badge="{$xf.session.unapprovedCounts.total|number}">
{{ phrase('approval_queue') }}
</a>
</xf:if>
<xf:if is="$xf.visitor.is_moderator && !$xf.options.reportIntoForumId && $xf.session.reportCounts.total">
<a href="{{ link('reports') }}"
class="p-staffBar-link badgeContainer badgeContainer--visible {{ ($xf.session.reportCounts.total && ($xf.session.reportCounts.lastBuilt > $xf.session.reportLastRead) OR $xf.session.reportCounts.assigned) ? ' badgeContainer--highlighted' : '' }}"
data-badge="{{ $xf.session.reportCounts.assigned ? $xf.session.reportCounts.assigned|number . ' / ' . $xf.session.reportCounts.total|number : $xf.session.reportCounts.total|number }}"
title="{{ $xf.session.reportCounts.lastBuilt ? phrase('last_report_update:')|for_attr . ' ' . date_time($xf.session.reportCounts.lastBuilt) : '' }}">
{{ phrase('reports') }}
</a>
</xf:if>
<xf:if contentcheck="true">
<a class="p-staffBar-link menuTrigger" data-xf-click="menu" data-xf-key="alt+m" role="button" tabindex="0" aria-expanded="false" aria-haspopup="true">{{ phrase('moderator') }}</a>
<div class="menu" data-menu="menu" aria-hidden="true">
<div class="menu-content">
<h4 class="menu-header">{{ phrase('moderator_tools') }}</h4>
<xf:contentcheck>
<!--[XF:mod_tools_menu:top]-->
<xf:if is="$xf.visitor.is_moderator">
<a href="{{ link('approval-queue') }}" class="menu-linkRow">{{ phrase('approval_queue') }}</a>
</xf:if>
<xf:if is="$xf.visitor.is_moderator && !$xf.options.reportIntoForumId">
<a href="{{ link('reports') }}" class="menu-linkRow" title="{{ $xf.session.reportCounts.lastBuilt ? phrase('last_report_update:')|for_attr . ' ' . date_time($xf.session.reportCounts.lastBuilt) : '' }}">{{ phrase('reports') }}</a>
</xf:if>
<!--[XF:mod_tools_menu:bottom]-->
</xf:contentcheck>
</div>
</div>
</xf:if>
<xf:if is="$xf.visitor.is_admin">
<a href="{{ base_url('admin.php') }}" class="p-staffBar-link" target="_blank">{{ phrase('admin') }}</a>
</xf:if>
</xf:contentcheck>
</div>
</div>
</div>
</xf:if>
<header class="p-header" id="header">
<div class="p-header-inner">
<div class="p-header-content">
<div class="p-header-logo p-header-logo--image">
<a href="{{ ($xf.options.logoLink && $xf.homePageUrl) ? $xf.homePageUrl : link('index') }}">
<xf:macro id="style_variation_macros::picture"
arg-property="publicLogoUrl"
arg-propertyRetina="publicLogoUrl2x"
arg-width="{{ property('publicLogoWidth') }}"
arg-height="{{ property('publicLogoHeight') }}"
arg-alt="{$xf.options.boardTitle}" />
</a>
</div>
<xf:ad position="container_header" />
</div>
</div>
</header>
<xf:set var="$navHtml">
<nav class="p-nav">
<div class="p-nav-inner">
<xf:button class="button--plain p-nav-menuTrigger" data-xf-click="off-canvas" data-menu=".js-headerOffCanvasMenu" tabindex="0"
aria-label="{{ phrase('menu')|for_attr }}">
<i aria-hidden="true"></i>
</xf:button>
<div class="p-nav-smallLogo">
<a href="{{ ($xf.options.logoLink && $xf.homePageUrl) ? $xf.homePageUrl : link('index') }}">
<xf:macro id="style_variation_macros::picture"
arg-property="publicLogoUrl"
arg-property2x="publicLogoUrl2x"
arg-width="{{ property('publicLogoWidth') }}"
arg-height="{{ property('publicLogoHeight') }}"
arg-alt="{$xf.options.boardTitle}" />
</a>
</div>
<div class="p-nav-scroller hScroller" data-xf-init="h-scroller" data-auto-scroll=".p-navEl.is-selected">
<div class="hScroller-scroll">
<ul class="p-nav-list js-offCanvasNavSource">
<xf:foreach loop="$navTree" key="$navSection" value="$navEntry" i="$i" if="{{ $navSection != $xf.app.defaultNavigationId }}">
<li>
<xf:macro name="nav_entry"
arg-navId="{$navSection}"
arg-nav="{$navEntry}"
arg-selected="{{ $navSection == $pageSection }}"
arg-shortcut="{$i}" />
</li>
</xf:foreach>
</ul>
</div>
</div>
<div class="p-nav-opposite">
<div class="p-navgroup p-account {{ $xf.visitor.user_id ? 'p-navgroup--member' : 'p-navgroup--guest' }}">
<xf:if is="$xf.visitor.user_id">
<xf:if is="$xf.visitor.user_state == 'rejected' OR $xf.visitor.user_state == 'disabled'">
<a href="{{ link('account') }}"
class="p-navgroup-link p-navgroup-link--iconic p-navgroup-link--user">
<xf:avatar user="$xf.visitor" size="xxs" href="" title="" />
<span class="p-navgroup-linkText">{$xf.visitor.username}</span>
</a>
<a href="{{ link('logout', null, {'t': csrf_token()}) }}" class="p-navgroup-link">
<span class="p-navgroup-linkText">{{ phrase('log_out') }}</span>
</a>
<xf:else />
<a href="{{ link('account') }}"
class="p-navgroup-link p-navgroup-link--iconic p-navgroup-link--user"
data-xf-click="menu"
data-xf-key="{{ phrase('shortcut.visitor_menu')|for_attr }}"
data-menu-pos-ref="< .p-navgroup"
title="{$xf.visitor.username}"
aria-expanded="false"
aria-haspopup="true">
<xf:avatar user="$xf.visitor" size="xxs" href="" title="" />
<span class="p-navgroup-linkText">{$xf.visitor.username}</span>
</a>
<div class="menu menu--structural menu--wide menu--account" data-menu="menu" aria-hidden="true"
data-href="{{ link('account/visitor-menu') }}"
data-load-target=".js-visitorMenuBody">
<div class="menu-content js-visitorMenuBody">
<div class="menu-row">
{{ phrase('loading...') }}
</div>
</div>
</div>
<a href="{{ link('direct-messages') }}"
class="p-navgroup-link p-navgroup-link--iconic p-navgroup-link--conversations js-badge--conversations badgeContainer{{ $xf.visitor.conversations_unread ? ' badgeContainer--highlighted' : '' }}"
data-badge="{$xf.visitor.conversations_unread|number}"
data-xf-click="menu"
data-xf-key="{{ phrase('shortcut.conversations_menu')|for_attr }}"
data-menu-pos-ref="< .p-navgroup"
title="{{ phrase('direct_messages')|for_attr }}"
aria-label="{{ phrase('direct_messages')|for_attr }}"
aria-expanded="false"
aria-haspopup="true">
<i aria-hidden="true"></i>
<span class="p-navgroup-linkText">{{ phrase('nav_inbox') }}</span>
</a>
<div class="menu menu--structural menu--medium" data-menu="menu" aria-hidden="true"
data-href="{{ link('direct-messages/popup') }}"
data-nocache="true"
data-load-target=".js-convMenuBody">
<div class="menu-content">
<h3 class="menu-header">{{ phrase('direct_messages') }}</h3>
<div class="js-convMenuBody">
<div class="menu-row">{{ phrase('loading...') }}</div>
</div>
<div class="menu-footer menu-footer--split">
<div class="menu-footer-main">
<ul class="listInline listInline--bullet">
<li><a href="{{ link('direct-messages') }}">{{ phrase('show_all') }}</a></li>
<xf:if is="$xf.visitor.canStartConversation()">
<li><a href="{{ link('direct-messages/add') }}">{{ phrase('send_direct_message') }}</a></li>
</xf:if>
</ul>
</div>
</div>
</div>
</div>
<a href="{{ link('account/alerts') }}"
class="p-navgroup-link p-navgroup-link--iconic p-navgroup-link--alerts js-badge--alerts badgeContainer{{ $xf.visitor.alerts_unviewed ? ' badgeContainer--highlighted' : '' }}"
data-badge="{$xf.visitor.alerts_unviewed|number}"
data-xf-click="menu"
data-xf-key="{{ phrase('shortcut.alerts_menu')|for_attr }}"
data-menu-pos-ref="< .p-navgroup"
title="{{ phrase('alerts')|for_attr }}"
aria-label="{{ phrase('alerts')|for_attr }}"
aria-expanded="false"
aria-haspopup="true">
<i aria-hidden="true"></i>
<span class="p-navgroup-linkText">{{ phrase('nav_alerts') }}</span>
</a>
<div class="menu menu--structural menu--medium" data-menu="menu" aria-hidden="true"
data-href="{{ link('account/alerts-popup') }}"
data-nocache="true"
data-load-target=".js-alertsMenuBody">
<div class="menu-content">
<h3 class="menu-header">{{ phrase('alerts') }}</h3>
<div class="js-alertsMenuBody">
<div class="menu-row">{{ phrase('loading...') }}</div>
</div>
<div class="menu-footer menu-footer--split">
<div class="menu-footer-main">
<ul class="listInline listInline--bullet">
<li><a href="{{ link('account/alerts') }}">{{ phrase('show_all') }}</a></li>
<li><a href="{{ link('account/alerts/mark-read') }}" class="js-alertsMarkRead">{{ phrase('mark_read') }}</a></li>
<li><a href="{{ link('account/preferences') }}">{{ phrase('preferences') }}</a></li>
</ul>
</div>
</div>
</div>
</div>
</xf:if>
<xf:else />
<a href="{{ link('login') }}" class="p-navgroup-link p-navgroup-link--textual p-navgroup-link--logIn"
data-xf-click="overlay" data-follow-redirects="on">
<span class="p-navgroup-linkText">{{ phrase('log_in') }}</span>
</a>
<xf:if is="$xf.options.registrationSetup.enabled">
<a href="{{ link('register') }}" class="p-navgroup-link p-navgroup-link--textual p-navgroup-link--register"
data-xf-click="overlay" data-follow-redirects="on">
<span class="p-navgroup-linkText">{{ phrase('register') }}</span>
</a>
</xf:if>
</xf:if>
</div>
<div class="p-navgroup p-discovery{{ !$xf.visitor.canSearch() ? ' p-discovery--noSearch' : '' }}">
<a href="{{ link('whats-new') }}"
class="p-navgroup-link p-navgroup-link--iconic p-navgroup-link--whatsnew"
aria-label="{{ phrase('whats_new')|for_attr }}"
title="{{ phrase('whats_new')|for_attr }}">
<i aria-hidden="true"></i>
<span class="p-navgroup-linkText">{{ phrase('whats_new') }}</span>
</a>
<xf:if is="$xf.visitor.canSearch()">
<a href="{{ link('search') }}"
class="p-navgroup-link p-navgroup-link--iconic p-navgroup-link--search"
data-xf-click="menu"
data-xf-key="{{ phrase('shortcut.search_menu')|for_attr }}"
aria-label="{{ phrase('search')|for_attr }}"
aria-expanded="false"
aria-haspopup="true"
title="{{ phrase('search')|for_attr }}">
<i aria-hidden="true"></i>
<span class="p-navgroup-linkText">{{ phrase('search') }}</span>
</a>
<div class="menu menu--structural menu--wide" data-menu="menu" aria-hidden="true">
<form action="{{ link('search/search') }}" method="post"
class="menu-content"
data-xf-init="quick-search">
<h3 class="menu-header">{{ phrase('search') }}</h3>
<!--[XF:search_menu:above_input]-->
<div class="menu-row">
<xf:if is="$searchConstraints">
<div class="inputGroup inputGroup--joined">
<xf:textbox name="keywords"
data-xf-init="{{ $xf.searchAutoComplete ? 'search-auto-complete' : '' }}"
data-acurl="{{ link('search/auto-complete') }}"
placeholder="{{ phrase('search...') }}"
aria-label="{{ phrase('search') }}"
data-menu-autofocus="true" />
<xf:select name="constraints"
class="js-quickSearch-constraint"
aria-label="{{ phrase('search_within') }}">
<xf:option value="">{{ phrase('everywhere') }}</xf:option>
<xf:foreach loop="$searchConstraints" key="$constraintName" value="$constraint">
<xf:option value="{$constraint|json}">{$constraintName}</xf:option>
</xf:foreach>
</xf:select>
</div>
<xf:else />
<xf:textbox name="keywords"
data-xf-init="{{ $xf.searchAutoComplete ? 'search-auto-complete' : '' }}"
data-acurl="{{ link('search/auto-complete') }}"
placeholder="{{ phrase('search...') }}"
aria-label="{{ phrase('search') }}"
data-menu-autofocus="true" />
</xf:if>
</div>
<!--[XF:search_menu:above_title_only]-->
<div class="menu-row">
<xf:checkbox standalone="true">
<xf:option name="c[title_only]">
<xf:label>
{{ phrase('search_titles_only') }}
<xf:if is="$xf.options.enableTagging">
<span tabindex="0" role="button"
data-xf-init="tooltip" data-trigger="hover focus click" title="{{ phrase('tags_will_also_be_searched')|for_attr }}">
<xf:fa icon="far fa-question-circle" class="u-muted u-smaller"
title="{{ phrase('note')|for_attr }}" />
</span>
</xf:if>
</xf:label>
</xf:option>
</xf:checkbox>
</div>
<!--[XF:search_menu:above_member]-->
<div class="menu-row">
<div class="inputGroup">
<span class="inputGroup-text" id="ctrl_search_menu_by_member">{{ phrase('by:') }}</span>
<input type="text" class="input" name="c[users]" data-xf-init="auto-complete" placeholder="{{ phrase('member')|for_attr }}" aria-labelledby="ctrl_search_menu_by_member" />
</div>
</div>
<div class="menu-footer">
<span class="menu-footer-controls">
<xf:button type="submit" class="button--primary" icon="search" />
<xf:button type="submit" name="from_search_menu">{{ phrase('advanced_search...') }}</xf:button>
</span>
</div>
<xf:csrf />
</form>
</div>
</xf:if>
</div>
</div>
</div>
</nav>
</xf:set>
<xf:set var="$subNavHtml">
<xf:if is="$selectedNavChildren is not empty">
<div class="p-sectionLinks">
<div class="p-sectionLinks-inner hScroller" data-xf-init="h-scroller">
<div class="hScroller-scroll">
<ul class="p-sectionLinks-list">
<xf:foreach loop="$selectedNavChildren" key="$navId" value="$navEntry" i="$i">
<li>
<xf:macro id="nav_entry" arg-navId="{$navId}" arg-nav="{$navEntry}" arg-shortcut="alt+{$i}" />
</li>
</xf:foreach>
</ul>
</div>
</div>
</div>
<xf:elseif is="{$selectedNavEntry}" />
<div class="p-sectionLinks p-sectionLinks--empty"></div>
</xf:if>
</xf:set>
<xf:if is="property('publicNavSticky') == 'primary'">
<div class="p-navSticky p-navSticky--primary" data-xf-init="sticky-header">
{$navHtml|raw}
</div>
{$subNavHtml|raw}
<xf:elseif is="property('publicNavSticky') == 'all'" />
<div class="p-navSticky p-navSticky--all" data-xf-init="sticky-header">
{$navHtml|raw}
{$subNavHtml|raw}
</div>
<xf:else />
{$navHtml|raw}
{$subNavHtml|raw}
</xf:if>
</xf:comment>
<div class="offCanvasMenu offCanvasMenu--nav js-headerOffCanvasMenu" data-menu="menu" aria-hidden="true" data-ocm-builder="navigation">
<div class="offCanvasMenu-backdrop" data-menu-close="true"></div>
<div class="offCanvasMenu-content">
<div class="offCanvasMenu-header">
{{ phrase('menu') }}
<a class="offCanvasMenu-closer" data-menu-close="true" role="button" tabindex="0" aria-label="{{ phrase('close')|for_attr }}"></a>
</div>
<xf:if is="$xf.visitor.user_id">
<div class="p-offCanvasAccountLink">
<div class="offCanvasMenu-linkHolder">
<a href="{{ link('account') }}" class="offCanvasMenu-link">
<xf:avatar user="$xf.visitor" size="xxs" href="" />
{$xf.visitor.username}
</a>
</div>
<hr class="offCanvasMenu-separator" />
</div>
<xf:else />
<div class="p-offCanvasRegisterLink">
<div class="offCanvasMenu-linkHolder">
<a href="{{ link('login') }}" class="offCanvasMenu-link" data-xf-click="overlay" data-menu-close="true">
{{ phrase('log_in') }}
</a>
</div>
<hr class="offCanvasMenu-separator" />
<xf:if is="$xf.options.registrationSetup.enabled">
<div class="offCanvasMenu-linkHolder">
<a href="{{ link('register') }}" class="offCanvasMenu-link" data-xf-click="overlay" data-menu-close="true">
{{ phrase('register') }}
</a>
</div>
<hr class="offCanvasMenu-separator" />
</xf:if>
</div>
</xf:if>
<div class="js-offCanvasNavTarget"></div>
<div class="offCanvasMenu-installBanner js-installPromptContainer" style="display: none;" data-xf-init="install-prompt">
<div class="offCanvasMenu-installBanner-header">{{ phrase('install_app') }}</div>
<xf:button class="js-installPromptButton">{{ phrase('install') }}</xf:button>
<template class="js-installTemplateIOS">
<div class="js-installTemplateContent">
<div class="overlay-title">{{ phrase('how_to_install_app_on_ios') }}</div>
<div class="block-body">
<div class="block-row">
<p>
{{ phrase('follow_along_with_video_below_to_see_how_to_install_our_site_as_web_app') }}
</p>
<p style="text-align: center">
<video src="{{ base_url(property('publicPwaInstallVideoUrl')) }}"
width="280" height="480" autoplay loop muted playsinline></video>
</p>
<p>
<small><strong>{{ phrase('note:') }}</strong> {{ phrase('this_feature_currently_may_not_be_available_in_some_browsers') }}</small>
</p>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
<main id="main-wrapper">
<header id="topbar">
<button class="$mobile-toggle">
<i data-lucide="menu"></i>
</button>
<div class="$search-bar">
<i data-lucide="search" size="18" color="var(--text2)"></i>
<input type="text">Search</input>
</div>
<xf:include template="topbar_actions" />
</header>
<div id="content">
<!--XF:EXTRA_OUTPUT-->
<xf:if is="$notices.block">
<xf:macro id="notice_macros::notice_list" arg-type="block" arg-notices="{$notices.block}" />
</xf:if>
<xf:if is="$notices.scrolling">
<xf:macro id="notice_macros::notice_list" arg-type="scrolling" arg-notices="{$notices.scrolling}" />
</xf:if>
<xf:ad position="container_breadcrumb_top_above" />
<xf:macro id="breadcrumbs"
arg-breadcrumbs="{$breadcrumbs}"
arg-navTree="{$navTree}"
arg-selectedNavEntry="{$selectedNavEntry}" />
<xf:ad position="container_breadcrumb_top_below" />
<xf:macro id="browser_warning_macros::javascript"/>
<xf:macro id="browser_warning_macros::browser"/>
<xf:if is="$headerHtml is not empty">
<div class="p-body-header">
{$headerHtml|raw}
</div>
<xf:elseif contentcheck="true" />
<div class="p-body-header">
<xf:contentcheck>
<xf:if contentcheck="true">
<div class="p-title {{ $noH1 ? 'p-title--noH1' : '' }}">
<xf:contentcheck>
<xf:if is="!$noH1">
<h1 class="p-title-value">{$h1}</h1>
</xf:if>
<xf:if contentcheck="true">
<div class="p-title-pageAction"><xf:contentcheck><xf:pageaction /></xf:contentcheck></div>
</xf:if>
</xf:contentcheck>
</div>
</xf:if>
<xf:if is="$description is not empty">
<div class="p-description">{$description}</div>
</xf:if>
</xf:contentcheck>
</div>
</xf:if>
<div class="p-body-main {{ $sidebar ? 'p-body-main--withSidebar' : '' }} {{ $sideNav ? 'p-body-main--withSideNav' : '' }}">
<xf:if is="$sideNav">
<div class="p-body-sideNavCol"></div>
</xf:if>
<div class="p-body-contentCol"></div>
<xf:if is="$sidebar">
<div class="p-body-sidebarCol"></div>
</xf:if>
<xf:if is="$sideNav">
<div class="p-body-sideNav">
<div class="p-body-sideNavTrigger">
<xf:button class="button--link" data-xf-click="off-canvas" data-menu="#js-SideNavOcm">
{{ $sideNavTitle ?: phrase('navigation') }}
</xf:button>
</div>
<div class="p-body-sideNavInner" data-ocm-class="offCanvasMenu offCanvasMenu--blocks" id="js-SideNavOcm" data-ocm-builder="sideNav">
<div data-ocm-class="offCanvasMenu-backdrop" data-menu-close="true"></div>
<div data-ocm-class="offCanvasMenu-content">
<div class="p-body-sideNavContent">
<xf:ad position="container_sidenav_above" />
<xf:foreach loop="$sideNav" value="$sideNavHtml">
{$sideNavHtml}
</xf:foreach>
<xf:ad position="container_sidenav_below" />
</div>
</div>
</div>
</div>
</xf:if>
<div class="p-body-content">
<xf:ad position="container_content_above" />
<div class="p-body-pageContent">{$content|raw}</div>
<xf:ad position="container_content_below" />
</div>
<xf:if is="$sidebar">
<div class="p-body-sidebar">
<xf:ad position="container_sidebar_above" />
<xf:foreach loop="$sidebar" value="$sidebarHtml">
{$sidebarHtml}
</xf:foreach>
<xf:ad position="container_sidebar_below" />
</div>
</xf:if>
</div>
<xf:ad position="container_breadcrumb_bottom_above" />
<xf:macro id="breadcrumbs"
arg-breadcrumbs="{$breadcrumbs}"
arg-navTree="{$navTree}"
arg-selectedNavEntry="{$selectedNavEntry}"
arg-variant="bottom" />
<xf:ad position="container_breadcrumb_bottom_below" />
</div>
</div>
<xf:comment>
<footer class="p-footer" id="footer">
<div class="p-footer-inner">
<div class="p-footer-row">
<xf:if contentcheck="true">
<div class="p-footer-row-main">
<ul class="p-footer-linkList">
<xf:contentcheck>
<xf:if is="$xf.cookieConsent.getMode() == 'advanced'">
<li><a href="{{ link('misc/cookies') }}" rel="nofollow"
data-xf-init="tooltip" title="{{ phrase('cookie_consent')|for_attr }}"
data-xf-click="cookie-consent-toggle">
<xf:fa icon="fa-cookie" /> {{ phrase('cookie_consent_label') }}
</a></li>
</xf:if>
<xf:if contentcheck="true">
<li>
<xf:contentcheck>
<xf:if is="$xf.visitor.canChangeStyle()">
<a href="{{ link('misc/style') }}" data-xf-click="overlay"
data-xf-init="tooltip" title="{{ phrase('style_chooser')|for_attr }}" rel="nofollow">
<xf:fa icon="fa-paint-brush" /> {$xf.style.title}
</a>
</xf:if>
<xf:if is="$xf.visitor.canChangeStyleVariation($xf.style)">
<a href="{{ link('misc/style-variation') }}" rel="nofollow"
class="js-styleVariationsLink"
data-xf-init="tooltip" title="{{ phrase('style_variation') }}"
data-xf-click="menu" data-z-index-ref=".u-bottomFixer" role="button" aria-expanded="false" aria-haspopup="true">
<xf:fa icon="{{ $xf.style.getVariationIcon($xf.visitor.style_variation) }}" title="{{ phrase('style_variation') }}" />
</a>
<div class="menu" data-menu="menu" aria-hidden="true">
<div class="menu-content js-styleVariationsMenu">
<xf:macro name="style_variation_macros::variation_menu"
arg-style="{$xf.style}"
arg-live="{{ true }}" />
</div>
</div>
</xf:if>
</xf:contentcheck>
</li>
</xf:if>
<xf:if is="$xf.visitor.canChangeLanguage()">
<li><a href="{{ link('misc/language') }}" data-xf-click="overlay"
data-xf-init="tooltip" title="{{ phrase('language_chooser')|for_attr }}" rel="nofollow">
<xf:fa icon="fa-globe" /> {$xf.language.title}</a></li>
</xf:if>
</xf:contentcheck>
</ul>
</div>
</xf:if>
<div class="p-footer-row-opposite">
<ul class="p-footer-linkList">
<xf:if is="$xf.visitor.canUseContactForm()">
<xf:if is="$xf.contactUrl">
<li><a href="{$xf.contactUrl}" data-xf-click="{{ ($xf.options.contactUrl.overlay OR $xf.options.contactUrl.type == 'default') ? 'overlay' : '' }}">{{ phrase('contact_us') }}</a></li>
</xf:if>
</xf:if>
<xf:if is="$xf.tosUrl">
<li><a href="{$xf.tosUrl}">{{ phrase('terms_and_rules') }}</a></li>
</xf:if>
<xf:if is="$xf.privacyPolicyUrl">
<li><a href="{$xf.privacyPolicyUrl}">{{ phrase('privacy_policy') }}</a></li>
</xf:if>
<xf:if is="$xf.helpPageCount">
<li><a href="{{ link('help') }}">{{ phrase('help') }}</a></li>
</xf:if>
<xf:if is="$xf.homePageUrl">
<li><a href="{$xf.homePageUrl}">{{ phrase('home') }}</a></li>
</xf:if>
<li><a href="{{ link('forums/index.rss', '-') }}" target="_blank" class="p-footer-rssLink" title="{{ phrase('rss')|for_attr }}"><span aria-hidden="true"><xf:fa icon="fa-rss" /><span class="u-srOnly">{{ phrase('rss') }}</span></span></a></li>
</ul>
</div>
</div>
<xf:if contentcheck="true">
<div class="p-footer-copyright">
<xf:contentcheck>
<xf:copyright />
{{ phrase('extra_copyright') }}
</xf:contentcheck>
</div>
</xf:if>
<xf:if contentcheck="true">
<div class="p-footer-debug">
<xf:contentcheck>
<xf:macro id="debug_macros::debug"
arg-controller="{$controller}"
arg-action="{$actionMethod}"
arg-template="{$template}" />
</xf:contentcheck>
</div>
</xf:if>
</div>
</footer>
</xf:comment>
</div> <!-- closing p-pageWrapper -->
<div class="u-bottomFixer js-bottomFixTarget">
<xf:if is="$notices.floating">
<xf:macro id="notice_macros::notice_list" arg-type="floating" arg-notices="{$notices.floating}" />
</xf:if>
<xf:if is="$notices.bottom_fixer">
<xf:macro id="notice_macros::notice_list" arg-type="bottom_fixer" arg-notices="{$notices.bottom_fixer}" />
</xf:if>
</div>
<div class="u-navButtons js-navButtons">
<xf:button href="javascript:" class="button--scroll"><xf:fa icon="{{ $xf.isRtl ? 'fa-arrow-right' : 'fa-arrow-left' }}" /><span class="u-srOnly">{{ phrase('back') }}</span></xf:button>
</div>
<xf:if is="property('scrollJumpButtons')">
<div class="u-scrollButtons js-scrollButtons" data-trigger-type="{{ property('scrollJumpButtons') }}">
<xf:button href="#top" class="button--scroll" data-xf-click="scroll-to"><xf:fa icon="fa-arrow-up" /><span class="u-srOnly">{{ phrase('top') }}</span></xf:button>
<xf:if is="property('scrollJumpButtons') != 'up'">
<xf:button href="#footer" class="button--scroll" data-xf-click="scroll-to"><xf:fa icon="fa-arrow-down" /><span class="u-srOnly">{{ phrase('bottom') }}</span></xf:button>
</xf:if>
</div>
</xf:if>
<xf:macro id="helper_js_global::body" arg-app="public" />
<xf:if is="count($xf.reactionsActive) > 1 AND $xf.visitor.user_id">
<script type="text/template" id="xfReactTooltipTemplate">
<div class="tooltip-content-inner">
<div class="reactTooltip">
<xf:foreach loop="$xf.reactionsActive" key="$reactionId" value="$reaction">
<xf:reaction id="{$reactionId}" tooltip="true" />
</xf:foreach>
</div>
</div>
</script>
</xf:if>
{$ldJsonHtml|raw}
<xf:include template="romhackplaza_js" />
</body>
</html>
<xf:macro id="nav_entry" arg-navId="!" arg-nav="!" arg-selected="{{ false }}" arg-shortcut="">
<div class="p-navEl {{ $selected ? 'is-selected' : '' }}" {{ $nav.children ? 'data-has-children="true"' : '' }}>
<xf:if is="$nav.href">
<xf:macro id="nav_link"
arg-navId="{$navId}"
arg-nav="{$nav}"
arg-class="p-navEl-link {{ $nav.children ? 'p-navEl-link--splitMenu' : '' }}"
arg-shortcut="{{ $nav.children ? false : $shortcut }}" />
<xf:if is="$nav.children"><a data-xf-key="{$shortcut}"
data-xf-click="menu"
data-menu-pos-ref="< .p-navEl"
class="p-navEl-splitTrigger"
role="button"
tabindex="0"
aria-label="{{ phrase('toggle_expanded')|for_attr }}"
aria-expanded="false"
aria-haspopup="true"></a></xf:if>
<xf:elseif is="$nav.children" />
<xf:if is="$selected">
<xf:macro id="nav_link"
arg-navId="{$navId}"
arg-nav="{$nav}"
arg-class="p-navEl-link" />
<xf:else />
<a data-xf-key="{$shortcut}"
data-xf-click="menu"
data-menu-pos-ref="< .p-navEl"
class="p-navEl-linkHolder"
role="button"
tabindex="0"
aria-expanded="false"
aria-haspopup="true">
<xf:macro id="nav_link"
arg-navId="{$navId}"
arg-nav="{$nav}"
arg-class="p-navEl-link p-navEl-link--menuTrigger" />
</a>
</xf:if>
<xf:else />
<xf:macro id="nav_link"
arg-navId="{$navId}"
arg-nav="{$nav}"
arg-class="p-navEl-link"
arg-shortcut="{$shortcut}" />
</xf:if>
<xf:if is="$nav.children">
<div class="menu menu--structural" data-menu="menu" aria-hidden="true">
<div class="menu-content">
<xf:foreach loop="$nav.children" key="$childNavId" value="$child">
<xf:macro id="nav_menu_entry"
arg-navId="{$childNavId}"
arg-nav="{$child}" />
</xf:foreach>
</div>
</div>
</xf:if>
</div>
</xf:macro>
<xf:macro id="nav_link" arg-navId="!" arg-nav="!" arg-class="" arg-titleHtml="" arg-shortcut="{{ false }}">
<xf:set var="$tag" value="{{ $nav.href ? 'a' : 'span' }}" />
<{$tag} {{ $nav.href ? 'href="' . $nav.href . '"' : '' }}
class="{{ trim($class) }} {$nav.attributes.class}"
{{ attributes($nav.attributes, ['class']) }}
{{ $shortcut !== false ? 'data-xf-key="' . $shortcut . '"' : '' }}
data-nav-id="{$navId}"><xf:if is="$nav.icon"><xf:fa icon="{$nav.icon}" /> </xf:if>{{ $titleHtml ? $titleHtml|raw : $nav.title }}<xf:if is="$nav.counter"> <span class="badge badge--highlighted">{$nav.counter|number}</span></xf:if></{$tag}>
</xf:macro>
<xf:macro id="nav_menu_entry" arg-navId="!" arg-nav="!" arg-depth="0">
<xf:macro id="nav_link"
arg-navId="{$navId}"
arg-nav="{$nav}"
arg-class="menu-linkRow u-indentDepth{$depth} js-offCanvasCopy" />
<xf:if is="$nav.children">
<xf:foreach loop="$nav.children" key="$childNavId" value="$child">
<xf:macro id="nav_menu_entry"
arg-navId="{$childNavId}"
arg-nav="{$child}"
arg-depth="{{ $depth + 1 }}" />
</xf:foreach>
<xf:if is="$depth == 0">
<hr class="menu-separator" />
</xf:if>
</xf:if>
</xf:macro>
<xf:macro id="breadcrumbs" arg-breadcrumbs="!" arg-navTree="!" arg-selectedNavEntry="{{ null }}" arg-variant="">
<xf:if contentcheck="true">
<ul class="p-breadcrumbs {{ $variant ? 'p-breadcrumbs--' . $variant : '' }}"
itemscope itemtype="https://schema.org/BreadcrumbList">
<xf:contentcheck>
<xf:set var="$position" value="{{ 0 }}" />
<xf:set var="$rootBreadcrumb" value="{$navTree.{$xf.options.rootBreadcrumb}}" />
<xf:set var="$rootBreadcrumbHref" value="{{ $rootBreadcrumb.href|substr(-1) == '/'
? $rootBreadcrumb.href
: $rootBreadcrumb.href . '/'
}}" />
<xf:if is="$rootBreadcrumb AND $rootBreadcrumbHref != $xf.uri AND $rootBreadcrumbHref != $xf.fullUri">
<xf:set var="$position" value="{{ $position + 1 }}" />
<xf:macro id="crumb"
arg-position="{$position}"
arg-href="{$rootBreadcrumb.href}"
arg-value="{$rootBreadcrumb.title}" />
</xf:if>
<xf:if is="$selectedNavEntry AND $selectedNavEntry.href AND $selectedNavEntry.href != $xf.uri AND $selectedNavEntry.href != $xf.fullUri AND $selectedNavEntry.href != $rootBreadcrumbHref">
<xf:set var="$position" value="{{ $position + 1 }}" />
<xf:macro id="crumb"
arg-position="{$position}"
arg-href="{$selectedNavEntry.href}"
arg-value="{$selectedNavEntry.title}" />
</xf:if>
<xf:foreach loop="$breadcrumbs" value="$breadcrumb" if="$breadcrumb.href != $xf.uri AND $breadcrumb.href != $xf.fullUri">
<xf:set var="$position" value="{{ $position + 1 }}" />
<xf:macro id="crumb"
arg-position="{$position}"
arg-href="{$breadcrumb.href}"
arg-value="{$breadcrumb.value}" />
</xf:foreach>
</xf:contentcheck>
</ul>
</xf:if>
</xf:macro>
<xf:macro id="crumb" arg-href="!" arg-value="!" arg-position="{{ 0 }}">
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href="{$href}" itemprop="item">
<span itemprop="name">{$value}</span>
</a>
<xf:if is="$position"><meta itemprop="position" content="{$position}" /></xf:if>
</li>
</xf:macro>

View File

@@ -0,0 +1,10 @@
<xf:if is="$alerts is not empty">
<xf:foreach loop="$alerts" value="$alert">
<xf:macro id="alert_macros::row_rhpz" arg-alert="{$alert}" />
</xf:foreach>
<xf:else />
<div class="$notifications-empty">
<i data-lucide="bell-off" size="24"></i>
<span>No new notifications.</span>
</div>
</xf:if>

View File

@@ -0,0 +1,37 @@
<xf:macro id="row" arg-alert="!">
<div class="contentRow">
<div class="contentRow-figure">
<xf:avatar user="$alert.User" size="xxs" defaultname="{$alert.username}" />
</div>
<div class="contentRow-main contentRow-main--close">
{$alert.render()|raw}
<div class="contentRow-minor contentRow-minor--smaller">
<xf:date time="$alert.event_date" />
<span class="u-pullRight">
<a href="{{ link('account/alert-toggle', null, {'alert_id': $alert.alert_id}) }}"
data-xf-init="tooltip" data-content="{{ $alert.isUnreadInUi() ? phrase('mark_read')|for_attr : phrase('mark_unread')|for_attr }}"
data-read="{{ phrase('mark_read')|for_attr }}" data-unread="{{ phrase('mark_unread')|for_attr }}"
class="js-alertToggle alertToggler"><xf:trim>
<i class="alertToggler-icon"></i>
</xf:trim></a>
</span>
</div>
</div>
</div>
</xf:macro>
<xf:macro id="row_rhpz" arg-alert="!">
<div class="$notifications-item {{ $alert.isUnreadInUi() ? '$unread' : '' }}">
<div class="$notifications-avatar">
<xf:avatar user="$alert.User" size="xxs" defaultname="{$alert.username}" />
</div>
<div class="$notifications-content">
<span class="$notifications-text">{$alert.render()|raw}</span>
<span class="$notifications-date"><xf:date time="$alert.event_date" /></span>
</div>
<xf:if is="$alert.isUnreadInUi()">
<div class="$notifications-unread-dot"></div>
</xf:if>
</div>
</xf:macro>

2083
templates/public/extra.less Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
<xf:css src="member_tooltip.less" />
<div class="tooltip-content-inner">
<div class="memberTooltip {{ $user.Profile.banner_date ? 'memberTooltip--withBanner' : '' }}">
<xf:profilebanner user="$user" size="m" class="memberTooltip-header" toggle="memberTooltip--withBanner">
<span class="memberTooltip-avatar">
<xf:avatar user="{$user}" size="m" notooltip="true" />
</span>
<div class="memberTooltip-headerInfo">
<xf:if contentcheck="true">
<div class="memberTooltip-headerAction">
<xf:contentcheck>
<!--[XF:header_action_start]-->
<xf:if contentcheck="true">
<xf:button class="button--link button--small menuTrigger"
data-xf-click="menu"
aria-label="{{ phrase('more_options') }}"
aria-expanded="false"
aria-haspopup="true">
<xf:fa icon="fa-cog" />
</xf:button>
<div class="menu" data-menu="menu" aria-hidden="true">
<div class="menu-content">
<h3 class="menu-header">{{ phrase('moderator_tools') }}</h3>
<xf:contentcheck>
<xf:macro id="member_macros::moderator_menu_actions"
arg-user="{$user}"
arg-context="tooltip" />
</xf:contentcheck>
</div>
</div>
</xf:if>
<!--[XF:header_action_end]-->
</xf:contentcheck>
</div>
</xf:if>
<h4 class="memberTooltip-name">
<span class="memberTooltip-nameWrapper">
<xf:username user="$user" rich="true" notooltip="true" />
</span>
<xf:if is="$user.hasViewableUsernameHistory()">
<a class="memberTooltip-nameChangeIndicator"
data-xf-click="menu"
data-xf-init="tooltip"
title="{{ phrase('username_changed')|for_attr }}"
role="button"
tabindex="0"
aria-expanded="false"
aria-haspopup="true"
aria-label="{{ phrase('username_changed')|for_attr }}"><xf:fa icon="fa-history" /></a>
<div class="menu" data-menu="menu" aria-hidden="true"
data-href="{{ link('members/username-history', $user, {'menu': 1}) }}"
data-load-target=".js-usernameHistoryBody">
<div class="menu-content">
<h3 class="menu-header">{{ phrase('previous_usernames') }}</h3>
<div class="js-usernameHistoryBody">
<div class="menu-row">
{{ phrase('loading...') }}
</div>
</div>
</div>
</div>
</xf:if>
</h4>
<xf:if contentcheck="true">
<div class="memberTooltip-banners">
<xf:contentcheck><xf:userbanners user="$user" /></xf:contentcheck>
</div>
</xf:if>
<div class="memberTooltip-blurbContainer">
<xf:if contentcheck="true">
<div class="memberTooltip-blurb">
<xf:contentcheck>
<xf:userblurb user="$user" tag="div" />
</xf:contentcheck>
</div>
</xf:if>
<div class="memberTooltip-blurb">
<dl class="pairs pairs--inline">
<dt>{{ phrase('joined') }}</dt>
<dd><xf:date time="$user.register_date" /></dd>
</dl>
</div>
<xf:if contentcheck="true">
<div class="memberTooltip-blurb">
<dl class="pairs pairs--inline">
<dt>{{ phrase('last_seen') }}</dt>
<dd dir="auto">
<xf:contentcheck><xf:useractivity user="$user" class="pairs--plainLabel" /></xf:contentcheck>
</dd>
</dl>
</div>
</xf:if>
</div>
</div>
</xf:profilebanner>
<div class="memberTooltip-info">
<div class="memberTooltip-stats">
<div class="pairJustifier">
<xf:macro id="member_macros::member_stat_pairs"
arg-user="{$user}"
arg-context="tooltip" />
</div>
</div>
</div>
<xf:if contentcheck="true">
<hr class="memberTooltip-separator" />
<div class="memberTooltip-actions">
<xf:contentcheck>
<xf:macro id="member_macros::member_action_buttons"
arg-user="{$user}"
arg-context="tooltip" />
</xf:contentcheck>
</div>
</xf:if>
</div>
</div>

View File

@@ -0,0 +1,164 @@
@_memberTooltip-padding: @xf-paddingMedium;
@_memberTooltip-avatarSize: @avatar-m;
.memberTooltip-header
{
display: flex;
padding: @_memberTooltip-padding;
.xf-memberTooltipHeader();
}
.memberTooltip-avatar
{
width: (@_memberTooltip-padding * 2 + @_memberTooltip-avatarSize);
}
.memberTooltip-headerInfo
{
flex: 1;
min-width: 0;
}
.memberTooltip-name
{
margin: 0;
margin-top: -.15em;
padding: 0;
font-weight: @xf-fontWeightNormal;
line-height: (@xf-lineHeightDefault * 0.8);
.xf-memberTooltipName();
.m-hiddenLinks();
.memberTooltip-nameChangeIndicator
{
color: @xf-textColorMuted;
font-size: 75%;
&:hover
{
color: @xf-textColorMuted;
}
}
.memberTooltip--withBanner &
{
.xf-memberTooltipNameBanner();
.memberTooltip-nameChangeIndicator
{
color: darken(xf-default(@xf-memberTooltipNameBanner--color, white), 20%);
&:hover
{
color: darken(xf-default(@xf-memberTooltipNameBanner--color, white), 20%);
}
}
}
}
// See XF-197998
@_memberTooltip-textStroke: 0 #000;
.memberTooltip-textStroke()
{
text-shadow:
-1px -1px @_memberTooltip-textStroke,
1px -1px @_memberTooltip-textStroke,
-1px 1px @_memberTooltip-textStroke,
1px 1px @_memberTooltip-textStroke;
}
.memberTooltip--withBanner
{
.memberTooltip-nameWrapper
{
.username:hover
{
text-decoration: none;
}
}
.username
{
.memberTooltip-textStroke();
}
.memberTooltip-nameChangeIndicator .fa-history
{
.memberTooltip-textStroke();
}
}
.memberTooltip-headerAction
{
float: right;
}
.memberTooltip-blurbContainer
{
.memberTooltip--withBanner &
{
.xf-memberTooltipBlurbContainerBanner();
.memberTooltip-blurb
{
&:first-child
{
margin-top: 0;
}
.pairs dt, a
{
color: darken(xf-default(@xf-memberTooltipBlurbContainerBanner--color, white), 20%);
}
}
}
}
.memberTooltip-banners,
.memberTooltip-blurb
{
margin-top: .25em;
}
.memberTooltip-blurb
{
font-size: @xf-fontSizeSmall;
}
.memberTooltip-stats
{
font-size: @xf-fontSizeSmall;
dl.pairs.pairs--rows > dt
{
font-size: @xf-fontSizeSmaller;
}
}
.memberTooltip-info,
.memberTooltip-actions
{
padding: @_memberTooltip-padding;
}
.memberTooltip-separator
{
margin: (@xf-borderSize * -1) @_memberTooltip-padding 0;
border: none;
border-top: @xf-borderSize solid @xf-borderColorLight;
}
@media (max-width: @xf-responsiveNarrow)
{
.memberTooltip-avatar
{
width: (@_memberTooltip-padding * 2 + @_memberTooltip-avatarSize * 2 / 3);
.avatar
{
.m-avatarSize((@_memberTooltip-avatarSize * 2 / 3));
}
}
}

View File

@@ -0,0 +1,3 @@
<style>
svg { fill: none !important; }
</style>

View File

@@ -0,0 +1,6 @@
<script src="https://unpkg.com/lucide@latest"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
lucide.createIcons();
});
</script>

View File

@@ -0,0 +1,78 @@
<xf:set var="$topbarAdminSeparator" value="false" />
<xf:set var="$topbarModSeparator" value="false" />
<div class="$topbar-actions">
<xf:if is="$xf.visitor.is_admin">
<xf:set var="$topbarAdminSeparator" value="true" />
<a href="{{ base_url('admin.php') }}" class="$btn">
<i data-lucide="landmark" size="18"></i>
</a>
<a href="{{ $xf.options.homePageUrl }}/manage" class="$btn">
<i data-lucide="shield-cog" size="18"></i>
</a>
</xf:if>
<xf:if is="$topbarAdminSeparator == true">
<div class="$vertical-separator"></div>
</xf:if>
<xf:if is="$xf.visitor.is_moderator">
<xf:set var="$topbarModSeparator" value="true" />
<a href="#" class="$btn">
<i data-lucide="siren" size="18"></i>
</a>
<a href="{{ link('approval-queue') }}" class="$btn">
<i data-lucide="message-circle-check" size="18"></i>
</a>
<a href="{{ link('reports') }}" class="$btn">
<i data-lucide="triangle-alert" size="18"></i>
</a>
</xf:if>
<xf:if is="$topbarModSeparator == true">
<div class="$vertical-separator"></div>
</xf:if>
<xf:if is="$xf.visitor.user_id">
<a href="#" class="$btn">
<i data-lucide="hard-drive-upload" size="18"></i>
</a>
</xf:if>
<xf:if is="$xf.visitor.user_id">
<!-- Notifications -->
<a href="{{ link('account/alerts') }}" class="$btn js-badge--alerts" data-badge="{$xf.visitor.alerts_unviewed|number}" data-xf-click="menu" data-xf-key="{{ phrase('shortcut.alerts_menu')|for_attr }}" title="" aria-expanded="false"
aria-haspopup="true">
<i data-lucide="bell" size="18"></i>
</a>
<div class="menu menu--structural menu--medium" data-menu="menu" aria-hidden="true"
data-href="{{ link('account/alerts-popup') }}"
data-nocache="true"
data-load-target=".js-alertsMenuBody">
<div class="menu-content">
<div class="$notifications-header">
<span class="$notifications-header-title">Notifications</span>
<div class="$notifications-header-actions">
<a href="{{ link('account/alerts/mark-read') }}" class="$btn js-alertsMarkRead" title="Mark all as read">
<i data-lucide="check-circle" size="14"></i>
</a>
<a href="{{ link('account/alerts') }}" class="$btn">
<i data-lucide="external-link" size="14"></i>
</a>
</div>
</div>
<div class="js-alertsMenuBody">
<div class="notifications-loading">
<i data-lucide="loader-2" class="spin"></i>
</div>
</div>
</div>
</div>
<button class="$btn">
<i data-lucide="mail" size="18"></i>
</button>
</xf:if>
<button class="$btn">
<i data-lucide="settings" size="18"></i>
</button>
</div>