From a3fa2d410708bdcd1a87b21c14f3e8286e7547e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 7 Jan 2022 18:10:45 +0100 Subject: [PATCH] Replace the Material theme by DiscordFX --- configuration/authorization-storage.md | 12 +- configuration/claim-destinations.md | 3 +- .../encryption-and-signing-credentials.md | 22 +- configuration/mongodb-integration.md | 33 +- configuration/proof-key-for-code-exchange.md | 3 +- docfx.json | 2 +- guide/getting-started.md | 15 +- templates/discordfx/layout/_master.tmpl | 68 ++ .../discordfx/partials/footer.tmpl.partial | 4 + .../partials/head.tmpl.partial | 11 +- templates/discordfx/partials/li.tmpl.partial | 31 + .../discordfx/partials/logo.tmpl.partial | 6 + .../discordfx/partials/navbar.tmpl.partial | 13 + .../discordfx/partials/scripts.tmpl.partial | 11 + templates/discordfx/partials/toc.tmpl.partial | 5 + templates/discordfx/styles/colors.css | 73 ++ templates/discordfx/styles/discord.css | 681 ++++++++++++++++++ templates/discordfx/styles/down-arrow.svg | 44 ++ .../discordfx/styles/jquery.twbsPagination.js | 317 ++++++++ templates/discordfx/styles/main.css | 0 templates/discordfx/styles/main.js | 20 + templates/discordfx/styles/url.min.js | 1 + templates/material/partials/logo.tmpl.partial | 5 - templates/material/styles/main.css | 306 -------- 24 files changed, 1310 insertions(+), 376 deletions(-) create mode 100644 templates/discordfx/layout/_master.tmpl create mode 100644 templates/discordfx/partials/footer.tmpl.partial rename templates/{material => discordfx}/partials/head.tmpl.partial (68%) create mode 100644 templates/discordfx/partials/li.tmpl.partial create mode 100644 templates/discordfx/partials/logo.tmpl.partial create mode 100644 templates/discordfx/partials/navbar.tmpl.partial create mode 100644 templates/discordfx/partials/scripts.tmpl.partial create mode 100644 templates/discordfx/partials/toc.tmpl.partial create mode 100644 templates/discordfx/styles/colors.css create mode 100644 templates/discordfx/styles/discord.css create mode 100644 templates/discordfx/styles/down-arrow.svg create mode 100644 templates/discordfx/styles/jquery.twbsPagination.js create mode 100644 templates/discordfx/styles/main.css create mode 100644 templates/discordfx/styles/main.js create mode 100644 templates/discordfx/styles/url.min.js delete mode 100644 templates/material/partials/logo.tmpl.partial delete mode 100644 templates/material/styles/main.css diff --git a/configuration/authorization-storage.md b/configuration/authorization-storage.md index 84a2713..1166294 100644 --- a/configuration/authorization-storage.md +++ b/configuration/authorization-storage.md @@ -37,8 +37,7 @@ switch (await _applicationManager.GetConsentTypeAsync(application)) authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = - Errors.ConsentRequired, + [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The logged in user is not allowed to access this client application." })); @@ -47,16 +46,14 @@ switch (await _applicationManager.GetConsentTypeAsync(application)) // return an authorization response without displaying the consent form. case ConsentTypes.Implicit: case ConsentTypes.External when authorizations.Any(): - case ConsentTypes.Explicit when authorizations.Any() && - !request.HasPrompt(Prompts.Consent): + case ConsentTypes.Explicit when authorizations.Any() && !request.HasPrompt(Prompts.Consent): var principal = await _signInManager.CreateUserPrincipalAsync(user); // Note: in this sample, the granted scopes match the requested scope // but you may want to allow the user to uncheck specific scopes. // For that, simply restrict the list of scopes before calling SetScopes. principal.SetScopes(request.GetScopes()); - principal.SetResources(await _scopeManager.ListResourcesAsync( - principal.GetScopes()).ToListAsync()); + principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); // Automatically create a permanent authorization to avoid requiring explicit consent // for future authorization or token requests containing the same scopes. @@ -88,8 +85,7 @@ switch (await _applicationManager.GetConsentTypeAsync(application)) authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = - Errors.ConsentRequired, + [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Interactive user consent is required." })); diff --git a/configuration/claim-destinations.md b/configuration/claim-destinations.md index b00c82a..23564f4 100644 --- a/configuration/claim-destinations.md +++ b/configuration/claim-destinations.md @@ -27,8 +27,7 @@ var principal = await _signInManager.CreateUserPrincipalAsync(user); // but you may want to allow the user to uncheck specific scopes. // For that, simply restrict the list of scopes before calling SetScopes(). principal.SetScopes(request.GetScopes()); -principal.SetResources( - await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); +principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); foreach (var claim in principal.Claims) { diff --git a/configuration/encryption-and-signing-credentials.md b/configuration/encryption-and-signing-credentials.md index 34710ef..ac5b6ca 100644 --- a/configuration/encryption-and-signing-credentials.md +++ b/configuration/encryption-and-signing-credentials.md @@ -87,14 +87,10 @@ Certificates can be generated and self-signed locally using the .NET Core `Certi using var algorithm = RSA.Create(keySizeInBits: 2048); var subject = new X500DistinguishedName("CN=Fabrikam Encryption Certificate"); -var request = new CertificateRequest(subject, algorithm, - HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); -request.CertificateExtensions.Add(new X509KeyUsageExtension( - X509KeyUsageFlags.KeyEncipherment, critical: true)); +var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); +request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true)); -var certificate = request.CreateSelfSigned( - DateTimeOffset.UtcNow, - DateTimeOffset.UtcNow.AddYears(2)); +var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); var data = certificate.Export(X509ContentType.Pfx, string.Empty); ``` @@ -103,19 +99,15 @@ var data = certificate.Export(X509ContentType.Pfx, string.Empty); using var algorithm = RSA.Create(keySizeInBits: 2048); var subject = new X500DistinguishedName("CN=Fabrikam Signing Certificate"); -var request = new CertificateRequest(subject, algorithm, - HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); -request.CertificateExtensions.Add(new X509KeyUsageExtension( - X509KeyUsageFlags.DigitalSignature, critical: true)); +var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); +request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true)); -var certificate = request.CreateSelfSigned( - DateTimeOffset.UtcNow, - DateTimeOffset.UtcNow.AddYears(2)); +var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); var data = certificate.Export(X509ContentType.Pfx, string.Empty); ``` -The best place to store your certificates will mostly depend on your host: +The best place to store your certificates will depend on your host: - For IIS applications, storing the certificates in the machine store is the recommended option. - On Azure, certificates can be uploaded and exposed to Azure App Services applications using the special `WEBSITE_LOAD_CERTIFICATES` flag. For more information, visit https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-certificate-in-code diff --git a/configuration/mongodb-integration.md b/configuration/mongodb-integration.md index 55aaa34..13f8f6f 100644 --- a/configuration/mongodb-integration.md +++ b/configuration/mongodb-integration.md @@ -46,47 +46,40 @@ initialize the database and create the indexes used by the OpenIddict entities: services.AddOpenIddict() .AddCore(options => options.UseMongoDb()); - services.AddSingleton(new MongoClient( - "mongodb://localhost:27017").GetDatabase("openiddict")); + services.AddSingleton(new MongoClient("mongodb://localhost:27017").GetDatabase("openiddict")); var provider = services.BuildServiceProvider(); var context = provider.GetRequiredService(); - var options = provider.GetRequiredService< - IOptionsMonitor>().CurrentValue; + var options = provider.GetRequiredService>().CurrentValue; var database = await context.GetDatabaseAsync(CancellationToken.None); - var applications = database.GetCollection( - options.ApplicationsCollectionName); + var applications = database.GetCollection(options.ApplicationsCollectionName); await applications.Indexes.CreateManyAsync(new[] { new CreateIndexModel( - Builders.IndexKeys.Ascending( - application => application.ClientId), + Builders.IndexKeys.Ascending(application => application.ClientId), new CreateIndexOptions { Unique = true }), new CreateIndexModel( - Builders.IndexKeys.Ascending( - application => application.PostLogoutRedirectUris), + Builders.IndexKeys.Ascending(application => application.PostLogoutRedirectUris), new CreateIndexOptions { Background = true }), new CreateIndexModel( - Builders.IndexKeys.Ascending( - application => application.RedirectUris), + Builders.IndexKeys.Ascending(application => application.RedirectUris), new CreateIndexOptions { Background = true }) }); - var authorizations = database.GetCollection( - options.AuthorizationsCollectionName); + var authorizations = database.GetCollection(options.AuthorizationsCollectionName); await authorizations.Indexes.CreateOneAsync( new CreateIndexModel( @@ -101,8 +94,7 @@ initialize the database and create the indexes used by the OpenIddict entities: Background = true })); - var scopes = database.GetCollection( - options.ScopesCollectionName); + var scopes = database.GetCollection(options.ScopesCollectionName); await scopes.Indexes.CreateOneAsync(new CreateIndexModel( Builders.IndexKeys.Ascending(scope => scope.Name), @@ -111,21 +103,18 @@ initialize the database and create the indexes used by the OpenIddict entities: Unique = true })); - var tokens = database.GetCollection( - options.TokensCollectionName); + var tokens = database.GetCollection(options.TokensCollectionName); await tokens.Indexes.CreateManyAsync(new[] { new CreateIndexModel( - Builders.IndexKeys.Ascending( - token => token.ReferenceId), + Builders.IndexKeys.Ascending(token => token.ReferenceId), new CreateIndexOptions { // Note: partial filter expressions are not supported on Azure Cosmos DB. // As a workaround, the expression and the unique constraint can be removed. PartialFilterExpression = - Builders.Filter.Exists( - token => token.ReferenceId), + Builders.Filter.Exists(token => token.ReferenceId), Unique = true }), diff --git a/configuration/proof-key-for-code-exchange.md b/configuration/proof-key-for-code-exchange.md index e484b64..d600388 100644 --- a/configuration/proof-key-for-code-exchange.md +++ b/configuration/proof-key-for-code-exchange.md @@ -63,7 +63,6 @@ While not recommended, support for the `code_challenge_method=plain` method can services.AddOpenIddict() .AddServer(options => { - options.Configure(options => options.CodeChallengeMethods.Add( - CodeChallengeMethods.Plain)); + options.Configure(options => options.CodeChallengeMethods.Add(CodeChallengeMethods.Plain)); }); ``` \ No newline at end of file diff --git a/docfx.json b/docfx.json index c98ca43..1a2b948 100644 --- a/docfx.json +++ b/docfx.json @@ -43,7 +43,7 @@ "fileMetadataFiles": [], "template": [ "default", - "templates/material" + "templates/discordfx" ], "postProcessors": [], "noLangKeyword": false, diff --git a/guide/getting-started.md b/guide/getting-started.md index f0bd6d5..ae226ef 100644 --- a/guide/getting-started.md +++ b/guide/getting-started.md @@ -4,7 +4,7 @@ If you don't want to start from one of the recommended samples, you'll need to: - - **Install the [.NET Core 2.1.x, 3.1.x or .NET 5.0.x tooling](https://www.microsoft.com/net/download)**. + - **Install the [.NET Core 3.1 (or later) tooling](https://www.microsoft.com/net/download)**. - **Have an existing project or create a new one**: when creating a new project using Visual Studio's default ASP.NET Core template, using **individual user accounts authentication** is strongly recommended as it automatically includes the default ASP.NET Core Identity UI, based on Razor Pages. @@ -57,11 +57,11 @@ If you don't want to start from one of the recommended samples, you'll need to: // Register the signing and encryption credentials. options.AddDevelopmentEncryptionCertificate() - .AddDevelopmentSigningCertificate(); + .AddDevelopmentSigningCertificate(); // Register the ASP.NET Core host and configure the ASP.NET Core options. options.UseAspNetCore() - .EnableTokenEndpointPassthrough(); + .EnableTokenEndpointPassthrough(); }) // Register the OpenIddict validation components. @@ -97,8 +97,6 @@ If you don't want to start from one of the recommended samples, you'll need to: options.MapControllers(); options.MapDefaultControllerRoute(); }); - - app.UseWelcomePage(); } ``` @@ -164,15 +162,12 @@ If you don't want to start from one of the recommended samples, you'll need to: // Note: the client credentials are automatically validated by OpenIddict: // if client_id or client_secret are invalid, this action won't be invoked. - var application = - await _applicationManager.FindByClientIdAsync(request.ClientId) ?? + var application = await _applicationManager.FindByClientIdAsync(request.ClientId) ?? throw new InvalidOperationException("The application cannot be found."); // Create a new ClaimsIdentity containing the claims that // will be used to create an id_token, a token or a code. - var identity = new ClaimsIdentity( - TokenValidationParameters.DefaultAuthenticationType, - Claims.Name, Claims.Role); + var identity = new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType, Claims.Name, Claims.Role); // Use the client_id as the subject identifier. identity.AddClaim(Claims.Subject, diff --git a/templates/discordfx/layout/_master.tmpl b/templates/discordfx/layout/_master.tmpl new file mode 100644 index 0000000..f25a5ee --- /dev/null +++ b/templates/discordfx/layout/_master.tmpl @@ -0,0 +1,68 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} +{{!include(/^styles/.*/)}} +{{!include(/^fonts/.*/)}} +{{!include(favicon.ico)}} +{{!include(logo.svg)}} +{{!include(search-stopwords.json)}} + + + + + {{>partials/head}} + + +
+ + + + + + {{>partials/logo}} + +
+ +
+ +
+ +
+ +
+ + {{>partials/navbar}} + +
+ + {{^_disableToc}} + {{>partials/toc}} + {{/_disableToc}} + +
+ + {{>partials/footer}} + +
+ +
+ +
+ + {{^_disableBreadcrumb}} + {{>partials/breadcrumb}} + {{/_disableBreadcrumb}} + +
+ {{!body}} +
+ +
+
+
+ + {{>partials/scripts}} + + + + diff --git a/templates/discordfx/partials/footer.tmpl.partial b/templates/discordfx/partials/footer.tmpl.partial new file mode 100644 index 0000000..b110641 --- /dev/null +++ b/templates/discordfx/partials/footer.tmpl.partial @@ -0,0 +1,4 @@ +
+ {{{_appFooter}}} + {{^_appFooter}}Generated by DocFX{{/_appFooter}} +
\ No newline at end of file diff --git a/templates/material/partials/head.tmpl.partial b/templates/discordfx/partials/head.tmpl.partial similarity index 68% rename from templates/material/partials/head.tmpl.partial rename to templates/discordfx/partials/head.tmpl.partial index c05e8c1..43a2cc7 100644 --- a/templates/material/partials/head.tmpl.partial +++ b/templates/discordfx/partials/head.tmpl.partial @@ -1,4 +1,4 @@ -{{!Copyright (c) Oscar Vasquez. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} @@ -9,13 +9,14 @@ {{#_description}}{{/_description}} - - + + + + - {{#_noindex}}{{/_noindex}} {{#_enableSearch}}{{/_enableSearch}} {{#_enableNewTab}}{{/_enableNewTab}} - \ No newline at end of file + diff --git a/templates/discordfx/partials/li.tmpl.partial b/templates/discordfx/partials/li.tmpl.partial new file mode 100644 index 0000000..2c8a3d0 --- /dev/null +++ b/templates/discordfx/partials/li.tmpl.partial @@ -0,0 +1,31 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +
    + {{#items}} + {{^dropdown}} +
  • + {{^leaf}} + + {{/leaf}} + {{#topicHref}} + {{name}} + {{/topicHref}} + {{^topicHref}} + {{{name}}} + {{/topicHref}} + + {{^leaf}} + {{>partials/li}} + {{/leaf}} +
  • + {{/dropdown}} + {{#dropdown}} +
  • + {{name}} +
      + {{>partials/dd-li}} +
    +
  • + {{/dropdown}} + {{/items}} +
diff --git a/templates/discordfx/partials/logo.tmpl.partial b/templates/discordfx/partials/logo.tmpl.partial new file mode 100644 index 0000000..738ab5b --- /dev/null +++ b/templates/discordfx/partials/logo.tmpl.partial @@ -0,0 +1,6 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + {{_appName}} + {{_appName}} + \ No newline at end of file diff --git a/templates/discordfx/partials/navbar.tmpl.partial b/templates/discordfx/partials/navbar.tmpl.partial new file mode 100644 index 0000000..10b82d7 --- /dev/null +++ b/templates/discordfx/partials/navbar.tmpl.partial @@ -0,0 +1,13 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + +
+ {{>partials/logo}} + +
+ +
+ +
+ diff --git a/templates/discordfx/partials/scripts.tmpl.partial b/templates/discordfx/partials/scripts.tmpl.partial new file mode 100644 index 0000000..749cbcd --- /dev/null +++ b/templates/discordfx/partials/scripts.tmpl.partial @@ -0,0 +1,11 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + + + + + + + + diff --git a/templates/discordfx/partials/toc.tmpl.partial b/templates/discordfx/partials/toc.tmpl.partial new file mode 100644 index 0000000..c660966 --- /dev/null +++ b/templates/discordfx/partials/toc.tmpl.partial @@ -0,0 +1,5 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +
+
+
diff --git a/templates/discordfx/styles/colors.css b/templates/discordfx/styles/colors.css new file mode 100644 index 0000000..63590c7 --- /dev/null +++ b/templates/discordfx/styles/colors.css @@ -0,0 +1,73 @@ +/* Color schemes */ +:root +{ + /* General */ + --main-bg-color: #36393f; + --footer-bg-color: rgba(0,0,0,.4); + --table-strip-bg-color: #121315; + --table-header-bg-color: #202225;; + --table-header-color: hsla(0,0%,100%,.8); + --table-header-border-color: #040405; + + /* Text */ + --text-color: #dcddde; + --link-color: #00b0f4; + --link-hover-color: #4bd5ff; + --link-active-color: #fff; + --link-active-bg-color: #7289da; + --h3-color: #ffffff85; + --h4-color: #ffffffeb; + --h5-color: #ffffffd1; + + /* Topbar */ + --topbar-bg-color: #18191c; + + /* Button */ + --button-color: #747f8d; + + /* Sidebar */ + --separator-color: #4f545c; + --sidebar-bg-color: #2f3136; + --sidebar-item-color: #b9bbbe; + --sidebar-item-2nd-color: hsla(0,0%,100%,.35); + --sidebar-item-3rd-color: hsla(0,0%,100%,.25); + + /* Scrollbar */ + --scrollbar-bg-color: transparent; + --scrollbar-thumb-bg-color: rgba(0,0,0,.4); + --scrollbar-thumb-border-color: transparent; + + /* Alerts and Blocks */ + --alert-info-border-color: rgba(114,137,218,.5); + --alert-info-bg-color: rgba(114,137,218,.1); + + --alert-warning-border-color: rgba(250,166,26,.5); + --alert-warning-bg-color: rgba(250,166,26,.1); + + --alert-danger-border-color: rgba(240,71,71,.5); + --alert-danger-bg-color: rgba(240,71,71,.1); + + --alert-tip-border-color: rgba(255,255,255,.5); + --alert-tip-bg-color: rgba(255,255,255,.1); + + --blockquote-border-color: rgba(255,255,255,.5); + --blockquote-bg-color: rgba(255,255,255,.1); + + --breadcrumb-bg-color: #2f3136; + + /* Code Higlighting */ + --code-bg-color: #18191c; + --code-color: #8790A3; + --code-keyword-color: #569cd6; + --code-comment-color: #57a64a; + --code-macro-color: #beb7ff; + --code-string-color: #d69d85; + --code-string-escape-color: #ffd68f; + --code-field-color: #c8c8c8; + --code-function-color: #dcdcaa; + --code-control-color: #d8a0df; + --code-class-color: #4ec9b0; + --code-number-color: #b5cea8; + --code-params-color: #9a9a9a; + --code-breakpoint-color: #8c2f2f; +} diff --git a/templates/discordfx/styles/discord.css b/templates/discordfx/styles/discord.css new file mode 100644 index 0000000..a5a97b4 --- /dev/null +++ b/templates/discordfx/styles/discord.css @@ -0,0 +1,681 @@ +/* Discord Style */ + +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: var(--scrollbar-bg-color); +} + +::-webkit-scrollbar-thumb { + background: var(--scrollbar-thumb-bg-color); + border-color: var(--scrollbar-thumb-border-color); + border-radius: 5px; +} + +::marker { + unicode-bidi: isolate; + font-variant-numeric: tabular-nums; + text-transform: none; + text-indent: 0px !important; + text-align: start !important; + text-align-last: start !important; +} + +*, :after, :before +{ + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html, body +{ + padding: 0; + margin: 0; + font: 15px/150% 'Roboto', sans-serif; + overflow: hidden; + color: var(--text-color); + background-color: var(--main-bg-color); + + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +img { + max-width: 100%; +} + +ul > li, ol > li { + display: list-item; +} + +h1,h2,h3,h4,h5 +{ + color: var(--link-active-color); + position: relative; +} + +h1, h2 +{ + margin-block-start: 2em; +} + +h3 +{ + margin-block-start: 1em; + font-weight: 300; + font-size: 1.5em; + color: var(--h3-color); + margin-block-start: 3em; +} + +h4 +{ + opacity: 1; + color: var(--h4-color); + font-size: large; + border-bottom: 2px solid var(--separator-color); + margin: 20px 0 0 0; +} + + +h5 { + margin-block-end: .8em; + margin-block-start: 1em; + font-size: .85em; + font-weight: 500; + color: var(--h5-color); +} + +h6 { + font-size: .75em; + margin: 0; +} + +p +{ + font-weight: 400; +} + +ul +{ + position: relative; +} + +ul, ol +{ + padding-inline-start: 3em; +} + +ul.level1 +{ + list-style-type: none; + padding-inline-start: 0; +} + +ul.level2, ul.level3 +{ + padding-inline-start: 1em; + list-style-type: none; + font-size: .9em; +} + +a +{ + color: var(--link-color); + text-decoration: none; + transition: color .25s; +} + +a:focus, a:hover +{ + color: var(--link-hover-color); + text-decoration: underline; +} + +a.anchorjs-link:hover { + text-decoration: none; +} + +a.active, a:active +{ + color: var(--link-active-color); +} + +.body-content +{ + display: flex; + flex-direction: row; + height: 100%; + overflow-x: hidden; + overflow-y: hidden; +} + +.page-title +{ + margin-block-start: 0; +} + +nav +{ + width: 300px; + transition: left .5s ease-out; + position: fixed; + left: -350px; + top: 40px; + bottom: 0; + background-color: var(--sidebar-bg-color); + overflow-y: auto; + + display: flex; + flex-direction: column; + + z-index: 1000; +} + +h1:first-child +{ + margin-block-start: 1.1em; + margin-top: 1.1em; +} + +.sidebar +{ + padding: 32px 17px 32px 32px; + flex: 1; +} + +.sidebar-item +{ + font-size: 1em; + font-weight: 400; + display: block; + padding: 4px 16px; + color: var(--sidebar-item-color); +} + +.sidebar-item.large, #navbar .sidebar-item +{ + padding: 8px 16px; +} + +a.sidebar-item:hover, a.sidebar-item:focus +{ + color: var(--link-active-color); + text-decoration: none; +} + +a.sidebar-item.active +{ + color: var(--link-active-color); +} + +ul.level1 > li > a.sidebar-item +{ + background-color: transparent; + border-radius: 4px; +} + +#toc ul.level1 > li > a.sidebar-item.active +{ + background-color: var(--link-active-bg-color); +} + +.sidebar-item-separator +{ + height: 2px; + width: 100%; + background-color: var(--separator-color); + margin: 2em 0; + opacity: .8; +} + +span.sidebar-item +{ + font-weight: 700; + text-transform: uppercase; + font-size: .8em; + color: var(--text-color); + margin-block-start: 1.25em; +} + +.main-panel +{ + background-color: var(--main-bg-color); + flex: 1; + overflow-y: auto; + padding: 20px 40px; +} + +.top-navbar +{ + display: flex; + flex-direction: row; + align-items: center; + padding: 0 40px; + height: 40px; + background-color: var(--topbar-bg-color); +} + +.burger-icon +{ + margin-right: 1em; + color: var(--button-color); +} + +.burger-icon:hover, .burger-icon:focus +{ + color: var(--link-active-color); +} + +.burger-icon.active, .burger-icon:active +{ + color: var(--link-active-color); +} + +.brand +{ + display: flex; + align-items: center; + justify-content: start; +} + +.logomark +{ + height: 28px; +} + +.brand-title +{ + padding: 0 .5em; + font-size: .9em; + color: var(--link-active-color); +} + +.footer +{ + background-color: var(--footer-bg-color); + padding: 20px; + margin: 0 20px 20px 20px; + border-radius: 8px; + color: var(--link-active-color); +} + +.footer > h4 +{ + margin-block-start: 0; +} + +.blackout +{ + display: block; + visibility: hidden; + position: absolute; + z-index: 100; + top: 40px; + bottom: 0; + left: 0; + right: 0; + background-color: var(--footer-bg-color); +} + +@keyframes showThat { + 0% { opacity: 0; visibility: hidden; } + 1% { opacity: 0; visibility: visible; } + 100% { opacity: 1; visibility: visible;} +} + +@keyframes hideThat { + 0% { opacity: 1; visibility: visible; } + 99% { opacity: 0; visibility: visible; } + 100% { opacity: 0; visibility: hidden;} +} + +.showThat +{ + animation: showThat .5s forwards; +} + +.hideThat +{ + animation: hideThat .5s forwards; +} + + + +@media (min-width: 1024px) +{ + nav + { + position: relative; + left: 0!important; + top: 0; + bottom: 0; + } + + .top-navbar + { + display: none; + } + + .blackout + { + display: none; + } +} + +/* Table */ + +.table-responsive +{ + overflow-x: auto; + margin-bottom: 64px; +} + +table +{ + background-color: var(--code-bg-color); + border-collapse: collapse; + width: 100%; + table-layout: auto; +} + +table.table-striped tbody tr:nth-child(2n) +{ + background-color: var(--table-strip-bg-color); +} + +table thead +{ + background: var(--table-header-bg-color); +} + +table th +{ + color: var(--table-header-color); + text-transform: uppercase; + font-size: 12px; + line-height: 15px; + border-bottom: 1px solid var(--table-header-border-color); + padding: 8px; +} + +.table-condensed th { + text-align: left; +} + +table td +{ + padding: 8px; + font-weight: 300; +} + +table td > p +{ + margin: 0; +} + +/* Alerts */ +.alert { + border-radius: 4px; + padding: 8px; + margin: 25px 0; +} + +.alert > h5 +{ + display: none; + margin: 0; +} + +.alert > p +{ + margin: 0; + font-weight: 300; + font-size: 13px; +} + +.alert.alert-info +{ + border: 2px solid var(--alert-info-border-color); + background: var(--alert-info-bg-color); +} + +.alert.alert-warning +{ + border: 2px solid var(--alert-warning-border-color); + background: var(--alert-warning-bg-color); +} + +.alert.alert-danger +{ + border: 2px solid var(--alert-danger-border-color); + background: var(--alert-danger-bg-color); +} + +.TIP.alert.alert-info +{ + border: 2px solid var(--alert-tip-border-color); + background: var(--alert-tip-bg-color); +} + +blockquote { + margin: 8px 0; + border-left: 4px solid var(--blockquote-border-color); + padding: 8px; + background: var(--blockquote-bg-color); + border-radius: 4px; +} + +blockquote > p { + margin: 0; + font-style: italic; + font-size: 13px; +} + + +/* Breadcrumb */ + +#breadcrumb +{ + padding: 8px 16px; + background: var(--breadcrumb-bg-color); + border-radius: 4px; + margin-bottom: 30px; +} + +#breadcrumb:empty +{ + display: none; +} + +ul.breadcrumb +{ + display: flex; + flex-direction: row; + margin: 0; +} + +ul.breadcrumb > li { + margin-right: 6px; +} + +ul.breadcrumb > li::before +{ + content: "/"; + margin-right: 5px; +} + +ul.breadcrumb > li:first-child::before +{ + content: ""; + margin: 0; +} + + +/* Code */ + +legend, pre +{ + display: block; + background-color: var(--code-bg-color); + padding: 16px; + border-radius: 4px; +} + +code +{ + background-color: var(--code-bg-color); + padding: 2px 4px; + border-radius: 4px; +} + +.hljs +{ + background: transparent; +} + +/* DocFX related */ + +.small { + font-size: .9em; +} + +.pull-right +{ + float: right; +} + +.mobile-hide +{ + visibility: hidden; +} + +@media (min-width: 1024px) +{ + .mobile-hide + { + visibility: visible; + } +} + +li +{ + display: block; + position: relative; +} + +.expand-stub +{ + cursor: pointer; + position: absolute; + width: 20px; + height: 20px; + left: -10px; +} + +ul.level1 > li > .expand-stub +{ + display: none; +} + +.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before +{ + content: " "; + position: absolute; + transform: rotate(-90deg); + width: 10px; + height: 10px; + top: 5px; + left: 5px; + background-repeat: no-repeat; + background: url(/styles/down-arrow.svg); +} + +.toc .nav > li.active > .expand-stub::before, .toc .nav > li.in > .expand-stub::before, .toc .nav > li.in.active > .expand-stub::before, .toc .nav > li.filtered > .expand-stub::before +{ + transform: none; +} + +li > ul +{ + display: none; +} + +li.in > ul +{ + display: block; +} + +ul.level2 > li > a.sidebar-item, +ul.level3 > li > a.sidebar-item +{ + font-weight: 500; + font-size: .95em; + padding: 0; + margin: 2px 16px; +} + +ul.level2 > li > a.sidebar-item +{ + color: var(--sidebar-item-2nd-color); +} + +ul.level3 > li > a.sidebar-item +{ + color: var(--sidebar-item-3rd-color); +} + +ul.level2 > li > a.sidebar-item:hover, +ul.level2 > li > a.sidebar-item:focus, +ul.level3 > li > a.sidebar-item:hover, +ul.level3 > li > a.sidebar-item:focus +{ + color: var(--link-active-color); + text-decoration: underline; +} + +ul.level2 > li > a.sidebar-item.active, +ul.level3 > li > a.sidebar-item.active +{ + color: var(--link-active-color); +} + +.inheritance .level0:before, +.inheritance .level1:before, +.inheritance .level2:before, +.inheritance .level3:before, +.inheritance .level4:before, +.inheritance .level5:before { + content: '↳'; + margin-right: 5px; +} + +.inheritance .level0 { + margin-left: 0em; +} + +.inheritance .level1 { + margin-left: 1em; +} + +.inheritance .level2 { + margin-left: 2em; +} + +.inheritance .level3 { + margin-left: 3em; +} + +.inheritance .level4 { + margin-left: 4em; +} + +.inheritance .level5 { + margin-left: 5em; +} \ No newline at end of file diff --git a/templates/discordfx/styles/down-arrow.svg b/templates/discordfx/styles/down-arrow.svg new file mode 100644 index 0000000..e086126 --- /dev/null +++ b/templates/discordfx/styles/down-arrow.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/discordfx/styles/jquery.twbsPagination.js b/templates/discordfx/styles/jquery.twbsPagination.js new file mode 100644 index 0000000..332c01c --- /dev/null +++ b/templates/discordfx/styles/jquery.twbsPagination.js @@ -0,0 +1,317 @@ +/*! + * jQuery pagination plugin v1.4.1 + * http://esimakin.github.io/twbs-pagination/ + * + * Copyright 2014-2016, Eugene Simakin + * Released under Apache 2.0 license + * http://apache.org/licenses/LICENSE-2.0.html + */ +(function ($, window, document, undefined) { + + 'use strict'; + + var old = $.fn.twbsPagination; + + // PROTOTYPE AND CONSTRUCTOR + + var TwbsPagination = function (element, options) { + this.$element = $(element); + this.options = $.extend({}, $.fn.twbsPagination.defaults, options); + + if (this.options.startPage < 1 || this.options.startPage > this.options.totalPages) { + throw new Error('Start page option is incorrect'); + } + + this.options.totalPages = parseInt(this.options.totalPages); + if (isNaN(this.options.totalPages)) { + throw new Error('Total pages option is not correct!'); + } + + this.options.visiblePages = parseInt(this.options.visiblePages); + if (isNaN(this.options.visiblePages)) { + throw new Error('Visible pages option is not correct!'); + } + + if (this.options.onPageClick instanceof Function) { + this.$element.first().on('page', this.options.onPageClick); + } + + // hide if only one page exists + if (this.options.hideOnlyOnePage && this.options.totalPages == 1) { + this.$element.trigger('page', 1); + return this; + } + + if (this.options.totalPages < this.options.visiblePages) { + this.options.visiblePages = this.options.totalPages; + } + + if (this.options.href) { + this.options.startPage = this.getPageFromQueryString(); + if (!this.options.startPage) { + this.options.startPage = 1; + } + } + + var tagName = (typeof this.$element.prop === 'function') ? + this.$element.prop('tagName') : this.$element.attr('tagName'); + + if (tagName === 'UL') { + this.$listContainer = this.$element; + } else { + this.$listContainer = $('
    '); + } + + this.$listContainer.addClass(this.options.paginationClass); + + if (tagName !== 'UL') { + this.$element.append(this.$listContainer); + } + + if (this.options.initiateStartPageClick) { + this.show(this.options.startPage); + } else { + this.render(this.getPages(this.options.startPage)); + this.setupEvents(); + } + + return this; + }; + + TwbsPagination.prototype = { + + constructor: TwbsPagination, + + destroy: function () { + this.$element.empty(); + this.$element.removeData('twbs-pagination'); + this.$element.off('page'); + + return this; + }, + + show: function (page) { + if (page < 1 || page > this.options.totalPages) { + throw new Error('Page is incorrect.'); + } + this.currentPage = page; + + this.render(this.getPages(page)); + this.setupEvents(); + + this.$element.trigger('page', page); + + return this; + }, + + buildListItems: function (pages) { + var listItems = []; + + if (this.options.first) { + listItems.push(this.buildItem('first', 1)); + } + + if (this.options.prev) { + var prev = pages.currentPage > 1 ? pages.currentPage - 1 : this.options.loop ? this.options.totalPages : 1; + listItems.push(this.buildItem('prev', prev)); + } + + for (var i = 0; i < pages.numeric.length; i++) { + listItems.push(this.buildItem('page', pages.numeric[i])); + } + + if (this.options.next) { + var next = pages.currentPage < this.options.totalPages ? pages.currentPage + 1 : this.options.loop ? 1 : this.options.totalPages; + listItems.push(this.buildItem('next', next)); + } + + if (this.options.last) { + listItems.push(this.buildItem('last', this.options.totalPages)); + } + + return listItems; + }, + + buildItem: function (type, page) { + var $itemContainer = $('
  • '), + $itemContent = $(''), + itemText = this.options[type] ? this.makeText(this.options[type], page) : page; + + $itemContainer.addClass(this.options[type + 'Class']); + $itemContainer.data('page', page); + $itemContainer.data('page-type', type); + $itemContainer.append($itemContent.attr('href', this.makeHref(page)).addClass(this.options.anchorClass).html(itemText)); + + return $itemContainer; + }, + + getPages: function (currentPage) { + var pages = []; + + var half = Math.floor(this.options.visiblePages / 2); + var start = currentPage - half + 1 - this.options.visiblePages % 2; + var end = currentPage + half; + + // handle boundary case + if (start <= 0) { + start = 1; + end = this.options.visiblePages; + } + if (end > this.options.totalPages) { + start = this.options.totalPages - this.options.visiblePages + 1; + end = this.options.totalPages; + } + + var itPage = start; + while (itPage <= end) { + pages.push(itPage); + itPage++; + } + + return {"currentPage": currentPage, "numeric": pages}; + }, + + render: function (pages) { + var _this = this; + this.$listContainer.children().remove(); + var items = this.buildListItems(pages); + jQuery.each(items, function(key, item){ + _this.$listContainer.append(item); + }); + + this.$listContainer.children().each(function () { + var $this = $(this), + pageType = $this.data('page-type'); + + switch (pageType) { + case 'page': + if ($this.data('page') === pages.currentPage) { + $this.addClass(_this.options.activeClass); + } + break; + case 'first': + $this.toggleClass(_this.options.disabledClass, pages.currentPage === 1); + break; + case 'last': + $this.toggleClass(_this.options.disabledClass, pages.currentPage === _this.options.totalPages); + break; + case 'prev': + $this.toggleClass(_this.options.disabledClass, !_this.options.loop && pages.currentPage === 1); + break; + case 'next': + $this.toggleClass(_this.options.disabledClass, + !_this.options.loop && pages.currentPage === _this.options.totalPages); + break; + default: + break; + } + + }); + }, + + setupEvents: function () { + var _this = this; + this.$listContainer.off('click').on('click', 'li', function (evt) { + var $this = $(this); + if ($this.hasClass(_this.options.disabledClass) || $this.hasClass(_this.options.activeClass)) { + return false; + } + // Prevent click event if href is not set. + !_this.options.href && evt.preventDefault(); + _this.show(parseInt($this.data('page'))); + }); + }, + + makeHref: function (page) { + return this.options.href ? this.generateQueryString(page) : "#"; + }, + + makeText: function (text, page) { + return text.replace(this.options.pageVariable, page) + .replace(this.options.totalPagesVariable, this.options.totalPages) + }, + getPageFromQueryString: function (searchStr) { + var search = this.getSearchString(searchStr), + regex = new RegExp(this.options.pageVariable + '(=([^&#]*)|&|#|$)'), + page = regex.exec(search); + if (!page || !page[2]) { + return null; + } + page = decodeURIComponent(page[2]); + page = parseInt(page); + if (isNaN(page)) { + return null; + } + return page; + }, + generateQueryString: function (pageNumber, searchStr) { + var search = this.getSearchString(searchStr), + regex = new RegExp(this.options.pageVariable + '=*[^&#]*'); + if (!search) return ''; + return '?' + search.replace(regex, this.options.pageVariable + '=' + pageNumber); + + }, + getSearchString: function (searchStr) { + var search = searchStr || window.location.search; + if (search === '') { + return null; + } + if (search.indexOf('?') === 0) search = search.substr(1); + return search; + } + + }; + + // PLUGIN DEFINITION + + $.fn.twbsPagination = function (option) { + var args = Array.prototype.slice.call(arguments, 1); + var methodReturn; + + var $this = $(this); + var data = $this.data('twbs-pagination'); + var options = typeof option === 'object' ? option : {}; + + if (!data) $this.data('twbs-pagination', (data = new TwbsPagination(this, options) )); + if (typeof option === 'string') methodReturn = data[ option ].apply(data, args); + + return ( methodReturn === undefined ) ? $this : methodReturn; + }; + + $.fn.twbsPagination.defaults = { + totalPages: 1, + startPage: 1, + visiblePages: 5, + initiateStartPageClick: true, + hideOnlyOnePage: false, + href: false, + pageVariable: '{{page}}', + totalPagesVariable: '{{total_pages}}', + page: null, + first: 'First', + prev: 'Previous', + next: 'Next', + last: 'Last', + loop: false, + onPageClick: null, + paginationClass: 'pagination', + nextClass: 'page-item next', + prevClass: 'page-item prev', + lastClass: 'page-item last', + firstClass: 'page-item first', + pageClass: 'page-item', + activeClass: 'active', + disabledClass: 'disabled', + anchorClass: 'page-link' + }; + + $.fn.twbsPagination.Constructor = TwbsPagination; + + $.fn.twbsPagination.noConflict = function () { + $.fn.twbsPagination = old; + return this; + }; + + $.fn.twbsPagination.version = "1.4.1"; + +})(window.jQuery, window, document); diff --git a/templates/discordfx/styles/main.css b/templates/discordfx/styles/main.css new file mode 100644 index 0000000..e69de29 diff --git a/templates/discordfx/styles/main.js b/templates/discordfx/styles/main.js new file mode 100644 index 0000000..b9150b4 --- /dev/null +++ b/templates/discordfx/styles/main.js @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. + +function toggleMenu() { + + var x = document.getElementById("sidebar"); + var b = document.getElementById("blackout"); + + if (x.style.left === "0px") + { + x.style.left = "-350px"; + b.classList.remove("showThat"); + b.classList.add("hideThat"); + } + else + { + x.style.left = "0px"; + b.classList.remove("hideThat"); + b.classList.add("showThat"); + } +} \ No newline at end of file diff --git a/templates/discordfx/styles/url.min.js b/templates/discordfx/styles/url.min.js new file mode 100644 index 0000000..8057e0a --- /dev/null +++ b/templates/discordfx/styles/url.min.js @@ -0,0 +1 @@ +/*! url - v1.8.6 - 2013-11-22 */window.url=function(){function a(a){return!isNaN(parseFloat(a))&&isFinite(a)}return function(b,c){var d=c||window.location.toString();if(!b)return d;b=b.toString(),"//"===d.substring(0,2)?d="http:"+d:1===d.split("://").length&&(d="http://"+d),c=d.split("/");var e={auth:""},f=c[2].split("@");1===f.length?f=f[0].split(":"):(e.auth=f[0],f=f[1].split(":")),e.protocol=c[0],e.hostname=f[0],e.port=f[1]||("https"===e.protocol.split(":")[0].toLowerCase()?"443":"80"),e.pathname=(c.length>3?"/":"")+c.slice(3,c.length).join("/").split("?")[0].split("#")[0];var g=e.pathname;"/"===g.charAt(g.length-1)&&(g=g.substring(0,g.length-1));var h=e.hostname,i=h.split("."),j=g.split("/");if("hostname"===b)return h;if("domain"===b)return/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test(h)?h:i.slice(-2).join(".");if("sub"===b)return i.slice(0,i.length-2).join(".");if("port"===b)return e.port;if("protocol"===b)return e.protocol.split(":")[0];if("auth"===b)return e.auth;if("user"===b)return e.auth.split(":")[0];if("pass"===b)return e.auth.split(":")[1]||"";if("path"===b)return e.pathname;if("."===b.charAt(0)){if(b=b.substring(1),a(b))return b=parseInt(b,10),i[0>b?i.length+b:b-1]||""}else{if(a(b))return b=parseInt(b,10),j[0>b?j.length+b:b]||"";if("file"===b)return j.slice(-1)[0];if("filename"===b)return j.slice(-1)[0].split(".")[0];if("fileext"===b)return j.slice(-1)[0].split(".")[1]||"";if("?"===b.charAt(0)||"#"===b.charAt(0)){var k=d,l=null;if("?"===b.charAt(0)?k=(k.split("?")[1]||"").split("#")[0]:"#"===b.charAt(0)&&(k=k.split("#")[1]||""),!b.charAt(1))return k;b=b.substring(1),k=k.split("&");for(var m=0,n=k.length;n>m;m++)if(l=k[m].split("="),l[0]===b)return l[1]||"";return null}}return""}}(),"undefined"!=typeof jQuery&&jQuery.extend({url:function(a,b){return window.url(a,b)}}); \ No newline at end of file diff --git a/templates/material/partials/logo.tmpl.partial b/templates/material/partials/logo.tmpl.partial deleted file mode 100644 index 8a16493..0000000 --- a/templates/material/partials/logo.tmpl.partial +++ /dev/null @@ -1,5 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - {{_appName}} - \ No newline at end of file diff --git a/templates/material/styles/main.css b/templates/material/styles/main.css deleted file mode 100644 index 872709b..0000000 --- a/templates/material/styles/main.css +++ /dev/null @@ -1,306 +0,0 @@ -/* COLOR VARIABLES*/ -:root { - --header-bg-color: #0d47a1; - --header-ft-color: #fff; - --highlight-light: #5e92f3; - --highlight-dark: #003c8f; - --accent-dim: #e0e0e0; - --accent-super-dim: #f3f3f3; - --font-color: #34393e; - --card-box-shadow: 0 1px 2px 0 rgba(61, 65, 68, 0.06), 0 1px 3px 1px rgba(61, 65, 68, 0.16); - --search-box-shadow: 0 1px 2px 0 rgba(41, 45, 48, 0.36), 0 1px 3px 1px rgba(41, 45, 48, 0.46); - --transition: 350ms; -} - -body { - color: var(--font-color); - font-family: "Roboto", sans-serif; - line-height: 1.5; - font-size: 16px; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; - word-wrap: break-word; -} - -/* HIGHLIGHT COLOR */ - -button, -a { - color: var(--highlight-dark); - cursor: pointer; -} - -button:hover, -button:focus, -a:hover, -a:focus { - color: var(--highlight-light); - text-decoration: none; -} - -.toc .nav > li.active > a { - color: var(--highlight-dark); -} - -.toc .nav > li.active > a:hover, -.toc .nav > li.active > a:focus { - color: var(--highlight-light); -} - -.pagination > .active > a { - background-color: var(--header-bg-color); - border-color: var(--header-bg-color); -} - -.pagination > .active > a, -.pagination > .active > a:focus, -.pagination > .active > a:hover, -.pagination > .active > span, -.pagination > .active > span:focus, -.pagination > .active > span:hover { - background-color: var(--highlight-light); - border-color: var(--highlight-light); -} - -/* HEADINGS */ - -h1 { - font-weight: 600; - font-size: 32px; -} - -h2 { - font-weight: 600; - font-size: 24px; - line-height: 1.8; -} - -h3 { - font-weight: 600; - font-size: 20px; - line-height: 1.8; -} - -h5 { - font-size: 14px; - padding: 10px 0px; -} - -article h1, -article h2, -article h3, -article h4 { - margin-top: 35px; - margin-bottom: 15px; -} - -article h4 { - padding-bottom: 8px; - border-bottom: 2px solid #ddd; -} - -/* NAVBAR */ - -.navbar-brand > img { - color: var(--header-ft-color); -} - -.navbar { - border: none; - /* Both navbars use box-shadow */ - -webkit-box-shadow: var(--card-box-shadow); - -moz-box-shadow: var(--card-box-shadow); - box-shadow: var(--card-box-shadow); -} - -.subnav { - border-top: 1px solid #ddd; - background-color: #fff; -} - -.navbar-inverse { - background-color: var(--header-bg-color); - z-index: 100; -} - -.navbar-inverse .navbar-nav > li > a, -.navbar-inverse .navbar-text { - color: var(--header-ft-color); - background-color: var(--header-bg-color); - border-bottom: 3px solid transparent; - padding-bottom: 12px; - transition: 350ms; -} - -.navbar-inverse .navbar-nav > li > a:focus, -.navbar-inverse .navbar-nav > li > a:hover { - color: var(--header-ft-color); - background-color: var(--header-bg-color); - border-bottom: 3px solid white; -} - -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:focus, -.navbar-inverse .navbar-nav > .active > a:hover { - color: var(--header-ft-color); - background-color: var(--header-bg-color); - border-bottom: 3px solid white; -} - -.navbar-form .form-control { - border: 0; - border-radius: 4px; - box-shadow: var(--search-box-shadow); - transition:var(--transition); -} - -.navbar-form .form-control:hover { - background-color: var(--accent-dim); -} - -/* NAVBAR TOGGLED (small screens) */ - -.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { - border: none; -} -.navbar-inverse .navbar-toggle { - box-shadow: var(--card-box-shadow); - border: none; -} - -.navbar-inverse .navbar-toggle:focus, -.navbar-inverse .navbar-toggle:hover { - background-color: var(--highlight-dark); -} - -/* SIDEBAR */ - -.toc .level1 > li { - font-weight: 400; -} - -.toc .nav > li > a { - color: var(--font-color); -} - -.sidefilter { - background-color: #fff; - border-left: none; - border-right: none; -} - -.sidefilter { - background-color: #fff; - border-left: none; - border-right: none; -} - -.toc-filter { - padding: 5px; - margin: 0; - box-shadow: var(--card-box-shadow); - transition:var(--transition); -} - -.toc-filter:hover { - background-color: var(--accent-super-dim); -} - -.toc-filter > input { - border: none; - background-color: inherit; - transition: inherit; -} - -.toc-filter > .filter-icon { - display: none; -} - -.sidetoc > .toc { - background-color: #fff; - overflow-x: hidden; -} - -.sidetoc { - background-color: #fff; - border: none; -} - -/* ALERTS */ - -.alert { - padding: 0px 0px 5px 0px; - color: inherit; - background-color: inherit; - border: none; - box-shadow: var(--card-box-shadow); -} - -.alert > p { - margin-bottom: 0; - padding: 5px 10px; -} - -.alert > ul { - margin-bottom: 0; - padding: 5px 40px; -} - -.alert > h5 { - padding: 10px 15px; - margin-top: 0; - text-transform: uppercase; - font-weight: bold; - border-radius: 4px 4px 0 0; -} - -.alert-info > h5 { - color: #1976d2; - border-bottom: 4px solid #1976d2; - background-color: #e3f2fd; -} - -.alert-warning > h5 { - color: #f57f17; - border-bottom: 4px solid #f57f17; - background-color: #fff3e0; -} - -.alert-danger > h5 { - color: #d32f2f; - border-bottom: 4px solid #d32f2f; - background-color: #ffebee; -} - -/* CODE HIGHLIGHT */ -pre { - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - word-break: break-all; - word-wrap: break-word; - background-color: #fffaef; - border-radius: 4px; - border: none; - box-shadow: var(--card-box-shadow); -} - -/* STYLE FOR IMAGES */ - -.article .small-image { - margin-top: 15px; - box-shadow: var(--card-box-shadow); - max-width: 350px; -} - -.article .medium-image { - margin-top: 15px; - box-shadow: var(--card-box-shadow); - max-width: 550px; -} - -.article .large-image { - margin-top: 15px; - box-shadow: var(--card-box-shadow); - max-width: 700px; -} \ No newline at end of file