@anas_hameed/edly-saas-widget 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.rst ADDED
@@ -0,0 +1,196 @@
1
+ frontend-template-application
2
+ #############################
3
+
4
+ |license-badge| |status-badge| |ci-badge| |codecov-badge|
5
+
6
+
7
+ Purpose
8
+ *******
9
+
10
+ This repository is a template for Open edX micro-frontend applications. It is
11
+ flagged as a Template Repository, meaning it can be used as a basis for new
12
+ GitHub repositories by clicking the green "Use this template" button above.
13
+ The rest of this document describes how to work with your new micro-frontend
14
+ **after you've created a new repository from the template.**
15
+
16
+ Getting Started
17
+ ***************
18
+
19
+ After copying the template repository, you'll want to do a find-and-replace to
20
+ replace all instances of ``frontend-template-application`` with the name of
21
+ your new repository. Also edit index.html to replace "Application Template"
22
+ with a friendly name for this application that users will see in their browser
23
+ tab.
24
+
25
+ Prerequisites
26
+ =============
27
+
28
+ The `devstack`_ is currently recommended as a development environment for your
29
+ new MFE. If you start it with ``make dev.up.lms`` that should give you
30
+ everything you need as a companion to this frontend.
31
+
32
+ Note that it is also possible to use `Tutor`_ to develop an MFE. You can refer
33
+ to the `relevant tutor-mfe documentation`_ to get started using it.
34
+
35
+ .. _Devstack: https://github.com/openedx/devstack
36
+
37
+ .. _Tutor: https://github.com/overhangio/tutor
38
+
39
+ .. _relevant tutor-mfe documentation: https://github.com/overhangio/tutor-mfe#mfe-development
40
+
41
+ Cloning and Startup
42
+ ===================
43
+
44
+ In the following steps, replace "[PLACEHOLDER]" with the name of the repo you
45
+ created when copying this template above.
46
+
47
+ 1. Clone your new repo:
48
+
49
+ ``git clone https://github.com/openedx/frontend-app-[PLACEHOLDER].git``
50
+
51
+ 2. Use node v18.x.
52
+
53
+ The current version of the micro-frontend build scripts support node 18.
54
+ Using other major versions of node *may* work, but this is unsupported. For
55
+ convenience, this repository includes an .nvmrc file to help in setting the
56
+ correct node version via `nvm <https://github.com/nvm-sh/nvm>`_.
57
+
58
+ 3. Install npm dependencies:
59
+
60
+ ``cd frontend-app-[PLACEHOLDER] && npm install``
61
+
62
+ 4. Update the application port to use for local development:
63
+
64
+ Default port is 8080. If this does not work for you, update the line
65
+ `PORT=8080` to your port in all .env.* files
66
+
67
+ 5. Start the dev server:
68
+
69
+ ``npm start``
70
+
71
+ The dev server is running at `http://localhost:8080 <http://localhost:8080>`_
72
+ or whatever port you setup.
73
+
74
+ Making Your New Project's README File
75
+ =====================================
76
+
77
+ Move ``README-template-frontend-app.rst`` to your project's ``README.rst``
78
+ file. Please fill out all the sections - this helps out all developers
79
+ understand your MFE, how to install it, and how to use it.
80
+
81
+ Developing
82
+ **********
83
+
84
+ This section concerns development of ``frontend-template-application`` itself,
85
+ not the templated copy.
86
+
87
+ It should be noted that one of the goals of this repository is for it to
88
+ function correctly as an MFE (as in ``npm install && npm start``) even if no
89
+ modifications are made. This ensures that developers get a *practical* working
90
+ example, not just a theoretical one.
91
+
92
+ This also means, of course, that any committed code should be tested and
93
+ subject to both CI and branch protection rules.
94
+
95
+ Project Structure
96
+ =================
97
+
98
+ The source for this project is organized into nested submodules according to
99
+ the `Feature-based Application Organization ADR`_.
100
+
101
+ .. _Feature-based Application Organization ADR: https://github.com/openedx/frontend-template-application/blob/master/docs/decisions/0002-feature-based-application-organization.rst
102
+
103
+ Build Process Notes
104
+ ===================
105
+
106
+ **Production Build**
107
+
108
+ The production build is created with ``npm run build``.
109
+
110
+ Internationalization
111
+ ====================
112
+
113
+ Please see refer to the `frontend-platform i18n howto`_ for documentation on
114
+ internationalization.
115
+
116
+ .. _frontend-platform i18n howto: https://github.com/openedx/frontend-platform/blob/master/docs/how_tos/i18n.rst
117
+
118
+ Getting Help
119
+ ************
120
+
121
+ If you're having trouble, we have discussion forums at
122
+ https://discuss.openedx.org where you can connect with others in the community.
123
+
124
+ Our real-time conversations are on Slack. You can request a `Slack
125
+ invitation`_, then join our `community Slack workspace`_. Because this is a
126
+ frontend repository, the best place to discuss it would be in the `#wg-frontend
127
+ channel`_.
128
+
129
+ For anything non-trivial, the best path is to open an issue in this repository
130
+ with as many details about the issue you are facing as you can provide.
131
+
132
+ https://github.com/openedx/frontend-template-application/issues
133
+
134
+ For more information about these options, see the `Getting Help`_ page.
135
+
136
+ .. _Slack invitation: https://openedx.org/slack
137
+ .. _community Slack workspace: https://openedx.slack.com/
138
+ .. _#wg-frontend channel: https://openedx.slack.com/archives/C04BM6YC7A6
139
+ .. _Getting Help: https://openedx.org/getting-help
140
+
141
+ License
142
+ *******
143
+
144
+ The code in this repository is licensed under the AGPLv3 unless otherwise
145
+ noted.
146
+
147
+ Please see `LICENSE <LICENSE>`_ for details.
148
+
149
+ Contributing
150
+ ************
151
+
152
+ Contributions are very welcome. Please read `How To Contribute`_ for details.
153
+
154
+ .. _How To Contribute: https://openedx.org/r/how-to-contribute
155
+
156
+ This project is currently accepting all types of contributions, bug fixes,
157
+ security fixes, maintenance work, or new features. However, please make sure
158
+ to have a discussion about your new feature idea with the maintainers prior to
159
+ beginning development to maximize the chances of your change being accepted.
160
+ You can start a conversation by creating a new issue on this repo summarizing
161
+ your idea.
162
+
163
+ The Open edX Code of Conduct
164
+ ****************************
165
+
166
+ All community members are expected to follow the `Open edX Code of Conduct`_.
167
+
168
+ .. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/
169
+
170
+ People
171
+ ******
172
+
173
+ The assigned maintainers for this component and other project details may be
174
+ found in `Backstage`_. Backstage pulls this data from the ``catalog-info.yaml``
175
+ file in this repo.
176
+
177
+ .. _Backstage: https://open-edx-backstage.herokuapp.com/catalog/default/component/frontend-template-application
178
+
179
+ Reporting Security Issues
180
+ *************************
181
+
182
+ Please do not report security issues in public, and email security@openedx.org instead.
183
+
184
+ .. |license-badge| image:: https://img.shields.io/github/license/openedx/frontend-template-application.svg
185
+ :target: https://github.com/openedx/frontend-template-application/blob/main/LICENSE
186
+ :alt: License
187
+
188
+ .. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen
189
+
190
+ .. |ci-badge| image:: https://github.com/openedx/frontend-template-application/actions/workflows/ci.yml/badge.svg
191
+ :target: https://github.com/openedx/frontend-template-application/actions/workflows/ci.yml
192
+ :alt: Continuous Integration
193
+
194
+ .. |codecov-badge| image:: https://codecov.io/github/openedx/frontend-template-application/coverage.svg?branch=main
195
+ :target: https://codecov.io/github/openedx/frontend-template-application?branch=main
196
+ :alt: Codecov
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _frontendPlatform = require("@edx/frontend-platform");
8
+ var _react = require("react");
9
+ require("./main.css");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ const HeaderWidget = () => {
12
+ const [headerData, setHeaderData] = (0, _react.useState)("");
13
+ const [isOpen, setIsOpen] = (0, _react.useState)(false);
14
+ const WIDTH = 1230;
15
+ const [isMobile, setIsMobile] = (0, _react.useState)(window.innerWidth < WIDTH);
16
+ const [isLoading, setIsLoading] = (0, _react.useState)(true);
17
+ const config = (0, _frontendPlatform.getConfig)();
18
+ (0, _react.useEffect)(() => {
19
+ const handleResize = () => {
20
+ setIsMobile(window.innerWidth < WIDTH);
21
+ if (window.innerWidth >= WIDTH) {
22
+ setIsOpen(false);
23
+ }
24
+ };
25
+ window.addEventListener("resize", handleResize);
26
+ return () => window.removeEventListener("resize", handleResize);
27
+ }, []);
28
+ (0, _react.useEffect)(() => {
29
+ const fetchData = async () => {
30
+ if (!config?.DISCOVERY_URL) {
31
+ console.error("No url found for discovery", config);
32
+ return;
33
+ }
34
+ try {
35
+ const response = await fetch(config.DISCOVERY_URL);
36
+ if (!response.ok) {
37
+ throw new Error(`HTTP error! status: ${response.status}`);
38
+ }
39
+ const jsonData = await response.json();
40
+
41
+ // Handle potential data structures (object)
42
+ if (typeof jsonData === "object") {
43
+ setHeaderData(jsonData.primary);
44
+ } else {
45
+ console.error("Data object is not json");
46
+ }
47
+ } catch (error) {
48
+ console.error(error);
49
+ } finally {
50
+ setIsLoading(false);
51
+ }
52
+ };
53
+ fetchData();
54
+ }, []);
55
+ const toggleMenu = () => {
56
+ setIsOpen(!isOpen);
57
+ };
58
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
59
+ className: `shadow-lg ${isMobile ? "header-frame" : ""}`,
60
+ children: [isMobile && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
61
+ className: "menuOpner",
62
+ onClick: toggleMenu,
63
+ style: {
64
+ background: "none",
65
+ border: "none",
66
+ cursor: "pointer",
67
+ fontSize: "24px"
68
+ },
69
+ children: isOpen ? "✖" : "☰"
70
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
71
+ className: `header-holder ${isMobile ? "mobile-menu" : ""} ${isOpen ? "" : "mobile-hide"}`,
72
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
73
+ href: "/",
74
+ className: "custom-logo-link",
75
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
76
+ width: "216",
77
+ height: "140",
78
+ src: config.LOGO_URL,
79
+ className: "custom-logo",
80
+ alt: "Venus",
81
+ decoding: "async"
82
+ })
83
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("header", {
84
+ className: "site-header",
85
+ dangerouslySetInnerHTML: {
86
+ __html: headerData
87
+ }
88
+ })]
89
+ })]
90
+ });
91
+ };
92
+ var _default = exports.default = HeaderWidget;
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_frontendPlatform","require","_react","_jsxRuntime","HeaderWidget","headerData","setHeaderData","useState","isOpen","setIsOpen","WIDTH","isMobile","setIsMobile","window","innerWidth","isLoading","setIsLoading","config","getConfig","useEffect","handleResize","addEventListener","removeEventListener","fetchData","DISCOVERY_URL","console","error","response","fetch","ok","Error","status","jsonData","json","primary","toggleMenu","jsxs","className","children","jsx","onClick","style","background","border","cursor","fontSize","href","width","height","src","LOGO_URL","alt","decoding","dangerouslySetInnerHTML","__html","_default","exports","default"],"sources":["../../src/HeaderWidget/index.js"],"sourcesContent":["import { getConfig } from \"@edx/frontend-platform\";\nimport { useEffect, useState } from \"react\";\nimport \"./main.css\";\n\nconst HeaderWidget = () => {\n const [headerData, setHeaderData] = useState(\"\");\n const [isOpen, setIsOpen] = useState(false);\n const WIDTH = 1230;\n const [isMobile, setIsMobile] = useState(window.innerWidth < WIDTH);\n const [isLoading, setIsLoading] = useState(true);\n const config = getConfig();\n\n useEffect(() => {\n const handleResize = () => {\n setIsMobile(window.innerWidth < WIDTH);\n if (window.innerWidth >= WIDTH) {\n setIsOpen(false);\n }\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n const fetchData = async () => {\n if (!config?.DISCOVERY_URL) {\n console.error(\"No url found for discovery\", config);\n return;\n }\n try {\n const response = await fetch(config.DISCOVERY_URL);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const jsonData = await response.json();\n\n // Handle potential data structures (object)\n if (typeof jsonData === \"object\") {\n setHeaderData(jsonData.primary);\n } else {\n console.error(\"Data object is not json\");\n }\n } catch (error) {\n console.error(error);\n } finally {\n setIsLoading(false);\n }\n };\n\n fetchData();\n }, []);\n\n const toggleMenu = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div className={`shadow-lg ${isMobile ? \"header-frame\" : \"\"}`}>\n {isMobile && (\n <button\n className=\"menuOpner\"\n onClick={toggleMenu}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: \"24px\",\n }}\n >\n {isOpen ? \"✖\" : \"☰\"}\n </button>\n )}\n <div\n className={`header-holder ${isMobile ? \"mobile-menu\" : \"\"} ${\n isOpen ? \"\" : \"mobile-hide\"\n }`}\n >\n <a href=\"/\" className=\"custom-logo-link\">\n <img\n width=\"216\"\n height=\"140\"\n src={config.LOGO_URL}\n className=\"custom-logo\"\n alt=\"Venus\"\n decoding=\"async\"\n />\n </a>\n <header\n className=\"site-header\"\n dangerouslySetInnerHTML={{ __html: headerData }}\n />\n </div>\n </div>\n );\n};\n\nexport default HeaderWidget;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,289 @@
1
+ @charset "UTF-8";
2
+ /* Header and logo */
3
+ .header-holder {
4
+ padding: 15px 20px 14px;
5
+ display: flex;
6
+ align-items: center;
7
+ flex-direction: row;
8
+ }
9
+
10
+ .site-header {
11
+ width: 100%;
12
+ flex: inherit !important;
13
+ }
14
+
15
+ .custom-logo-link img {
16
+ margin: auto;
17
+ max-width: 200px;
18
+ max-height: 70px;
19
+ height: auto;
20
+ width: auto;
21
+ }
22
+
23
+ /* Desktop Menu */
24
+ #menu-primary-menu {
25
+ display: flex;
26
+ align-items: center;
27
+ list-style: none;
28
+ margin: 0;
29
+ padding: 0;
30
+ }
31
+ #menu-primary-menu > li {
32
+ position: relative;
33
+ padding: 10px;
34
+ }
35
+ #menu-primary-menu > li a {
36
+ color: #0d1321;
37
+ text-decoration: none;
38
+ font-weight: 600;
39
+ display: block;
40
+ border-bottom: 1px solid transparent;
41
+ transition: color 0.25s ease, border-color 0.25s ease;
42
+ position: relative;
43
+ display: block;
44
+ padding-bottom: 0px;
45
+ border: 0px;
46
+ text-decoration: none;
47
+ }
48
+ #menu-primary-menu > li a:before {
49
+ content: "";
50
+ background-color: #de2025;
51
+ width: auto;
52
+ height: 1px;
53
+ position: absolute;
54
+ bottom: -5px;
55
+ left: 0;
56
+ right: 0;
57
+ opacity: 0;
58
+ }
59
+ #menu-primary-menu > li:hover > a, #menu-primary-menu > li.menu-active > a {
60
+ color: #de2025;
61
+ }
62
+ @media (min-width: 1231px) {
63
+ #menu-primary-menu > li:hover > a:before, #menu-primary-menu > li.menu-active > a:before {
64
+ opacity: 1;
65
+ }
66
+ }
67
+ #menu-primary-menu > li.menu-item-has-children > a::after, #menu-primary-menu > li.menu-item-object-custom_link_filter > a::after, #menu-primary-menu > li.submenu-item-class > a::after {
68
+ content: "›";
69
+ font-size: 0.95em;
70
+ margin-left: 0.4em;
71
+ display: inline-block;
72
+ transform: rotate(90deg);
73
+ transition: transform 0.25s ease;
74
+ }
75
+ #menu-primary-menu > li:hover > a::after {
76
+ transform: rotate(90deg) translateX(2px);
77
+ }
78
+ #menu-primary-menu > li > .sub-menu {
79
+ display: none;
80
+ position: absolute;
81
+ top: 100%;
82
+ left: 0;
83
+ background: #ffffff;
84
+ border: 1px solid #d1d5db;
85
+ border-radius: 6px;
86
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
87
+ list-style: none;
88
+ min-width: 230px;
89
+ padding: 0.5rem 0;
90
+ z-index: 10;
91
+ }
92
+ #menu-primary-menu > li > .sub-menu > li {
93
+ position: relative;
94
+ list-style: none;
95
+ }
96
+ #menu-primary-menu > li > .sub-menu > li a {
97
+ display: block;
98
+ padding: 0.6rem 1rem;
99
+ color: #0d1321;
100
+ transition: background 0.25s ease, color 0.25s ease;
101
+ }
102
+ #menu-primary-menu > li > .sub-menu > li a:hover {
103
+ background: rgb(251.6614173228, 231.8385826772, 232.3602362205);
104
+ color: #de2025;
105
+ }
106
+ @media (max-width: 1230px) {
107
+ #menu-primary-menu > li > .sub-menu > li a:hover {
108
+ background: transparent;
109
+ }
110
+ }
111
+ #menu-primary-menu > li > .sub-menu > li.submenu-item-class > a::after {
112
+ content: "›";
113
+ float: right;
114
+ font-size: 0.95em;
115
+ }
116
+ #menu-primary-menu > li > .sub-menu > li .sub-menu {
117
+ display: none;
118
+ position: absolute;
119
+ top: -5px;
120
+ left: 94%;
121
+ margin-left: 0.5rem;
122
+ border: 1px solid #d1d5db;
123
+ border-radius: 6px;
124
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
125
+ background: #ffffff;
126
+ min-width: 200px;
127
+ padding: 0.5rem 0;
128
+ list-style: none;
129
+ }
130
+ #menu-primary-menu > li > .sub-menu > li:hover > .sub-menu {
131
+ display: block;
132
+ }
133
+ #menu-primary-menu > li:hover > .sub-menu {
134
+ display: block;
135
+ }
136
+
137
+ .mobile-menu .site-header {
138
+ background: white;
139
+ flex: inherit;
140
+ position: absolute;
141
+ top: 100px;
142
+ left: 0;
143
+ box-sizing: border-box;
144
+ }
145
+ .mobile-menu .site-header #menu-primary-menu {
146
+ flex-direction: column;
147
+ text-align: left;
148
+ }
149
+ .mobile-menu .site-header {
150
+ opacity: 1;
151
+ visibility: visible;
152
+ max-height: 4000px;
153
+ transition: all 0.3s ease;
154
+ max-height: 200px;
155
+ overflow-y: auto;
156
+ overflow-x: hidden;
157
+ }
158
+ .mobile-menu.mobile-hide .site-header {
159
+ opacity: 0;
160
+ visibility: hidden;
161
+ max-height: 0;
162
+ }
163
+
164
+ .menuOpner {
165
+ position: absolute;
166
+ top: 50%;
167
+ right: 20px;
168
+ transform: translateY(-50%);
169
+ }
170
+
171
+ .header-frame {
172
+ z-index: 9;
173
+ position: relative;
174
+ }
175
+
176
+ /* Desktop: Keep Sign In button on the right */
177
+ @media (min-width: 1231px) {
178
+ #menu-primary-menu {
179
+ display: flex;
180
+ justify-content: flex-start;
181
+ align-items: center;
182
+ }
183
+ #menu-primary-menu > li.menu-item-object-signin_openedx {
184
+ margin-left: auto;
185
+ order: 999;
186
+ padding-right: 10px !important;
187
+ }
188
+ #menu-primary-menu > li.menu-item-object-signin_openedx a {
189
+ color: #fff;
190
+ background: #de2025;
191
+ padding: 8px 16px;
192
+ border-radius: 6px;
193
+ }
194
+ #menu-primary-menu > li.menu-item-object-signin_openedx a:before {
195
+ display: none;
196
+ }
197
+ }
198
+ /* Mobile Menu */
199
+ @media (max-width: 1230px) {
200
+ .custom-logo-link img {
201
+ max-width: 160px;
202
+ max-height: 50px;
203
+ }
204
+ .mobile-menu .site-header {
205
+ top: 70px;
206
+ padding: 0 30px;
207
+ }
208
+ #menu-primary-menu > li {
209
+ display: block;
210
+ width: 100%;
211
+ border-top: 1px solid #ccc;
212
+ }
213
+ #menu-primary-menu > li:first-child {
214
+ border-top: none;
215
+ }
216
+ #menu-primary-menu > li > .sub-menu {
217
+ position: static;
218
+ display: block;
219
+ padding: 0 0 0 10px;
220
+ border-radius: 0;
221
+ border: 0;
222
+ box-shadow: none;
223
+ }
224
+ #menu-primary-menu > li > .sub-menu li a {
225
+ font-size: 12px;
226
+ }
227
+ #menu-primary-menu > li > .sub-menu > li .sub-menu {
228
+ position: static;
229
+ display: block;
230
+ padding: 0 0 0 20px;
231
+ border-radius: 0;
232
+ border: 0;
233
+ box-shadow: none;
234
+ }
235
+ .main-navigation .menu-toggle {
236
+ display: flex;
237
+ }
238
+ .main-navigation #menu-primary-menu {
239
+ flex-direction: column;
240
+ width: 100%;
241
+ background: #ffffff;
242
+ position: absolute;
243
+ top: 100%;
244
+ left: 0;
245
+ padding: 1rem 0;
246
+ display: none;
247
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
248
+ border-top: 1px solid #d1d5db;
249
+ }
250
+ .main-navigation #menu-primary-menu.open {
251
+ display: flex;
252
+ }
253
+ .main-navigation #menu-primary-menu > li {
254
+ width: 100%;
255
+ padding: 0.75rem 1rem;
256
+ border-bottom: 1px solid #d1d5db;
257
+ }
258
+ .main-navigation #menu-primary-menu > li a {
259
+ display: flex;
260
+ justify-content: space-between;
261
+ align-items: center;
262
+ }
263
+ .main-navigation #menu-primary-menu > li .sub-menu {
264
+ position: relative;
265
+ top: 0;
266
+ left: 0;
267
+ margin: 0;
268
+ border: none;
269
+ border-radius: 0;
270
+ box-shadow: none;
271
+ background: #ffffff;
272
+ padding-left: 1rem;
273
+ display: none;
274
+ list-style: none;
275
+ }
276
+ .main-navigation #menu-primary-menu > li .sub-menu li a {
277
+ padding: 0.5rem 1rem;
278
+ transition: background 0.25s ease, color 0.25s ease;
279
+ }
280
+ .main-navigation #menu-primary-menu > li .sub-menu li a:hover {
281
+ background: rgb(251.6614173228, 231.8385826772, 232.3602362205);
282
+ color: #de2025;
283
+ }
284
+ .main-navigation #menu-primary-menu > li:hover > .sub-menu {
285
+ display: block;
286
+ }
287
+ }
288
+
289
+ /*# sourceMappingURL=main.css.map */