Vibe Google Analytics
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3.0
|
||||||
@@ -60,7 +60,7 @@ foreach (var file in mdFiles)
|
|||||||
ImmortalizeWhen = NullIfNa(StripWikiLinks(yaml.GetValueOrDefault("immortalizeWhen"))),
|
ImmortalizeWhen = NullIfNa(StripWikiLinks(yaml.GetValueOrDefault("immortalizeWhen"))),
|
||||||
ImageFile = imageFile,
|
ImageFile = imageFile,
|
||||||
Artist = yaml.GetValueOrDefault("artist"),
|
Artist = yaml.GetValueOrDefault("artist"),
|
||||||
Rarity = yaml.GetValueOrDefault("rarity"),
|
Rarity = yaml.GetValueOrDefault("rarity")
|
||||||
};
|
};
|
||||||
|
|
||||||
cards.Add(card);
|
cards.Add(card);
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Model\Model.csproj" />
|
<ProjectReference Include="..\Model\Model.csproj"/>
|
||||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
<ProjectReference Include="..\Shared\Shared.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -21,20 +21,20 @@ main {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin-left: 1.5rem;
|
margin-left: 1.5rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-row ::deep a:first-child {
|
.top-row ::deep a:first-child {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640.98px) {
|
@media (max-width: 640.98px) {
|
||||||
.top-row {
|
.top-row {
|
||||||
@@ -90,9 +90,9 @@ main {
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#blazor-error-ui .dismiss {
|
#blazor-error-ui .dismiss {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.75rem;
|
right: 0.75rem;
|
||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
.top-row {
|
.top-row {
|
||||||
min-height: 3.5rem;
|
min-height: 3.5rem;
|
||||||
background-color: rgba(0,0,0,0.4);
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-brand {
|
.navbar-brand {
|
||||||
@@ -51,33 +51,33 @@
|
|||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:first-of-type {
|
.nav-item:first-of-type {
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:last-of-type {
|
.nav-item:last-of-type {
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item ::deep .nav-link {
|
.nav-item ::deep .nav-link {
|
||||||
color: #d7d7d7;
|
color: #d7d7d7;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
line-height: 3rem;
|
line-height: 3rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item ::deep a.active {
|
.nav-item ::deep a.active {
|
||||||
background-color: rgba(255,255,255,0.37);
|
background-color: rgba(255, 255, 255, 0.37);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item ::deep .nav-link:hover {
|
.nav-item ::deep .nav-link:hover {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,11 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
|
transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
|
||||||
animation: components-reconnect-modal-fadeOutOpacity 0.5s both;
|
animation: components-reconnect-modal-fadeOutOpacity 0.5s both;
|
||||||
&[open]
|
|
||||||
|
|
||||||
{
|
&[open] {
|
||||||
animation: components-reconnect-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity 0.5s ease-in-out 0.3s;
|
animation: components-reconnect-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity 0.5s ease-in-out 0.3s;
|
||||||
animation-fill-mode: both;
|
animation-fill-mode: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,13 +95,13 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#components-reconnect-modal button:hover {
|
#components-reconnect-modal button:hover {
|
||||||
background-color: #3b6ea2;
|
background-color: #3b6ea2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#components-reconnect-modal button:active {
|
#components-reconnect-modal button:active {
|
||||||
background-color: #6b9ed2;
|
background-color: #6b9ed2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.components-rejoining-animation {
|
.components-rejoining-animation {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -110,17 +109,17 @@
|
|||||||
height: 80px;
|
height: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.components-rejoining-animation div {
|
.components-rejoining-animation div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 3px solid #0087ff;
|
border: 3px solid #0087ff;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
animation: components-rejoining-animation 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
|
animation: components-rejoining-animation 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.components-rejoining-animation div:nth-child(2) {
|
.components-rejoining-animation div:nth-child(2) {
|
||||||
animation-delay: -0.5s;
|
animation-delay: -0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes components-rejoining-animation {
|
@keyframes components-rejoining-animation {
|
||||||
0% {
|
0% {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private int currentCount = 0;
|
private int currentCount;
|
||||||
|
|
||||||
private void IncrementCount()
|
private void IncrementCount()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,12 +15,14 @@
|
|||||||
|
|
||||||
<h3>Development Mode</h3>
|
<h3>Development Mode</h3>
|
||||||
<p>
|
<p>
|
||||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
Swapping to <strong>Development</strong> environment will display more detailed information about the error that
|
||||||
|
occurred.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||||
It can result in displaying sensitive information from exceptions to end users.
|
It can result in displaying sensitive information from exceptions to end users.
|
||||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong>
|
||||||
|
environment variable to <strong>Development</strong>
|
||||||
and restarting the app.
|
and restarting the app.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -30,7 +32,9 @@
|
|||||||
private string? RequestId { get; set; }
|
private string? RequestId { get; set; }
|
||||||
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
|
||||||
protected override void OnInitialized() =>
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
|
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
@using Shared.Pages
|
@using Shared.Pages
|
||||||
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly }" NotFoundPage="typeof(Pages.NotFound)">
|
@using NotFound = Cloud.Components.Pages.NotFound
|
||||||
|
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly }"
|
||||||
|
NotFoundPage="typeof(NotFound)">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)"/>
|
<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)"/>
|
||||||
<FocusOnNavigate RouteData="routeData" Selector="h1"/>
|
<FocusOnNavigate RouteData="routeData" Selector="h1"/>
|
||||||
</Found>
|
</Found>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -11,7 +11,7 @@ var app = builder.Build();
|
|||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (!app.Environment.IsDevelopment())
|
if (!app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
app.UseExceptionHandler("/Error", true);
|
||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
app.UseHsts();
|
app.UseHsts();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"http": {
|
"http": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"applicationUrl": "http://localhost:5230",
|
"applicationUrl": "http://localhost:5230",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"https": {
|
"https": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"applicationUrl": "https://localhost:7086;http://localhost:5230",
|
"applicationUrl": "https://localhost:7086;http://localhost:5230",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ a, .btn-link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
@@ -42,9 +42,9 @@ h1:focus {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blazor-error-boundary::after {
|
.blazor-error-boundary::after {
|
||||||
content: "An error has occurred."
|
content: "An error has occurred."
|
||||||
}
|
}
|
||||||
|
|
||||||
.darker-border-checkbox.form-check-input {
|
.darker-border-checkbox.form-check-input {
|
||||||
border-color: #929292;
|
border-color: #929292;
|
||||||
|
|||||||
+4416
-3450
File diff suppressed because it is too large
Load Diff
+4417
-3450
File diff suppressed because it is too large
Load Diff
+339
-327
@@ -5,427 +5,435 @@
|
|||||||
*/
|
*/
|
||||||
:root,
|
:root,
|
||||||
[data-bs-theme=light] {
|
[data-bs-theme=light] {
|
||||||
--bs-blue: #0d6efd;
|
--bs-blue: #0d6efd;
|
||||||
--bs-indigo: #6610f2;
|
--bs-indigo: #6610f2;
|
||||||
--bs-purple: #6f42c1;
|
--bs-purple: #6f42c1;
|
||||||
--bs-pink: #d63384;
|
--bs-pink: #d63384;
|
||||||
--bs-red: #dc3545;
|
--bs-red: #dc3545;
|
||||||
--bs-orange: #fd7e14;
|
--bs-orange: #fd7e14;
|
||||||
--bs-yellow: #ffc107;
|
--bs-yellow: #ffc107;
|
||||||
--bs-green: #198754;
|
--bs-green: #198754;
|
||||||
--bs-teal: #20c997;
|
--bs-teal: #20c997;
|
||||||
--bs-cyan: #0dcaf0;
|
--bs-cyan: #0dcaf0;
|
||||||
--bs-black: #000;
|
--bs-black: #000;
|
||||||
--bs-white: #fff;
|
--bs-white: #fff;
|
||||||
--bs-gray: #6c757d;
|
--bs-gray: #6c757d;
|
||||||
--bs-gray-dark: #343a40;
|
--bs-gray-dark: #343a40;
|
||||||
--bs-gray-100: #f8f9fa;
|
--bs-gray-100: #f8f9fa;
|
||||||
--bs-gray-200: #e9ecef;
|
--bs-gray-200: #e9ecef;
|
||||||
--bs-gray-300: #dee2e6;
|
--bs-gray-300: #dee2e6;
|
||||||
--bs-gray-400: #ced4da;
|
--bs-gray-400: #ced4da;
|
||||||
--bs-gray-500: #adb5bd;
|
--bs-gray-500: #adb5bd;
|
||||||
--bs-gray-600: #6c757d;
|
--bs-gray-600: #6c757d;
|
||||||
--bs-gray-700: #495057;
|
--bs-gray-700: #495057;
|
||||||
--bs-gray-800: #343a40;
|
--bs-gray-800: #343a40;
|
||||||
--bs-gray-900: #212529;
|
--bs-gray-900: #212529;
|
||||||
--bs-primary: #0d6efd;
|
--bs-primary: #0d6efd;
|
||||||
--bs-secondary: #6c757d;
|
--bs-secondary: #6c757d;
|
||||||
--bs-success: #198754;
|
--bs-success: #198754;
|
||||||
--bs-info: #0dcaf0;
|
--bs-info: #0dcaf0;
|
||||||
--bs-warning: #ffc107;
|
--bs-warning: #ffc107;
|
||||||
--bs-danger: #dc3545;
|
--bs-danger: #dc3545;
|
||||||
--bs-light: #f8f9fa;
|
--bs-light: #f8f9fa;
|
||||||
--bs-dark: #212529;
|
--bs-dark: #212529;
|
||||||
--bs-primary-rgb: 13, 110, 253;
|
--bs-primary-rgb: 13, 110, 253;
|
||||||
--bs-secondary-rgb: 108, 117, 125;
|
--bs-secondary-rgb: 108, 117, 125;
|
||||||
--bs-success-rgb: 25, 135, 84;
|
--bs-success-rgb: 25, 135, 84;
|
||||||
--bs-info-rgb: 13, 202, 240;
|
--bs-info-rgb: 13, 202, 240;
|
||||||
--bs-warning-rgb: 255, 193, 7;
|
--bs-warning-rgb: 255, 193, 7;
|
||||||
--bs-danger-rgb: 220, 53, 69;
|
--bs-danger-rgb: 220, 53, 69;
|
||||||
--bs-light-rgb: 248, 249, 250;
|
--bs-light-rgb: 248, 249, 250;
|
||||||
--bs-dark-rgb: 33, 37, 41;
|
--bs-dark-rgb: 33, 37, 41;
|
||||||
--bs-primary-text-emphasis: #052c65;
|
--bs-primary-text-emphasis: #052c65;
|
||||||
--bs-secondary-text-emphasis: #2b2f32;
|
--bs-secondary-text-emphasis: #2b2f32;
|
||||||
--bs-success-text-emphasis: #0a3622;
|
--bs-success-text-emphasis: #0a3622;
|
||||||
--bs-info-text-emphasis: #055160;
|
--bs-info-text-emphasis: #055160;
|
||||||
--bs-warning-text-emphasis: #664d03;
|
--bs-warning-text-emphasis: #664d03;
|
||||||
--bs-danger-text-emphasis: #58151c;
|
--bs-danger-text-emphasis: #58151c;
|
||||||
--bs-light-text-emphasis: #495057;
|
--bs-light-text-emphasis: #495057;
|
||||||
--bs-dark-text-emphasis: #495057;
|
--bs-dark-text-emphasis: #495057;
|
||||||
--bs-primary-bg-subtle: #cfe2ff;
|
--bs-primary-bg-subtle: #cfe2ff;
|
||||||
--bs-secondary-bg-subtle: #e2e3e5;
|
--bs-secondary-bg-subtle: #e2e3e5;
|
||||||
--bs-success-bg-subtle: #d1e7dd;
|
--bs-success-bg-subtle: #d1e7dd;
|
||||||
--bs-info-bg-subtle: #cff4fc;
|
--bs-info-bg-subtle: #cff4fc;
|
||||||
--bs-warning-bg-subtle: #fff3cd;
|
--bs-warning-bg-subtle: #fff3cd;
|
||||||
--bs-danger-bg-subtle: #f8d7da;
|
--bs-danger-bg-subtle: #f8d7da;
|
||||||
--bs-light-bg-subtle: #fcfcfd;
|
--bs-light-bg-subtle: #fcfcfd;
|
||||||
--bs-dark-bg-subtle: #ced4da;
|
--bs-dark-bg-subtle: #ced4da;
|
||||||
--bs-primary-border-subtle: #9ec5fe;
|
--bs-primary-border-subtle: #9ec5fe;
|
||||||
--bs-secondary-border-subtle: #c4c8cb;
|
--bs-secondary-border-subtle: #c4c8cb;
|
||||||
--bs-success-border-subtle: #a3cfbb;
|
--bs-success-border-subtle: #a3cfbb;
|
||||||
--bs-info-border-subtle: #9eeaf9;
|
--bs-info-border-subtle: #9eeaf9;
|
||||||
--bs-warning-border-subtle: #ffe69c;
|
--bs-warning-border-subtle: #ffe69c;
|
||||||
--bs-danger-border-subtle: #f1aeb5;
|
--bs-danger-border-subtle: #f1aeb5;
|
||||||
--bs-light-border-subtle: #e9ecef;
|
--bs-light-border-subtle: #e9ecef;
|
||||||
--bs-dark-border-subtle: #adb5bd;
|
--bs-dark-border-subtle: #adb5bd;
|
||||||
--bs-white-rgb: 255, 255, 255;
|
--bs-white-rgb: 255, 255, 255;
|
||||||
--bs-black-rgb: 0, 0, 0;
|
--bs-black-rgb: 0, 0, 0;
|
||||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||||
--bs-body-font-size: 1rem;
|
--bs-body-font-size: 1rem;
|
||||||
--bs-body-font-weight: 400;
|
--bs-body-font-weight: 400;
|
||||||
--bs-body-line-height: 1.5;
|
--bs-body-line-height: 1.5;
|
||||||
--bs-body-color: #212529;
|
--bs-body-color: #212529;
|
||||||
--bs-body-color-rgb: 33, 37, 41;
|
--bs-body-color-rgb: 33, 37, 41;
|
||||||
--bs-body-bg: #fff;
|
--bs-body-bg: #fff;
|
||||||
--bs-body-bg-rgb: 255, 255, 255;
|
--bs-body-bg-rgb: 255, 255, 255;
|
||||||
--bs-emphasis-color: #000;
|
--bs-emphasis-color: #000;
|
||||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||||
--bs-secondary-color-rgb: 33, 37, 41;
|
--bs-secondary-color-rgb: 33, 37, 41;
|
||||||
--bs-secondary-bg: #e9ecef;
|
--bs-secondary-bg: #e9ecef;
|
||||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||||
--bs-tertiary-bg: #f8f9fa;
|
--bs-tertiary-bg: #f8f9fa;
|
||||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||||
--bs-heading-color: inherit;
|
--bs-heading-color: inherit;
|
||||||
--bs-link-color: #0d6efd;
|
--bs-link-color: #0d6efd;
|
||||||
--bs-link-color-rgb: 13, 110, 253;
|
--bs-link-color-rgb: 13, 110, 253;
|
||||||
--bs-link-decoration: underline;
|
--bs-link-decoration: underline;
|
||||||
--bs-link-hover-color: #0a58ca;
|
--bs-link-hover-color: #0a58ca;
|
||||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||||
--bs-code-color: #d63384;
|
--bs-code-color: #d63384;
|
||||||
--bs-highlight-color: #212529;
|
--bs-highlight-color: #212529;
|
||||||
--bs-highlight-bg: #fff3cd;
|
--bs-highlight-bg: #fff3cd;
|
||||||
--bs-border-width: 1px;
|
--bs-border-width: 1px;
|
||||||
--bs-border-style: solid;
|
--bs-border-style: solid;
|
||||||
--bs-border-color: #dee2e6;
|
--bs-border-color: #dee2e6;
|
||||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||||
--bs-border-radius: 0.375rem;
|
--bs-border-radius: 0.375rem;
|
||||||
--bs-border-radius-sm: 0.25rem;
|
--bs-border-radius-sm: 0.25rem;
|
||||||
--bs-border-radius-lg: 0.5rem;
|
--bs-border-radius-lg: 0.5rem;
|
||||||
--bs-border-radius-xl: 1rem;
|
--bs-border-radius-xl: 1rem;
|
||||||
--bs-border-radius-xxl: 2rem;
|
--bs-border-radius-xxl: 2rem;
|
||||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||||
--bs-border-radius-pill: 50rem;
|
--bs-border-radius-pill: 50rem;
|
||||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||||
--bs-focus-ring-width: 0.25rem;
|
--bs-focus-ring-width: 0.25rem;
|
||||||
--bs-focus-ring-opacity: 0.25;
|
--bs-focus-ring-opacity: 0.25;
|
||||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||||
--bs-form-valid-color: #198754;
|
--bs-form-valid-color: #198754;
|
||||||
--bs-form-valid-border-color: #198754;
|
--bs-form-valid-border-color: #198754;
|
||||||
--bs-form-invalid-color: #dc3545;
|
--bs-form-invalid-color: #dc3545;
|
||||||
--bs-form-invalid-border-color: #dc3545;
|
--bs-form-invalid-border-color: #dc3545;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-bs-theme=dark] {
|
[data-bs-theme=dark] {
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
--bs-body-color: #dee2e6;
|
--bs-body-color: #dee2e6;
|
||||||
--bs-body-color-rgb: 222, 226, 230;
|
--bs-body-color-rgb: 222, 226, 230;
|
||||||
--bs-body-bg: #212529;
|
--bs-body-bg: #212529;
|
||||||
--bs-body-bg-rgb: 33, 37, 41;
|
--bs-body-bg-rgb: 33, 37, 41;
|
||||||
--bs-emphasis-color: #fff;
|
--bs-emphasis-color: #fff;
|
||||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||||
--bs-secondary-color-rgb: 222, 226, 230;
|
--bs-secondary-color-rgb: 222, 226, 230;
|
||||||
--bs-secondary-bg: #343a40;
|
--bs-secondary-bg: #343a40;
|
||||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||||
--bs-tertiary-bg: #2b3035;
|
--bs-tertiary-bg: #2b3035;
|
||||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||||
--bs-primary-text-emphasis: #6ea8fe;
|
--bs-primary-text-emphasis: #6ea8fe;
|
||||||
--bs-secondary-text-emphasis: #a7acb1;
|
--bs-secondary-text-emphasis: #a7acb1;
|
||||||
--bs-success-text-emphasis: #75b798;
|
--bs-success-text-emphasis: #75b798;
|
||||||
--bs-info-text-emphasis: #6edff6;
|
--bs-info-text-emphasis: #6edff6;
|
||||||
--bs-warning-text-emphasis: #ffda6a;
|
--bs-warning-text-emphasis: #ffda6a;
|
||||||
--bs-danger-text-emphasis: #ea868f;
|
--bs-danger-text-emphasis: #ea868f;
|
||||||
--bs-light-text-emphasis: #f8f9fa;
|
--bs-light-text-emphasis: #f8f9fa;
|
||||||
--bs-dark-text-emphasis: #dee2e6;
|
--bs-dark-text-emphasis: #dee2e6;
|
||||||
--bs-primary-bg-subtle: #031633;
|
--bs-primary-bg-subtle: #031633;
|
||||||
--bs-secondary-bg-subtle: #161719;
|
--bs-secondary-bg-subtle: #161719;
|
||||||
--bs-success-bg-subtle: #051b11;
|
--bs-success-bg-subtle: #051b11;
|
||||||
--bs-info-bg-subtle: #032830;
|
--bs-info-bg-subtle: #032830;
|
||||||
--bs-warning-bg-subtle: #332701;
|
--bs-warning-bg-subtle: #332701;
|
||||||
--bs-danger-bg-subtle: #2c0b0e;
|
--bs-danger-bg-subtle: #2c0b0e;
|
||||||
--bs-light-bg-subtle: #343a40;
|
--bs-light-bg-subtle: #343a40;
|
||||||
--bs-dark-bg-subtle: #1a1d20;
|
--bs-dark-bg-subtle: #1a1d20;
|
||||||
--bs-primary-border-subtle: #084298;
|
--bs-primary-border-subtle: #084298;
|
||||||
--bs-secondary-border-subtle: #41464b;
|
--bs-secondary-border-subtle: #41464b;
|
||||||
--bs-success-border-subtle: #0f5132;
|
--bs-success-border-subtle: #0f5132;
|
||||||
--bs-info-border-subtle: #087990;
|
--bs-info-border-subtle: #087990;
|
||||||
--bs-warning-border-subtle: #997404;
|
--bs-warning-border-subtle: #997404;
|
||||||
--bs-danger-border-subtle: #842029;
|
--bs-danger-border-subtle: #842029;
|
||||||
--bs-light-border-subtle: #495057;
|
--bs-light-border-subtle: #495057;
|
||||||
--bs-dark-border-subtle: #343a40;
|
--bs-dark-border-subtle: #343a40;
|
||||||
--bs-heading-color: inherit;
|
--bs-heading-color: inherit;
|
||||||
--bs-link-color: #6ea8fe;
|
--bs-link-color: #6ea8fe;
|
||||||
--bs-link-hover-color: #8bb9fe;
|
--bs-link-hover-color: #8bb9fe;
|
||||||
--bs-link-color-rgb: 110, 168, 254;
|
--bs-link-color-rgb: 110, 168, 254;
|
||||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||||
--bs-code-color: #e685b5;
|
--bs-code-color: #e685b5;
|
||||||
--bs-highlight-color: #dee2e6;
|
--bs-highlight-color: #dee2e6;
|
||||||
--bs-highlight-bg: #664d03;
|
--bs-highlight-bg: #664d03;
|
||||||
--bs-border-color: #495057;
|
--bs-border-color: #495057;
|
||||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
--bs-form-valid-color: #75b798;
|
--bs-form-valid-color: #75b798;
|
||||||
--bs-form-valid-border-color: #75b798;
|
--bs-form-valid-border-color: #75b798;
|
||||||
--bs-form-invalid-color: #ea868f;
|
--bs-form-invalid-color: #ea868f;
|
||||||
--bs-form-invalid-border-color: #ea868f;
|
--bs-form-invalid-border-color: #ea868f;
|
||||||
}
|
}
|
||||||
|
|
||||||
*,
|
*,
|
||||||
*::before,
|
*::before,
|
||||||
*::after {
|
*::after {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
:root {
|
:root {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: var(--bs-body-font-family);
|
font-family: var(--bs-body-font-family);
|
||||||
font-size: var(--bs-body-font-size);
|
font-size: var(--bs-body-font-size);
|
||||||
font-weight: var(--bs-body-font-weight);
|
font-weight: var(--bs-body-font-weight);
|
||||||
line-height: var(--bs-body-line-height);
|
line-height: var(--bs-body-line-height);
|
||||||
color: var(--bs-body-color);
|
color: var(--bs-body-color);
|
||||||
text-align: var(--bs-body-text-align);
|
text-align: var(--bs-body-text-align);
|
||||||
background-color: var(--bs-body-bg);
|
background-color: var(--bs-body-bg);
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-top: var(--bs-border-width) solid;
|
border-top: var(--bs-border-width) solid;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
h6, h5, h4, h3, h2, h1 {
|
h6, h5, h4, h3, h2, h1 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
color: var(--bs-heading-color);
|
color: var(--bs-heading-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: calc(1.375rem + 1.5vw);
|
font-size: calc(1.375rem + 1.5vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: calc(1.325rem + 0.9vw);
|
font-size: calc(1.325rem + 0.9vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: calc(1.3rem + 0.6vw);
|
font-size: calc(1.3rem + 0.6vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h4 {
|
h4 {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
abbr[title] {
|
abbr[title] {
|
||||||
-webkit-text-decoration: underline dotted;
|
-webkit-text-decoration: underline dotted;
|
||||||
text-decoration: underline dotted;
|
text-decoration: underline dotted;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
-webkit-text-decoration-skip-ink: none;
|
-webkit-text-decoration-skip-ink: none;
|
||||||
text-decoration-skip-ink: none;
|
text-decoration-skip-ink: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
address {
|
address {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul {
|
ul {
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul,
|
ul,
|
||||||
dl {
|
dl {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol ol,
|
ol ol,
|
||||||
ul ul,
|
ul ul,
|
||||||
ol ul,
|
ol ul,
|
||||||
ul ol {
|
ul ol {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt {
|
dt {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd {
|
dd {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
b,
|
b,
|
||||||
strong {
|
strong {
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small {
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
}
|
}
|
||||||
|
|
||||||
mark {
|
mark {
|
||||||
padding: 0.1875em;
|
padding: 0.1875em;
|
||||||
color: var(--bs-highlight-color);
|
color: var(--bs-highlight-color);
|
||||||
background-color: var(--bs-highlight-bg);
|
background-color: var(--bs-highlight-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub,
|
sub,
|
||||||
sup {
|
sup {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub {
|
sub {
|
||||||
bottom: -0.25em;
|
bottom: -0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
sup {
|
sup {
|
||||||
top: -0.5em;
|
top: -0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre,
|
pre,
|
||||||
code,
|
code,
|
||||||
kbd,
|
kbd,
|
||||||
samp {
|
samp {
|
||||||
font-family: var(--bs-font-monospace);
|
font-family: var(--bs-font-monospace);
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre code {
|
pre code {
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
word-break: normal;
|
word-break: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
color: var(--bs-code-color);
|
color: var(--bs-code-color);
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
a > code {
|
a > code {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd {
|
kbd {
|
||||||
padding: 0.1875rem 0.375rem;
|
padding: 0.1875rem 0.375rem;
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
color: var(--bs-body-bg);
|
color: var(--bs-body-bg);
|
||||||
background-color: var(--bs-body-color);
|
background-color: var(--bs-body-color);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd kbd {
|
kbd kbd {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
img,
|
img,
|
||||||
svg {
|
svg {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
caption-side: bottom;
|
caption-side: bottom;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
caption {
|
caption {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
color: var(--bs-secondary-color);
|
color: var(--bs-secondary-color);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
text-align: inherit;
|
text-align: inherit;
|
||||||
text-align: -webkit-match-parent;
|
text-align: -webkit-match-parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
thead,
|
thead,
|
||||||
@@ -434,21 +442,21 @@ tfoot,
|
|||||||
tr,
|
tr,
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
border-color: inherit;
|
border-color: inherit;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:focus:not(:focus-visible) {
|
button:focus:not(:focus-visible) {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
@@ -456,76 +464,80 @@ button,
|
|||||||
select,
|
select,
|
||||||
optgroup,
|
optgroup,
|
||||||
textarea {
|
textarea {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
select {
|
select {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[role=button] {
|
[role=button] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
word-wrap: normal;
|
word-wrap: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
select:disabled {
|
select:disabled {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
[type=button],
|
[type=button],
|
||||||
[type=reset],
|
[type=reset],
|
||||||
[type=submit] {
|
[type=submit] {
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:not(:disabled),
|
button:not(:disabled),
|
||||||
[type=button]:not(:disabled),
|
[type=button]:not(:disabled),
|
||||||
[type=reset]:not(:disabled),
|
[type=reset]:not(:disabled),
|
||||||
[type=submit]:not(:disabled) {
|
[type=submit]:not(:disabled) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-moz-focus-inner {
|
::-moz-focus-inner {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
legend {
|
legend {
|
||||||
float: left;
|
float: left;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
legend {
|
legend {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
legend + * {
|
legend + * {
|
||||||
clear: left;
|
clear: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-datetime-edit-fields-wrapper,
|
::-webkit-datetime-edit-fields-wrapper,
|
||||||
@@ -535,16 +547,16 @@ legend + * {
|
|||||||
::-webkit-datetime-edit-day-field,
|
::-webkit-datetime-edit-day-field,
|
||||||
::-webkit-datetime-edit-month-field,
|
::-webkit-datetime-edit-month-field,
|
||||||
::-webkit-datetime-edit-year-field {
|
::-webkit-datetime-edit-year-field {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-inner-spin-button {
|
::-webkit-inner-spin-button {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
[type=search] {
|
[type=search] {
|
||||||
-webkit-appearance: textfield;
|
-webkit-appearance: textfield;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rtl:raw:
|
/* rtl:raw:
|
||||||
@@ -556,42 +568,42 @@ legend + * {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
::-webkit-search-decoration {
|
::-webkit-search-decoration {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-color-swatch-wrapper {
|
::-webkit-color-swatch-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-file-upload-button {
|
::-webkit-file-upload-button {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
::file-selector-button {
|
::file-selector-button {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
output {
|
output {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
summary {
|
summary {
|
||||||
display: list-item;
|
display: list-item;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress {
|
progress {
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
[hidden] {
|
[hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||||
+342
-328
@@ -5,427 +5,435 @@
|
|||||||
*/
|
*/
|
||||||
:root,
|
:root,
|
||||||
[data-bs-theme=light] {
|
[data-bs-theme=light] {
|
||||||
--bs-blue: #0d6efd;
|
--bs-blue: #0d6efd;
|
||||||
--bs-indigo: #6610f2;
|
--bs-indigo: #6610f2;
|
||||||
--bs-purple: #6f42c1;
|
--bs-purple: #6f42c1;
|
||||||
--bs-pink: #d63384;
|
--bs-pink: #d63384;
|
||||||
--bs-red: #dc3545;
|
--bs-red: #dc3545;
|
||||||
--bs-orange: #fd7e14;
|
--bs-orange: #fd7e14;
|
||||||
--bs-yellow: #ffc107;
|
--bs-yellow: #ffc107;
|
||||||
--bs-green: #198754;
|
--bs-green: #198754;
|
||||||
--bs-teal: #20c997;
|
--bs-teal: #20c997;
|
||||||
--bs-cyan: #0dcaf0;
|
--bs-cyan: #0dcaf0;
|
||||||
--bs-black: #000;
|
--bs-black: #000;
|
||||||
--bs-white: #fff;
|
--bs-white: #fff;
|
||||||
--bs-gray: #6c757d;
|
--bs-gray: #6c757d;
|
||||||
--bs-gray-dark: #343a40;
|
--bs-gray-dark: #343a40;
|
||||||
--bs-gray-100: #f8f9fa;
|
--bs-gray-100: #f8f9fa;
|
||||||
--bs-gray-200: #e9ecef;
|
--bs-gray-200: #e9ecef;
|
||||||
--bs-gray-300: #dee2e6;
|
--bs-gray-300: #dee2e6;
|
||||||
--bs-gray-400: #ced4da;
|
--bs-gray-400: #ced4da;
|
||||||
--bs-gray-500: #adb5bd;
|
--bs-gray-500: #adb5bd;
|
||||||
--bs-gray-600: #6c757d;
|
--bs-gray-600: #6c757d;
|
||||||
--bs-gray-700: #495057;
|
--bs-gray-700: #495057;
|
||||||
--bs-gray-800: #343a40;
|
--bs-gray-800: #343a40;
|
||||||
--bs-gray-900: #212529;
|
--bs-gray-900: #212529;
|
||||||
--bs-primary: #0d6efd;
|
--bs-primary: #0d6efd;
|
||||||
--bs-secondary: #6c757d;
|
--bs-secondary: #6c757d;
|
||||||
--bs-success: #198754;
|
--bs-success: #198754;
|
||||||
--bs-info: #0dcaf0;
|
--bs-info: #0dcaf0;
|
||||||
--bs-warning: #ffc107;
|
--bs-warning: #ffc107;
|
||||||
--bs-danger: #dc3545;
|
--bs-danger: #dc3545;
|
||||||
--bs-light: #f8f9fa;
|
--bs-light: #f8f9fa;
|
||||||
--bs-dark: #212529;
|
--bs-dark: #212529;
|
||||||
--bs-primary-rgb: 13, 110, 253;
|
--bs-primary-rgb: 13, 110, 253;
|
||||||
--bs-secondary-rgb: 108, 117, 125;
|
--bs-secondary-rgb: 108, 117, 125;
|
||||||
--bs-success-rgb: 25, 135, 84;
|
--bs-success-rgb: 25, 135, 84;
|
||||||
--bs-info-rgb: 13, 202, 240;
|
--bs-info-rgb: 13, 202, 240;
|
||||||
--bs-warning-rgb: 255, 193, 7;
|
--bs-warning-rgb: 255, 193, 7;
|
||||||
--bs-danger-rgb: 220, 53, 69;
|
--bs-danger-rgb: 220, 53, 69;
|
||||||
--bs-light-rgb: 248, 249, 250;
|
--bs-light-rgb: 248, 249, 250;
|
||||||
--bs-dark-rgb: 33, 37, 41;
|
--bs-dark-rgb: 33, 37, 41;
|
||||||
--bs-primary-text-emphasis: #052c65;
|
--bs-primary-text-emphasis: #052c65;
|
||||||
--bs-secondary-text-emphasis: #2b2f32;
|
--bs-secondary-text-emphasis: #2b2f32;
|
||||||
--bs-success-text-emphasis: #0a3622;
|
--bs-success-text-emphasis: #0a3622;
|
||||||
--bs-info-text-emphasis: #055160;
|
--bs-info-text-emphasis: #055160;
|
||||||
--bs-warning-text-emphasis: #664d03;
|
--bs-warning-text-emphasis: #664d03;
|
||||||
--bs-danger-text-emphasis: #58151c;
|
--bs-danger-text-emphasis: #58151c;
|
||||||
--bs-light-text-emphasis: #495057;
|
--bs-light-text-emphasis: #495057;
|
||||||
--bs-dark-text-emphasis: #495057;
|
--bs-dark-text-emphasis: #495057;
|
||||||
--bs-primary-bg-subtle: #cfe2ff;
|
--bs-primary-bg-subtle: #cfe2ff;
|
||||||
--bs-secondary-bg-subtle: #e2e3e5;
|
--bs-secondary-bg-subtle: #e2e3e5;
|
||||||
--bs-success-bg-subtle: #d1e7dd;
|
--bs-success-bg-subtle: #d1e7dd;
|
||||||
--bs-info-bg-subtle: #cff4fc;
|
--bs-info-bg-subtle: #cff4fc;
|
||||||
--bs-warning-bg-subtle: #fff3cd;
|
--bs-warning-bg-subtle: #fff3cd;
|
||||||
--bs-danger-bg-subtle: #f8d7da;
|
--bs-danger-bg-subtle: #f8d7da;
|
||||||
--bs-light-bg-subtle: #fcfcfd;
|
--bs-light-bg-subtle: #fcfcfd;
|
||||||
--bs-dark-bg-subtle: #ced4da;
|
--bs-dark-bg-subtle: #ced4da;
|
||||||
--bs-primary-border-subtle: #9ec5fe;
|
--bs-primary-border-subtle: #9ec5fe;
|
||||||
--bs-secondary-border-subtle: #c4c8cb;
|
--bs-secondary-border-subtle: #c4c8cb;
|
||||||
--bs-success-border-subtle: #a3cfbb;
|
--bs-success-border-subtle: #a3cfbb;
|
||||||
--bs-info-border-subtle: #9eeaf9;
|
--bs-info-border-subtle: #9eeaf9;
|
||||||
--bs-warning-border-subtle: #ffe69c;
|
--bs-warning-border-subtle: #ffe69c;
|
||||||
--bs-danger-border-subtle: #f1aeb5;
|
--bs-danger-border-subtle: #f1aeb5;
|
||||||
--bs-light-border-subtle: #e9ecef;
|
--bs-light-border-subtle: #e9ecef;
|
||||||
--bs-dark-border-subtle: #adb5bd;
|
--bs-dark-border-subtle: #adb5bd;
|
||||||
--bs-white-rgb: 255, 255, 255;
|
--bs-white-rgb: 255, 255, 255;
|
||||||
--bs-black-rgb: 0, 0, 0;
|
--bs-black-rgb: 0, 0, 0;
|
||||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||||
--bs-body-font-size: 1rem;
|
--bs-body-font-size: 1rem;
|
||||||
--bs-body-font-weight: 400;
|
--bs-body-font-weight: 400;
|
||||||
--bs-body-line-height: 1.5;
|
--bs-body-line-height: 1.5;
|
||||||
--bs-body-color: #212529;
|
--bs-body-color: #212529;
|
||||||
--bs-body-color-rgb: 33, 37, 41;
|
--bs-body-color-rgb: 33, 37, 41;
|
||||||
--bs-body-bg: #fff;
|
--bs-body-bg: #fff;
|
||||||
--bs-body-bg-rgb: 255, 255, 255;
|
--bs-body-bg-rgb: 255, 255, 255;
|
||||||
--bs-emphasis-color: #000;
|
--bs-emphasis-color: #000;
|
||||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||||
--bs-secondary-color-rgb: 33, 37, 41;
|
--bs-secondary-color-rgb: 33, 37, 41;
|
||||||
--bs-secondary-bg: #e9ecef;
|
--bs-secondary-bg: #e9ecef;
|
||||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||||
--bs-tertiary-bg: #f8f9fa;
|
--bs-tertiary-bg: #f8f9fa;
|
||||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||||
--bs-heading-color: inherit;
|
--bs-heading-color: inherit;
|
||||||
--bs-link-color: #0d6efd;
|
--bs-link-color: #0d6efd;
|
||||||
--bs-link-color-rgb: 13, 110, 253;
|
--bs-link-color-rgb: 13, 110, 253;
|
||||||
--bs-link-decoration: underline;
|
--bs-link-decoration: underline;
|
||||||
--bs-link-hover-color: #0a58ca;
|
--bs-link-hover-color: #0a58ca;
|
||||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||||
--bs-code-color: #d63384;
|
--bs-code-color: #d63384;
|
||||||
--bs-highlight-color: #212529;
|
--bs-highlight-color: #212529;
|
||||||
--bs-highlight-bg: #fff3cd;
|
--bs-highlight-bg: #fff3cd;
|
||||||
--bs-border-width: 1px;
|
--bs-border-width: 1px;
|
||||||
--bs-border-style: solid;
|
--bs-border-style: solid;
|
||||||
--bs-border-color: #dee2e6;
|
--bs-border-color: #dee2e6;
|
||||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||||
--bs-border-radius: 0.375rem;
|
--bs-border-radius: 0.375rem;
|
||||||
--bs-border-radius-sm: 0.25rem;
|
--bs-border-radius-sm: 0.25rem;
|
||||||
--bs-border-radius-lg: 0.5rem;
|
--bs-border-radius-lg: 0.5rem;
|
||||||
--bs-border-radius-xl: 1rem;
|
--bs-border-radius-xl: 1rem;
|
||||||
--bs-border-radius-xxl: 2rem;
|
--bs-border-radius-xxl: 2rem;
|
||||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||||
--bs-border-radius-pill: 50rem;
|
--bs-border-radius-pill: 50rem;
|
||||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||||
--bs-focus-ring-width: 0.25rem;
|
--bs-focus-ring-width: 0.25rem;
|
||||||
--bs-focus-ring-opacity: 0.25;
|
--bs-focus-ring-opacity: 0.25;
|
||||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||||
--bs-form-valid-color: #198754;
|
--bs-form-valid-color: #198754;
|
||||||
--bs-form-valid-border-color: #198754;
|
--bs-form-valid-border-color: #198754;
|
||||||
--bs-form-invalid-color: #dc3545;
|
--bs-form-invalid-color: #dc3545;
|
||||||
--bs-form-invalid-border-color: #dc3545;
|
--bs-form-invalid-border-color: #dc3545;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-bs-theme=dark] {
|
[data-bs-theme=dark] {
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
--bs-body-color: #dee2e6;
|
--bs-body-color: #dee2e6;
|
||||||
--bs-body-color-rgb: 222, 226, 230;
|
--bs-body-color-rgb: 222, 226, 230;
|
||||||
--bs-body-bg: #212529;
|
--bs-body-bg: #212529;
|
||||||
--bs-body-bg-rgb: 33, 37, 41;
|
--bs-body-bg-rgb: 33, 37, 41;
|
||||||
--bs-emphasis-color: #fff;
|
--bs-emphasis-color: #fff;
|
||||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||||
--bs-secondary-color-rgb: 222, 226, 230;
|
--bs-secondary-color-rgb: 222, 226, 230;
|
||||||
--bs-secondary-bg: #343a40;
|
--bs-secondary-bg: #343a40;
|
||||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||||
--bs-tertiary-bg: #2b3035;
|
--bs-tertiary-bg: #2b3035;
|
||||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||||
--bs-primary-text-emphasis: #6ea8fe;
|
--bs-primary-text-emphasis: #6ea8fe;
|
||||||
--bs-secondary-text-emphasis: #a7acb1;
|
--bs-secondary-text-emphasis: #a7acb1;
|
||||||
--bs-success-text-emphasis: #75b798;
|
--bs-success-text-emphasis: #75b798;
|
||||||
--bs-info-text-emphasis: #6edff6;
|
--bs-info-text-emphasis: #6edff6;
|
||||||
--bs-warning-text-emphasis: #ffda6a;
|
--bs-warning-text-emphasis: #ffda6a;
|
||||||
--bs-danger-text-emphasis: #ea868f;
|
--bs-danger-text-emphasis: #ea868f;
|
||||||
--bs-light-text-emphasis: #f8f9fa;
|
--bs-light-text-emphasis: #f8f9fa;
|
||||||
--bs-dark-text-emphasis: #dee2e6;
|
--bs-dark-text-emphasis: #dee2e6;
|
||||||
--bs-primary-bg-subtle: #031633;
|
--bs-primary-bg-subtle: #031633;
|
||||||
--bs-secondary-bg-subtle: #161719;
|
--bs-secondary-bg-subtle: #161719;
|
||||||
--bs-success-bg-subtle: #051b11;
|
--bs-success-bg-subtle: #051b11;
|
||||||
--bs-info-bg-subtle: #032830;
|
--bs-info-bg-subtle: #032830;
|
||||||
--bs-warning-bg-subtle: #332701;
|
--bs-warning-bg-subtle: #332701;
|
||||||
--bs-danger-bg-subtle: #2c0b0e;
|
--bs-danger-bg-subtle: #2c0b0e;
|
||||||
--bs-light-bg-subtle: #343a40;
|
--bs-light-bg-subtle: #343a40;
|
||||||
--bs-dark-bg-subtle: #1a1d20;
|
--bs-dark-bg-subtle: #1a1d20;
|
||||||
--bs-primary-border-subtle: #084298;
|
--bs-primary-border-subtle: #084298;
|
||||||
--bs-secondary-border-subtle: #41464b;
|
--bs-secondary-border-subtle: #41464b;
|
||||||
--bs-success-border-subtle: #0f5132;
|
--bs-success-border-subtle: #0f5132;
|
||||||
--bs-info-border-subtle: #087990;
|
--bs-info-border-subtle: #087990;
|
||||||
--bs-warning-border-subtle: #997404;
|
--bs-warning-border-subtle: #997404;
|
||||||
--bs-danger-border-subtle: #842029;
|
--bs-danger-border-subtle: #842029;
|
||||||
--bs-light-border-subtle: #495057;
|
--bs-light-border-subtle: #495057;
|
||||||
--bs-dark-border-subtle: #343a40;
|
--bs-dark-border-subtle: #343a40;
|
||||||
--bs-heading-color: inherit;
|
--bs-heading-color: inherit;
|
||||||
--bs-link-color: #6ea8fe;
|
--bs-link-color: #6ea8fe;
|
||||||
--bs-link-hover-color: #8bb9fe;
|
--bs-link-hover-color: #8bb9fe;
|
||||||
--bs-link-color-rgb: 110, 168, 254;
|
--bs-link-color-rgb: 110, 168, 254;
|
||||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||||
--bs-code-color: #e685b5;
|
--bs-code-color: #e685b5;
|
||||||
--bs-highlight-color: #dee2e6;
|
--bs-highlight-color: #dee2e6;
|
||||||
--bs-highlight-bg: #664d03;
|
--bs-highlight-bg: #664d03;
|
||||||
--bs-border-color: #495057;
|
--bs-border-color: #495057;
|
||||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
--bs-form-valid-color: #75b798;
|
--bs-form-valid-color: #75b798;
|
||||||
--bs-form-valid-border-color: #75b798;
|
--bs-form-valid-border-color: #75b798;
|
||||||
--bs-form-invalid-color: #ea868f;
|
--bs-form-invalid-color: #ea868f;
|
||||||
--bs-form-invalid-border-color: #ea868f;
|
--bs-form-invalid-border-color: #ea868f;
|
||||||
}
|
}
|
||||||
|
|
||||||
*,
|
*,
|
||||||
*::before,
|
*::before,
|
||||||
*::after {
|
*::after {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
:root {
|
:root {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: var(--bs-body-font-family);
|
font-family: var(--bs-body-font-family);
|
||||||
font-size: var(--bs-body-font-size);
|
font-size: var(--bs-body-font-size);
|
||||||
font-weight: var(--bs-body-font-weight);
|
font-weight: var(--bs-body-font-weight);
|
||||||
line-height: var(--bs-body-line-height);
|
line-height: var(--bs-body-line-height);
|
||||||
color: var(--bs-body-color);
|
color: var(--bs-body-color);
|
||||||
text-align: var(--bs-body-text-align);
|
text-align: var(--bs-body-text-align);
|
||||||
background-color: var(--bs-body-bg);
|
background-color: var(--bs-body-bg);
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-top: var(--bs-border-width) solid;
|
border-top: var(--bs-border-width) solid;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
h6, h5, h4, h3, h2, h1 {
|
h6, h5, h4, h3, h2, h1 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
color: var(--bs-heading-color);
|
color: var(--bs-heading-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: calc(1.375rem + 1.5vw);
|
font-size: calc(1.375rem + 1.5vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: calc(1.325rem + 0.9vw);
|
font-size: calc(1.325rem + 0.9vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: calc(1.3rem + 0.6vw);
|
font-size: calc(1.3rem + 0.6vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
h4 {
|
h4 {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
abbr[title] {
|
abbr[title] {
|
||||||
-webkit-text-decoration: underline dotted;
|
-webkit-text-decoration: underline dotted;
|
||||||
text-decoration: underline dotted;
|
text-decoration: underline dotted;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
-webkit-text-decoration-skip-ink: none;
|
-webkit-text-decoration-skip-ink: none;
|
||||||
text-decoration-skip-ink: none;
|
text-decoration-skip-ink: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
address {
|
address {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul {
|
ul {
|
||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul,
|
ul,
|
||||||
dl {
|
dl {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol ol,
|
ol ol,
|
||||||
ul ul,
|
ul ul,
|
||||||
ol ul,
|
ol ul,
|
||||||
ul ol {
|
ul ol {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt {
|
dt {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd {
|
dd {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
b,
|
b,
|
||||||
strong {
|
strong {
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small {
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
}
|
}
|
||||||
|
|
||||||
mark {
|
mark {
|
||||||
padding: 0.1875em;
|
padding: 0.1875em;
|
||||||
color: var(--bs-highlight-color);
|
color: var(--bs-highlight-color);
|
||||||
background-color: var(--bs-highlight-bg);
|
background-color: var(--bs-highlight-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub,
|
sub,
|
||||||
sup {
|
sup {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub {
|
sub {
|
||||||
bottom: -0.25em;
|
bottom: -0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
sup {
|
sup {
|
||||||
top: -0.5em;
|
top: -0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre,
|
pre,
|
||||||
code,
|
code,
|
||||||
kbd,
|
kbd,
|
||||||
samp {
|
samp {
|
||||||
font-family: var(--bs-font-monospace);
|
font-family: var(--bs-font-monospace);
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre code {
|
pre code {
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
word-break: normal;
|
word-break: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
color: var(--bs-code-color);
|
color: var(--bs-code-color);
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
a > code {
|
a > code {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd {
|
kbd {
|
||||||
padding: 0.1875rem 0.375rem;
|
padding: 0.1875rem 0.375rem;
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
color: var(--bs-body-bg);
|
color: var(--bs-body-bg);
|
||||||
background-color: var(--bs-body-color);
|
background-color: var(--bs-body-color);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd kbd {
|
kbd kbd {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
img,
|
img,
|
||||||
svg {
|
svg {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
caption-side: bottom;
|
caption-side: bottom;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
caption {
|
caption {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
color: var(--bs-secondary-color);
|
color: var(--bs-secondary-color);
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
text-align: inherit;
|
text-align: inherit;
|
||||||
text-align: -webkit-match-parent;
|
text-align: -webkit-match-parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
thead,
|
thead,
|
||||||
@@ -434,21 +442,21 @@ tfoot,
|
|||||||
tr,
|
tr,
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
border-color: inherit;
|
border-color: inherit;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:focus:not(:focus-visible) {
|
button:focus:not(:focus-visible) {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
@@ -456,76 +464,80 @@ button,
|
|||||||
select,
|
select,
|
||||||
optgroup,
|
optgroup,
|
||||||
textarea {
|
textarea {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
select {
|
select {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[role=button] {
|
[role=button] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
word-wrap: normal;
|
word-wrap: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
select:disabled {
|
select:disabled {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
[type=button],
|
[type=button],
|
||||||
[type=reset],
|
[type=reset],
|
||||||
[type=submit] {
|
[type=submit] {
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:not(:disabled),
|
button:not(:disabled),
|
||||||
[type=button]:not(:disabled),
|
[type=button]:not(:disabled),
|
||||||
[type=reset]:not(:disabled),
|
[type=reset]:not(:disabled),
|
||||||
[type=submit]:not(:disabled) {
|
[type=submit]:not(:disabled) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-moz-focus-inner {
|
::-moz-focus-inner {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
legend {
|
legend {
|
||||||
float: right;
|
float: right;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
legend {
|
legend {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
legend + * {
|
legend + * {
|
||||||
clear: right;
|
clear: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-datetime-edit-fields-wrapper,
|
::-webkit-datetime-edit-fields-wrapper,
|
||||||
@@ -535,60 +547,62 @@ legend + * {
|
|||||||
::-webkit-datetime-edit-day-field,
|
::-webkit-datetime-edit-day-field,
|
||||||
::-webkit-datetime-edit-month-field,
|
::-webkit-datetime-edit-month-field,
|
||||||
::-webkit-datetime-edit-year-field {
|
::-webkit-datetime-edit-year-field {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-inner-spin-button {
|
::-webkit-inner-spin-button {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
[type=search] {
|
[type=search] {
|
||||||
-webkit-appearance: textfield;
|
-webkit-appearance: textfield;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[type="tel"],
|
[type="tel"],
|
||||||
[type="url"],
|
[type="url"],
|
||||||
[type="email"],
|
[type="email"],
|
||||||
[type="number"] {
|
[type="number"] {
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-search-decoration {
|
::-webkit-search-decoration {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-color-swatch-wrapper {
|
::-webkit-color-swatch-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-file-upload-button {
|
::-webkit-file-upload-button {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
::file-selector-button {
|
::file-selector-button {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
output {
|
output {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
summary {
|
summary {
|
||||||
display: list-item;
|
display: list-item;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress {
|
progress {
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
[hidden] {
|
[hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
||||||
+4740
-3832
File diff suppressed because it is too large
Load Diff
+4740
-3830
File diff suppressed because it is too large
Load Diff
+10002
-8338
File diff suppressed because it is too large
Load Diff
+10012
-8337
File diff suppressed because it is too large
Load Diff
+6340
-6144
File diff suppressed because it is too large
Load Diff
+3421
-3232
File diff suppressed because it is too large
Load Diff
+4602
-4412
File diff suppressed because it is too large
Load Diff
@@ -5,5 +5,5 @@ public class DocData
|
|||||||
public string Title { get; init; } = "";
|
public string Title { get; init; } = "";
|
||||||
public string Category { get; init; } = "";
|
public string Category { get; init; } = "";
|
||||||
public string Content { get; init; } = "";
|
public string Content { get; init; } = "";
|
||||||
public System.Collections.Generic.Dictionary<string, string> Frontmatter { get; init; } = [];
|
public Dictionary<string, string> Frontmatter { get; init; } = [];
|
||||||
}
|
}
|
||||||
@@ -20,8 +20,8 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<Routes />
|
<Routes/>
|
||||||
<script src="_framework/blazor.web.js"></script>
|
<script src="_framework/blazor.web.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Shared.Pages.Home).Assembly }">
|
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly }">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
||||||
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Server;
|
using Server;
|
||||||
|
using Server.Components;
|
||||||
|
using Shared.Pages;
|
||||||
|
using Shared.Services;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -7,7 +10,7 @@ builder.Services.AddControllers();
|
|||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
|
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
|
||||||
builder.Services.AddTelerikBlazor();
|
builder.Services.AddTelerikBlazor();
|
||||||
builder.Services.AddSingleton<Shared.Services.CardRenderingService>();
|
builder.Services.AddSingleton<CardRenderingService>();
|
||||||
|
|
||||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||||
builder.Services.AddDbContext<AppDbContext>(options =>
|
builder.Services.AddDbContext<AppDbContext>(options =>
|
||||||
@@ -32,17 +35,14 @@ using (var scope = app.Services.CreateScope())
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!app.Environment.IsDevelopment())
|
if (!app.Environment.IsDevelopment()) app.UseExceptionHandler("/Error");
|
||||||
{
|
|
||||||
app.UseExceptionHandler("/Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseAntiforgery();
|
app.UseAntiforgery();
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
app.MapRazorComponents<Server.Components.App>()
|
app.MapRazorComponents<App>()
|
||||||
.AddInteractiveServerRenderMode()
|
.AddInteractiveServerRenderMode()
|
||||||
.AddAdditionalAssemblies(typeof(Shared.Pages.Home).Assembly);
|
.AddAdditionalAssemblies(typeof(Home).Assembly);
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -257,9 +257,6 @@ a, .btn-link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.inline-card-btn {
|
.inline-card-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
@namespace Shared.Components
|
@namespace Shared.Components
|
||||||
@using Chrono.Model
|
|
||||||
|
|
||||||
@if (Card != null)
|
@if (Card != null)
|
||||||
{
|
{
|
||||||
@@ -11,7 +10,7 @@
|
|||||||
{
|
{
|
||||||
<div class="detail-image">
|
<div class="detail-image">
|
||||||
<img src="@Card.ImagePath" alt="@Card.Name"
|
<img src="@Card.ImagePath" alt="@Card.Name"
|
||||||
onerror="this.style.display='none';this.parentElement.style.display='none'" />
|
onerror="this.style.display='none';this.parentElement.style.display='none'"/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="detail-info">
|
<div class="detail-info">
|
||||||
@@ -105,7 +104,8 @@
|
|||||||
var target = LookupCard(targetName);
|
var target = LookupCard(targetName);
|
||||||
if (target != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
<button class="inline-card-btn" @onclick="() => SelectCard(target)">@targetName</button>
|
<button class="inline-card-btn"
|
||||||
|
@onclick="() => SelectCard(target)">@targetName</button>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -125,7 +125,8 @@
|
|||||||
var fromCard = LookupCard(Card.ImmortalizeFrom);
|
var fromCard = LookupCard(Card.ImmortalizeFrom);
|
||||||
if (fromCard != null)
|
if (fromCard != null)
|
||||||
{
|
{
|
||||||
<button class="inline-card-btn" @onclick="() => SelectCard(fromCard)">@Card.ImmortalizeFrom</button>
|
<button class="inline-card-btn"
|
||||||
|
@onclick="() => SelectCard(fromCard)">@Card.ImmortalizeFrom</button>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -148,9 +149,15 @@
|
|||||||
|
|
||||||
private bool HasImage => Card?.ImageFile is { Length: > 0 } && Card.ImageFile != "placeholder.png";
|
private bool HasImage => Card?.ImageFile is { Length: > 0 } && Card.ImageFile != "placeholder.png";
|
||||||
|
|
||||||
private async Task Close() => await OnClose.InvokeAsync();
|
private async Task Close()
|
||||||
|
{
|
||||||
|
await OnClose.InvokeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SelectCard(CardData card) => await OnSelectCard.InvokeAsync(card);
|
private async Task SelectCard(CardData card)
|
||||||
|
{
|
||||||
|
await OnSelectCard.InvokeAsync(card);
|
||||||
|
}
|
||||||
|
|
||||||
private RenderFragment RenderCardDescription(string description)
|
private RenderFragment RenderCardDescription(string description)
|
||||||
{
|
{
|
||||||
@@ -163,4 +170,5 @@
|
|||||||
return CardDatabase.Cards.FirstOrDefault(c =>
|
return CardDatabase.Cards.FirstOrDefault(c =>
|
||||||
string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase));
|
string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
from { opacity: 0; }
|
from {
|
||||||
to { opacity: 1; }
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-detail {
|
.card-detail {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
@namespace Shared.Components
|
@namespace Shared.Components
|
||||||
@using Chrono.Model
|
|
||||||
|
|
||||||
<div class="deck-card-row">
|
<div class="deck-card-row">
|
||||||
@foreach (var group in Cards.GroupBy(x => x))
|
@foreach (var group in Cards.GroupBy(x => x))
|
||||||
@@ -29,10 +28,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter, EditorRequired] public List<string> Cards { get; set; } = [];
|
[Parameter][EditorRequired] public List<string> Cards { get; set; } = [];
|
||||||
[Parameter] public EventCallback<CardData?> OnSelectCard { get; set; }
|
[Parameter] public EventCallback<CardData?> OnSelectCard { get; set; }
|
||||||
|
|
||||||
private async Task SelectCard(CardData? card) => await OnSelectCard.InvokeAsync(card);
|
private async Task SelectCard(CardData? card)
|
||||||
|
{
|
||||||
|
await OnSelectCard.InvokeAsync(card);
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<string, CardData> CardLookup = CardDatabase.Cards
|
private static readonly Dictionary<string, CardData> CardLookup = CardDatabase.Cards
|
||||||
.Where(c => !string.IsNullOrWhiteSpace(c.Name))
|
.Where(c => !string.IsNullOrWhiteSpace(c.Name))
|
||||||
@@ -43,4 +45,5 @@
|
|||||||
{
|
{
|
||||||
return CardLookup.GetValueOrDefault(cardName);
|
return CardLookup.GetValueOrDefault(cardName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="mana-curve">
|
<div class="mana-curve">
|
||||||
@foreach (var entry in Distribution)
|
@foreach (var entry in Distribution)
|
||||||
{
|
{
|
||||||
var height = MaxCount > 0 ? (entry.Count * 100 / MaxCount) : 0;
|
var height = MaxCount > 0 ? entry.Count * 100 / MaxCount : 0;
|
||||||
<div class="mana-bar-container">
|
<div class="mana-bar-container">
|
||||||
<div class="mana-bar-label">@entry.Count</div>
|
<div class="mana-bar-label">@entry.Count</div>
|
||||||
<div class="mana-bar" style="height: @($"{Math.Max(height, 5)}%")"></div>
|
<div class="mana-bar" style="height: @($"{Math.Max(height, 5)}%")"></div>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter, EditorRequired] public List<(int Cost, int Count)> Distribution { get; set; } = [];
|
[Parameter][EditorRequired] public List<(int Cost, int Count)> Distribution { get; set; } = [];
|
||||||
[Parameter] public int MaxCostLabel { get; set; } = 10;
|
[Parameter] public int MaxCostLabel { get; set; } = 10;
|
||||||
|
|
||||||
private int MaxCount => Distribution.Count > 0 ? Distribution.Max(x => x.Count) : 0;
|
private int MaxCount => Distribution.Count > 0 ? Distribution.Max(x => x.Count) : 0;
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
@implements IDisposable
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject AnalyticsService AnalyticsService
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
NavigationManager.LocationChanged += OnLocationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnLocationChanged(object? sender, LocationChangedEventArgs e)
|
||||||
|
{
|
||||||
|
await TrackPageView(e.Location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task TrackPageView(string url)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var relativePath = NavigationManager.ToBaseRelativePath(url);
|
||||||
|
if (!relativePath.StartsWith("/"))
|
||||||
|
{
|
||||||
|
relativePath = "/" + relativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
await AnalyticsService.TrackPageView(relativePath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore errors during tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
NavigationManager.LocationChanged -= OnLocationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -154,7 +154,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Lifeblood",
|
Title = "Lifeblood",
|
||||||
Category = "Faction",
|
Category = "Faction",
|
||||||
Content = "Concepts:\r\n- Wide Boards\r\n- Overpower",
|
Content = "Concepts:\r\n\r\n- Wide Boards\r\n- Overpower",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Faction" },
|
{ "category", "Faction" },
|
||||||
@@ -164,7 +164,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Phasetide",
|
Title = "Phasetide",
|
||||||
Category = "Faction",
|
Category = "Faction",
|
||||||
Content = "Concepts:\r\n- Healing\r\n-",
|
Content = "Concepts:\r\n\r\n- Healing\r\n-",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Faction" },
|
{ "category", "Faction" },
|
||||||
@@ -174,7 +174,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Silence",
|
Title = "Silence",
|
||||||
Category = "Faction",
|
Category = "Faction",
|
||||||
Content = "Concepts:\r\n- Activatable Agents\r\n-",
|
Content = "Concepts:\r\n\r\n- Activatable Agents\r\n-",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Faction" },
|
{ "category", "Faction" },
|
||||||
@@ -184,7 +184,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Singularity",
|
Title = "Singularity",
|
||||||
Category = "Faction",
|
Category = "Faction",
|
||||||
Content = "Concepts:\r\n- Discard",
|
Content = "Concepts:\r\n\r\n- Discard",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Faction" },
|
{ "category", "Faction" },
|
||||||
@@ -194,7 +194,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Splintergleam",
|
Title = "Splintergleam",
|
||||||
Category = "Faction",
|
Category = "Faction",
|
||||||
Content = "# Self Damage\r\n\r\nCan hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.\r\n\r\n# Core Damage \r\n\r\nCan hurt both cores easily. Has [[Breakdown]] to take advantage of having an injured core for more damage.",
|
Content = "# Self Damage\r\n\r\nCan hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.\r\n\r\n# Core Damage\r\n\r\nCan hurt both cores easily. Has [[Breakdown]] to take advantage of having an injured core for more damage.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Faction" },
|
{ "category", "Faction" },
|
||||||
@@ -204,7 +204,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Sungrace",
|
Title = "Sungrace",
|
||||||
Category = "Faction",
|
Category = "Faction",
|
||||||
Content = "# Energy Reserves\r\n\r\nCare about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is you [[Overflow]] your energy reserve.\r\n\r\nConcepts:\r\n- Ramp\r\n- Using and Replenishing Reserved Energy\r\n-",
|
Content = "# Energy Reserves\r\n\r\nCare about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is\r\nyou [[Overflow]] your energy reserve.\r\n\r\nConcepts:\r\n\r\n- Ramp\r\n- Using and Replenishing Reserved Energy\r\n-",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Faction" },
|
{ "category", "Faction" },
|
||||||
@@ -479,7 +479,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Onboarding Track",
|
Title = "Onboarding Track",
|
||||||
Category = "Pass",
|
Category = "Pass",
|
||||||
Content = "| Tier | Reward |\r\n| ---- | -------------------------------- |\r\n| 1 | Sprouts Record |\r\n| 2 | 120 Core Charges |\r\n| 3 | Burn Precon |\r\n| 4 | 120 Core Charges, 25 Flux |\r\n| 5 | Profile Pictures |\r\n| 6 | Emotes |\r\n| 7 | 120 Core Charges |\r\n| 8 | Profile Pictures |\r\n| 9 | 60 Core Charges, 50 Flux |\r\n| 10 | 240 Core Charges, 1 Draft Ticket |\r\n\r\n| Core Charges | Flux |\r\n| ------------ | ---- |\r\n| 660 | 75 |",
|
Content = "| Tier | Reward |\r\n|------|----------------------------------|\r\n| 1 | Sprouts Record |\r\n| 2 | 120 Core Charges |\r\n| 3 | Burn Precon |\r\n| 4 | 120 Core Charges, 25 Flux |\r\n| 5 | Profile Pictures |\r\n| 6 | Emotes |\r\n| 7 | 120 Core Charges |\r\n| 8 | Profile Pictures |\r\n| 9 | 60 Core Charges, 50 Flux |\r\n| 10 | 240 Core Charges, 1 Draft Ticket |\r\n\r\n| Core Charges | Flux |\r\n|--------------|------|\r\n| 660 | 75 |",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "expPer", "30" },
|
{ "expPer", "30" },
|
||||||
@@ -491,7 +491,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Daily Wins",
|
Title = "Daily Wins",
|
||||||
Category = "Quest",
|
Category = "Quest",
|
||||||
Content = "1: 30cc 30xp \n2: 20cc 25xp \n3: 20cc 20xp \n4: 10cc 20xp \n5: 10cc 15xp \n6-12 are all simply 5xp. \n\nSo the daily total win reward for 12 wins is 90cc/145xp.",
|
Content = "1: 30cc 30xp\n2: 20cc 25xp\n3: 20cc 20xp\n4: 10cc 20xp\n5: 10cc 15xp\n6-12 are all simply 5xp.\n\nSo the daily total win reward for 12 wins is 90cc/145xp.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Quest" },
|
{ "category", "Quest" },
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
<NavigationTracker/>
|
||||||
<article class="content px-4">
|
<article class="content px-4">
|
||||||
<TelerikRootComponent>
|
<TelerikRootComponent>
|
||||||
@Body
|
@Body
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
<PageTitle>Chrono CCG - Agents</PageTitle>
|
<PageTitle>Chrono CCG - Agents</PageTitle>
|
||||||
|
|
||||||
<HeadContent>
|
<HeadContent>
|
||||||
<meta name="description" content="View and compare all Chrono CCG agents. Analyze stats, factions, and efficiency to build the perfect deck." />
|
<meta name="description"
|
||||||
|
content="View and compare all Chrono CCG agents. Analyze stats, factions, and efficiency to build the perfect deck."/>
|
||||||
</HeadContent>
|
</HeadContent>
|
||||||
|
|
||||||
<div class="agents-page">
|
<div class="agents-page">
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
<PageTitle>Chrono CCG - @(deck?.Name ?? "Deck Details")</PageTitle>
|
<PageTitle>Chrono CCG - @(deck?.Name ?? "Deck Details")</PageTitle>
|
||||||
|
|
||||||
<HeadContent>
|
<HeadContent>
|
||||||
<meta name="description" content="@(deck != null ? $"View details for the {deck.Name} deck. {deck.Cards.Count} cards, {deck.Factions.Count} factions." : "Deck details and card list.")" />
|
<meta name="description"
|
||||||
|
content="@(deck != null ? $"View details for the {deck.Name} deck. {deck.Cards.Count} cards, {deck.Factions.Count} factions." : "Deck details and card list.")"/>
|
||||||
</HeadContent>
|
</HeadContent>
|
||||||
|
|
||||||
<div class="deck-detail-page">
|
<div class="deck-detail-page">
|
||||||
@@ -23,7 +24,8 @@
|
|||||||
<article class="deck-article">
|
<article class="deck-article">
|
||||||
<header class="deck-header">
|
<header class="deck-header">
|
||||||
<h1>@deck.Name</h1>
|
<h1>@deck.Name</h1>
|
||||||
<b>Deck Code:</b> <pre>@deck.DeckCode</pre>
|
<b>Deck Code:</b>
|
||||||
|
<pre>@deck.DeckCode</pre>
|
||||||
@if (deck.Factions.Count > 0)
|
@if (deck.Factions.Count > 0)
|
||||||
{
|
{
|
||||||
<div class="deck-factions">
|
<div class="deck-factions">
|
||||||
@@ -44,14 +46,14 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ManaCurve Distribution="GetManaDistribution()" MaxCostLabel="10" />
|
<ManaCurve Distribution="GetManaDistribution()" MaxCostLabel="10"/>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@if (deck.Keycards.Count > 0)
|
@if (deck.Keycards.Count > 0)
|
||||||
{
|
{
|
||||||
<section class="deck-section">
|
<section class="deck-section">
|
||||||
<h2><i class="bi bi-star-fill" style="color: var(--gold);"></i> Keycards</h2>
|
<h2><i class="bi bi-star-fill" style="color: var(--gold);"></i> Keycards</h2>
|
||||||
<CardGrid Cards="deck.Keycards" OnSelectCard="SelectCard" />
|
<CardGrid Cards="deck.Keycards" OnSelectCard="SelectCard"/>
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,13 +61,13 @@
|
|||||||
{
|
{
|
||||||
<section class="deck-section">
|
<section class="deck-section">
|
||||||
<h2><i class="bi bi-shuffle"></i> Divers</h2>
|
<h2><i class="bi bi-shuffle"></i> Divers</h2>
|
||||||
<CardGrid Cards="deck.Divers" OnSelectCard="SelectCard" />
|
<CardGrid Cards="deck.Divers" OnSelectCard="SelectCard"/>
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
|
|
||||||
<section class="deck-section">
|
<section class="deck-section">
|
||||||
<h2><i class="bi bi-collection-fill"></i> Cards</h2>
|
<h2><i class="bi bi-collection-fill"></i> Cards</h2>
|
||||||
<CardGrid Cards="deck.Cards" OnSelectCard="SelectCard" />
|
<CardGrid Cards="deck.Cards" OnSelectCard="SelectCard"/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@if (deck.Description != null)
|
@if (deck.Description != null)
|
||||||
@@ -84,7 +86,7 @@
|
|||||||
<CardDetailModal Card="selectedCard"
|
<CardDetailModal Card="selectedCard"
|
||||||
OnClose="CloseDetail"
|
OnClose="CloseDetail"
|
||||||
OnSelectCard="SelectCard"
|
OnSelectCard="SelectCard"
|
||||||
DescriptionRenderer="@(desc => CardRenderer.RenderDescription(desc, SelectCard))" />
|
DescriptionRenderer="@(desc => CardRenderer.RenderDescription(desc, SelectCard))"/>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public string Name { get; set; } = "";
|
[Parameter] public string Name { get; set; } = "";
|
||||||
@@ -124,7 +126,7 @@
|
|||||||
{
|
{
|
||||||
if (deck == null) return [];
|
if (deck == null) return [];
|
||||||
var counts = new Dictionary<int, int>();
|
var counts = new Dictionary<int, int>();
|
||||||
for (int i = 0; i <= 10; i++) counts[i] = 0;
|
for (var i = 0; i <= 10; i++) counts[i] = 0;
|
||||||
|
|
||||||
foreach (var cardName in deck.Cards)
|
foreach (var cardName in deck.Cards)
|
||||||
{
|
{
|
||||||
@@ -139,4 +141,5 @@
|
|||||||
|
|
||||||
return counts.OrderBy(x => x.Key).Select(x => (x.Key, x.Value)).ToList();
|
return counts.OrderBy(x => x.Key).Select(x => (x.Key, x.Value)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
<PageTitle>Chrono CCG - Decks</PageTitle>
|
<PageTitle>Chrono CCG - Decks</PageTitle>
|
||||||
|
|
||||||
<HeadContent>
|
<HeadContent>
|
||||||
<meta name="description" content="Explore community and official Chrono CCG decks. Find the best strategies and card combinations." />
|
<meta name="description"
|
||||||
|
content="Explore community and official Chrono CCG decks. Find the best strategies and card combinations."/>
|
||||||
</HeadContent>
|
</HeadContent>
|
||||||
|
|
||||||
<div class="decks-page">
|
<div class="decks-page">
|
||||||
@@ -13,7 +14,8 @@
|
|||||||
<div class="decks-header-row">
|
<div class="decks-header-row">
|
||||||
<p class="text-secondary">@decks.Count deck@(decks.Count != 1 ? "s" : "")</p>
|
<p class="text-secondary">@decks.Count deck@(decks.Count != 1 ? "s" : "")</p>
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<input class="form-check-input" type="checkbox" id="showPrecons" @bind="showPrecons" @bind:after="RefreshDecks">
|
<input class="form-check-input" type="checkbox" id="showPrecons" @bind="showPrecons"
|
||||||
|
@bind:after="RefreshDecks">
|
||||||
<label class="form-check-label" for="showPrecons">Show Precons</label>
|
<label class="form-check-label" for="showPrecons">Show Precons</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,7 +72,7 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<DeckData> decks = [];
|
private List<DeckData> decks = [];
|
||||||
private bool showPrecons = false;
|
private bool showPrecons;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
@@ -83,8 +85,8 @@
|
|||||||
.Where(d => d.IsVisible)
|
.Where(d => d.IsVisible)
|
||||||
.Where(d =>
|
.Where(d =>
|
||||||
showPrecons
|
showPrecons
|
||||||
? d.DeckType is "precon" or "store" :
|
? d.DeckType is "precon" or "store"
|
||||||
d.DeckType is "custom")
|
: d.DeckType is "custom")
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,17 +13,19 @@
|
|||||||
<aside class="docs-sidebar">
|
<aside class="docs-sidebar">
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
<i class="bi bi-search"></i>
|
<i class="bi bi-search"></i>
|
||||||
<input type="text" placeholder="Search docs..." @bind="searchQuery" @bind:event="oninput" />
|
<input type="text" placeholder="Search docs..." @bind="searchQuery" @bind:event="oninput"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="category-list">
|
<div class="category-list">
|
||||||
<div class="category-item @(selectedCategory == null ? "active" : "")" @onclick="() => SelectCategory(null)">
|
<div class="category-item @(selectedCategory == null ? "active" : "")"
|
||||||
|
@onclick="() => SelectCategory(null)">
|
||||||
All Pages
|
All Pages
|
||||||
</div>
|
</div>
|
||||||
@foreach (var category in categories)
|
@foreach (var category in categories)
|
||||||
{
|
{
|
||||||
var cat = category;
|
var cat = category;
|
||||||
<div class="category-item @(selectedCategory == cat ? "active" : "")" @onclick="() => SelectCategory(cat)">
|
<div class="category-item @(selectedCategory == cat ? "active" : "")"
|
||||||
|
@onclick="() => SelectCategory(cat)">
|
||||||
@cat
|
@cat
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -134,20 +136,24 @@
|
|||||||
return doc.Frontmatter.TryGetValue(key, out var val) && !string.IsNullOrWhiteSpace(val) ? val : null;
|
return doc.Frontmatter.TryGetValue(key, out var val) && !string.IsNullOrWhiteSpace(val) ? val : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetLabel(string key) => key switch
|
private static string GetLabel(string key)
|
||||||
{
|
{
|
||||||
"category" => "Category",
|
return key switch
|
||||||
"description" => "Description",
|
{
|
||||||
"essencePrice" => "Essence Price",
|
"category" => "Category",
|
||||||
"crytalPrice" => "Crystal Price",
|
"description" => "Description",
|
||||||
"coreChargesPrice" => "Core Charges Price",
|
"essencePrice" => "Essence Price",
|
||||||
"pricePerPack" => "Price per Pack",
|
"crytalPrice" => "Crystal Price",
|
||||||
"codeCharges" => "Code Charges",
|
"coreChargesPrice" => "Core Charges Price",
|
||||||
"coreCharges" => "Core Charges",
|
"pricePerPack" => "Price per Pack",
|
||||||
"currency" => "Currency",
|
"codeCharges" => "Code Charges",
|
||||||
"faction" => "Faction",
|
"coreCharges" => "Core Charges",
|
||||||
"exp" => "EXP Reward",
|
"currency" => "Currency",
|
||||||
"see" => "See Also",
|
"faction" => "Faction",
|
||||||
_ => string.Concat(key.Select((c, i) => i > 0 && char.IsUpper(c) ? " " + c : c.ToString())),
|
"exp" => "EXP Reward",
|
||||||
};
|
"see" => "See Also",
|
||||||
|
_ => string.Concat(key.Select((c, i) => i > 0 && char.IsUpper(c) ? " " + c : c.ToString()))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.JSInterop;
|
||||||
|
|
||||||
|
namespace Shared.Services;
|
||||||
|
|
||||||
|
public class AnalyticsService
|
||||||
|
{
|
||||||
|
private readonly IJSRuntime _jsRuntime;
|
||||||
|
|
||||||
|
public AnalyticsService(IJSRuntime jsRuntime)
|
||||||
|
{
|
||||||
|
_jsRuntime = jsRuntime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask TrackPageView(string path)
|
||||||
|
{
|
||||||
|
await _jsRuntime.InvokeVoidAsync("trackPageView", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask TrackEvent(string eventName, object? eventData = null)
|
||||||
|
{
|
||||||
|
if (eventData != null)
|
||||||
|
await _jsRuntime.InvokeVoidAsync("gtag", "event", eventName, eventData);
|
||||||
|
else
|
||||||
|
await _jsRuntime.InvokeVoidAsync("gtag", "event", eventName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using System.Text.RegularExpressions;
|
||||||
using Chrono.Model;
|
using Chrono.Model;
|
||||||
using System.Text.RegularExpressions;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace Shared.Services;
|
namespace Shared.Services;
|
||||||
|
|
||||||
public class CardRenderingService
|
public class CardRenderingService
|
||||||
{
|
{
|
||||||
private readonly List<string> _cardNames;
|
|
||||||
private readonly Dictionary<string, CardData> _cardLookup;
|
private readonly Dictionary<string, CardData> _cardLookup;
|
||||||
|
private readonly List<string> _cardNames;
|
||||||
private readonly Regex _nameRegex;
|
private readonly Regex _nameRegex;
|
||||||
|
|
||||||
public CardRenderingService()
|
public CardRenderingService()
|
||||||
@@ -33,7 +33,7 @@ public class CardRenderingService
|
|||||||
{
|
{
|
||||||
return builder =>
|
return builder =>
|
||||||
{
|
{
|
||||||
int sequence = 0;
|
var sequence = 0;
|
||||||
var paragraphs = description.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
var paragraphs = description.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
foreach (var paragraph in paragraphs)
|
foreach (var paragraph in paragraphs)
|
||||||
@@ -41,31 +41,27 @@ public class CardRenderingService
|
|||||||
builder.OpenElement(sequence++, "p");
|
builder.OpenElement(sequence++, "p");
|
||||||
|
|
||||||
var matches = _nameRegex.Matches(paragraph);
|
var matches = _nameRegex.Matches(paragraph);
|
||||||
int lastIndex = 0;
|
var lastIndex = 0;
|
||||||
|
|
||||||
foreach (Match match in matches)
|
foreach (Match match in matches)
|
||||||
{
|
{
|
||||||
if (match.Index > lastIndex)
|
if (match.Index > lastIndex)
|
||||||
{
|
|
||||||
builder.AddContent(sequence++, paragraph.Substring(lastIndex, match.Index - lastIndex));
|
builder.AddContent(sequence++, paragraph.Substring(lastIndex, match.Index - lastIndex));
|
||||||
}
|
|
||||||
|
|
||||||
var cardName = match.Value;
|
var cardName = match.Value;
|
||||||
var card = LookupCard(cardName);
|
var card = LookupCard(cardName);
|
||||||
|
|
||||||
builder.OpenElement(sequence++, "button");
|
builder.OpenElement(sequence++, "button");
|
||||||
builder.AddAttribute(sequence++, "class", "inline-card-btn");
|
builder.AddAttribute(sequence++, "class", "inline-card-btn");
|
||||||
builder.AddAttribute(sequence++, "onclick", EventCallback.Factory.Create(this, () => onCardClick(card)));
|
builder.AddAttribute(sequence++, "onclick",
|
||||||
|
EventCallback.Factory.Create(this, () => onCardClick(card)));
|
||||||
builder.AddContent(sequence++, cardName);
|
builder.AddContent(sequence++, cardName);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
|
|
||||||
lastIndex = match.Index + match.Length;
|
lastIndex = match.Index + match.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastIndex < paragraph.Length)
|
if (lastIndex < paragraph.Length) builder.AddContent(sequence++, paragraph.Substring(lastIndex));
|
||||||
{
|
|
||||||
builder.AddContent(sequence++, paragraph.Substring(lastIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.Playwright;
|
using Microsoft.Playwright.NUnit;
|
||||||
using Microsoft.Playwright.NUnit;
|
|
||||||
using Tests.PageObjects;
|
using Tests.PageObjects;
|
||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
@@ -8,10 +7,6 @@ namespace Tests;
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FeatureTests : PageTest
|
public class FeatureTests : PageTest
|
||||||
{
|
{
|
||||||
private DecksPage _decksPage;
|
|
||||||
private DeckDetailPage _deckDetailPage;
|
|
||||||
private AgentsPage _agentsPage;
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
@@ -20,6 +15,10 @@ public class FeatureTests : PageTest
|
|||||||
_agentsPage = new AgentsPage(Page);
|
_agentsPage = new AgentsPage(Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DecksPage _decksPage;
|
||||||
|
private DeckDetailPage _deckDetailPage;
|
||||||
|
private AgentsPage _agentsPage;
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task DeckManaCurve_ShouldBeVisibleOnDetail()
|
public async Task DeckManaCurve_ShouldBeVisibleOnDetail()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,12 +4,17 @@ namespace Tests.PageObjects;
|
|||||||
|
|
||||||
public class AgentsPage : BasePage
|
public class AgentsPage : BasePage
|
||||||
{
|
{
|
||||||
public AgentsPage(IPage page) : base(page) { }
|
public AgentsPage(IPage page) : base(page)
|
||||||
|
{
|
||||||
public async Task GotoAsync() => await NavigateToAsync("/agents");
|
}
|
||||||
|
|
||||||
public ILocator Grid => Page.Locator(".agents-grid");
|
public ILocator Grid => Page.Locator(".agents-grid");
|
||||||
|
|
||||||
|
public async Task GotoAsync()
|
||||||
|
{
|
||||||
|
await NavigateToAsync("/agents");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task WaitForGridAsync()
|
public async Task WaitForGridAsync()
|
||||||
{
|
{
|
||||||
await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);
|
await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ namespace Tests.PageObjects;
|
|||||||
|
|
||||||
public abstract class BasePage
|
public abstract class BasePage
|
||||||
{
|
{
|
||||||
protected readonly IPage Page;
|
|
||||||
protected readonly string BaseUrl = "http://localhost:5256";
|
protected readonly string BaseUrl = "http://localhost:5256";
|
||||||
|
protected readonly IPage Page;
|
||||||
|
|
||||||
protected BasePage(IPage page)
|
protected BasePage(IPage page)
|
||||||
{
|
{
|
||||||
@@ -17,5 +17,8 @@ public abstract class BasePage
|
|||||||
await Page.GotoAsync($"{BaseUrl}{path}");
|
await Page.GotoAsync($"{BaseUrl}{path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILocator GetHeading() => Page.Locator("h1");
|
public ILocator GetHeading()
|
||||||
|
{
|
||||||
|
return Page.Locator("h1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,17 @@ namespace Tests.PageObjects;
|
|||||||
|
|
||||||
public class DeckDetailPage : BasePage
|
public class DeckDetailPage : BasePage
|
||||||
{
|
{
|
||||||
public DeckDetailPage(IPage page) : base(page) { }
|
public DeckDetailPage(IPage page) : base(page)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public ILocator ManaCurve => Page.Locator(".mana-curve");
|
public ILocator ManaCurve => Page.Locator(".mana-curve");
|
||||||
public ILocator ManaBars => Page.Locator(".mana-bar");
|
public ILocator ManaBars => Page.Locator(".mana-bar");
|
||||||
public ILocator ManaBarLabels => Page.Locator(".mana-bar-label");
|
public ILocator ManaBarLabels => Page.Locator(".mana-bar-label");
|
||||||
public ILocator ManaCosts => Page.Locator(".mana-cost");
|
public ILocator ManaCosts => Page.Locator(".mana-cost");
|
||||||
|
|
||||||
public async Task<int> GetManaBarCountAsync() => await ManaBars.CountAsync();
|
public async Task<int> GetManaBarCountAsync()
|
||||||
|
{
|
||||||
|
return await ManaBars.CountAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,14 +4,23 @@ namespace Tests.PageObjects;
|
|||||||
|
|
||||||
public class DecksPage : BasePage
|
public class DecksPage : BasePage
|
||||||
{
|
{
|
||||||
public DecksPage(IPage page) : base(page) { }
|
public DecksPage(IPage page) : base(page)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public async Task GotoAsync() => await NavigateToAsync("/decks");
|
public async Task GotoAsync()
|
||||||
|
{
|
||||||
|
await NavigateToAsync("/decks");
|
||||||
|
}
|
||||||
|
|
||||||
public ILocator GetDeckCards() => Page.Locator(".deck-card");
|
public ILocator GetDeckCards()
|
||||||
|
{
|
||||||
|
return Page.Locator(".deck-card");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ClickDeckByNameAsync(string name)
|
public async Task ClickDeckByNameAsync(string name)
|
||||||
{
|
{
|
||||||
await Page.Locator(".deck-card-title").GetByText(name, new() { Exact = true }).ClickAsync();
|
await Page.Locator(".deck-card-title").GetByText(name, new LocatorGetByTextOptions { Exact = true })
|
||||||
|
.ClickAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Playwright;
|
using Microsoft.Playwright;
|
||||||
using Microsoft.Playwright.NUnit;
|
using Microsoft.Playwright.NUnit;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ public class PlaywrightTests : PageTest
|
|||||||
public async Task HomePage_ShouldLoad()
|
public async Task HomePage_ShouldLoad()
|
||||||
{
|
{
|
||||||
await Page.GotoAsync(BaseUrl);
|
await Page.GotoAsync(BaseUrl);
|
||||||
await Expect(Page).ToHaveTitleAsync(new System.Text.RegularExpressions.Regex("Chrono CCG"));
|
await Expect(Page).ToHaveTitleAsync(new Regex("Chrono CCG"));
|
||||||
|
|
||||||
// Check for some content that should be on the home page
|
// Check for some content that should be on the home page
|
||||||
var heading = Page.Locator("h1");
|
var heading = Page.Locator("h1");
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Tests;
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TelerikLicenseTests : PageTest
|
public class TelerikLicenseTests : PageTest
|
||||||
{
|
{
|
||||||
|
|
||||||
private const string BaseUrl = "http://localhost:5256";
|
private const string BaseUrl = "http://localhost:5256";
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
+12
-17
@@ -1,13 +1,12 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net.Http;
|
|
||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
|
|
||||||
[SetUpFixture]
|
[SetUpFixture]
|
||||||
public class TestSetup
|
public class TestSetup
|
||||||
{
|
{
|
||||||
private Process? _serverProcess;
|
|
||||||
private const string ServerUrl = "http://localhost:5256";
|
private const string ServerUrl = "http://localhost:5256";
|
||||||
|
private Process? _serverProcess;
|
||||||
|
|
||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
public async Task BeforeAllTests()
|
public async Task BeforeAllTests()
|
||||||
@@ -17,14 +16,9 @@ public class TestSetup
|
|||||||
// Find solution root
|
// Find solution root
|
||||||
var currentDir = AppContext.BaseDirectory;
|
var currentDir = AppContext.BaseDirectory;
|
||||||
while (currentDir != null && !File.Exists(Path.Combine(currentDir, "Chrono.sln")))
|
while (currentDir != null && !File.Exists(Path.Combine(currentDir, "Chrono.sln")))
|
||||||
{
|
|
||||||
currentDir = Path.GetDirectoryName(currentDir);
|
currentDir = Path.GetDirectoryName(currentDir);
|
||||||
}
|
|
||||||
|
|
||||||
if (currentDir == null)
|
if (currentDir == null) throw new Exception("Could not find Chrono.sln to determine project path.");
|
||||||
{
|
|
||||||
throw new Exception("Could not find Chrono.sln to determine project path.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var projectPath = Path.Combine(currentDir, "Server", "Server.csproj");
|
var projectPath = Path.Combine(currentDir, "Server", "Server.csproj");
|
||||||
|
|
||||||
@@ -41,24 +35,26 @@ public class TestSetup
|
|||||||
|
|
||||||
_serverProcess = Process.Start(startInfo);
|
_serverProcess = Process.Start(startInfo);
|
||||||
|
|
||||||
_serverProcess.OutputDataReceived += (s, e) => { if (e.Data != null) Console.WriteLine($"[SERVER OUT] {e.Data}"); };
|
_serverProcess.OutputDataReceived += (s, e) =>
|
||||||
_serverProcess.ErrorDataReceived += (s, e) => { if (e.Data != null) Console.WriteLine($"[SERVER ERR] {e.Data}"); };
|
{
|
||||||
|
if (e.Data != null) Console.WriteLine($"[SERVER OUT] {e.Data}");
|
||||||
|
};
|
||||||
|
_serverProcess.ErrorDataReceived += (s, e) =>
|
||||||
|
{
|
||||||
|
if (e.Data != null) Console.WriteLine($"[SERVER ERR] {e.Data}");
|
||||||
|
};
|
||||||
_serverProcess.BeginOutputReadLine();
|
_serverProcess.BeginOutputReadLine();
|
||||||
_serverProcess.BeginErrorReadLine();
|
_serverProcess.BeginErrorReadLine();
|
||||||
|
|
||||||
if (_serverProcess == null)
|
if (_serverProcess == null) throw new Exception("Failed to start server process.");
|
||||||
{
|
|
||||||
throw new Exception("Failed to start server process.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the server to be ready
|
// Wait for the server to be ready
|
||||||
using var client = new HttpClient();
|
using var client = new HttpClient();
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
var timeout = TimeSpan.FromSeconds(30);
|
var timeout = TimeSpan.FromSeconds(30);
|
||||||
bool isReady = false;
|
var isReady = false;
|
||||||
|
|
||||||
while (sw.Elapsed < timeout)
|
while (sw.Elapsed < timeout)
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await client.GetAsync(ServerUrl);
|
var response = await client.GetAsync(ServerUrl);
|
||||||
@@ -73,7 +69,6 @@ public class TestSetup
|
|||||||
// Wait and retry
|
// Wait and retry
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!isReady)
|
if (!isReady)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly }" NotFoundPage="typeof(NotFound)">
|
<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly }"
|
||||||
|
NotFoundPage="typeof(NotFound)">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
||||||
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@using System.Text.RegularExpressions
|
||||||
@namespace Chrono.Components
|
@namespace Chrono.Components
|
||||||
|
|
||||||
@if (Card != null)
|
@if (Card != null)
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
{
|
{
|
||||||
<div class="detail-image">
|
<div class="detail-image">
|
||||||
<img src="@Card.ImagePath" alt="@Card.Name"
|
<img src="@Card.ImagePath" alt="@Card.Name"
|
||||||
onerror="this.style.display='none';this.parentElement.style.display='none'" />
|
onerror="this.style.display='none';this.parentElement.style.display='none'"/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="detail-info">
|
<div class="detail-info">
|
||||||
@@ -88,7 +89,8 @@
|
|||||||
var target = LookupCard(targetName);
|
var target = LookupCard(targetName);
|
||||||
if (target != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
<button class="inline-card-btn" @onclick="() => Navigate(target)">@targetName</button>
|
<button class="inline-card-btn"
|
||||||
|
@onclick="() => Navigate(target)">@targetName</button>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -108,7 +110,8 @@
|
|||||||
var fromCard = LookupCard(Card.ImmortalizeFrom);
|
var fromCard = LookupCard(Card.ImmortalizeFrom);
|
||||||
if (fromCard != null)
|
if (fromCard != null)
|
||||||
{
|
{
|
||||||
<button class="inline-card-btn" @onclick="() => Navigate(fromCard)">@Card.ImmortalizeFrom</button>
|
<button class="inline-card-btn"
|
||||||
|
@onclick="() => Navigate(fromCard)">@Card.ImmortalizeFrom</button>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -181,7 +184,9 @@
|
|||||||
{
|
{
|
||||||
await Http.PostAsJsonAsync("api/notes", new CardNote { CardName = Card.Name, Note = currentNote });
|
await Http.PostAsJsonAsync("api/notes", new CardNote { CardName = Card.Name, Note = currentNote });
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
isSaving = false;
|
isSaving = false;
|
||||||
@@ -209,64 +214,68 @@
|
|||||||
string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase));
|
string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private RenderFragment RenderDescription(string description) => builder =>
|
private RenderFragment RenderDescription(string description)
|
||||||
{
|
{
|
||||||
var cardNames = CardDatabase.Cards
|
return builder =>
|
||||||
.Select(c => c.Name)
|
|
||||||
.Where(n => !string.IsNullOrWhiteSpace(n))
|
|
||||||
.OrderByDescending(n => n.Length)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
int seq = 0;
|
|
||||||
var remaining = description;
|
|
||||||
|
|
||||||
while (!string.IsNullOrEmpty(remaining))
|
|
||||||
{
|
{
|
||||||
int bestIdx = -1;
|
var cardNames = CardDatabase.Cards
|
||||||
string? bestName = null;
|
.Select(c => c.Name)
|
||||||
|
.Where(n => !string.IsNullOrWhiteSpace(n))
|
||||||
|
.OrderByDescending(n => n.Length)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
foreach (var name in cardNames)
|
var seq = 0;
|
||||||
|
var remaining = description;
|
||||||
|
|
||||||
|
while (!string.IsNullOrEmpty(remaining))
|
||||||
{
|
{
|
||||||
var pattern = $@"\b{System.Text.RegularExpressions.Regex.Escape(name)}\b";
|
var bestIdx = -1;
|
||||||
var match = System.Text.RegularExpressions.Regex.Match(remaining, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
string? bestName = null;
|
||||||
|
|
||||||
if (match.Success)
|
foreach (var name in cardNames)
|
||||||
{
|
{
|
||||||
if (bestIdx == -1 || match.Index < bestIdx)
|
var pattern = $@"\b{Regex.Escape(name)}\b";
|
||||||
|
var match = Regex.Match(remaining, pattern, RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
if (match.Success)
|
||||||
{
|
{
|
||||||
bestIdx = match.Index;
|
if (bestIdx == -1 || match.Index < bestIdx)
|
||||||
bestName = match.Value;
|
{
|
||||||
|
bestIdx = match.Index;
|
||||||
|
bestName = match.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (bestIdx != -1 && bestName != null)
|
if (bestIdx != -1 && bestName != null)
|
||||||
{
|
|
||||||
if (bestIdx > 0)
|
|
||||||
builder.AddContent(seq++, remaining[..bestIdx]);
|
|
||||||
|
|
||||||
var card = LookupCard(bestName);
|
|
||||||
if (card != null)
|
|
||||||
{
|
{
|
||||||
builder.OpenElement(seq++, "button");
|
if (bestIdx > 0)
|
||||||
builder.AddAttribute(seq++, "class", "inline-card-btn");
|
builder.AddContent(seq++, remaining[..bestIdx]);
|
||||||
builder.AddAttribute(seq++, "onclick",
|
|
||||||
EventCallback.Factory.Create(this, () => Navigate(card)));
|
var card = LookupCard(bestName);
|
||||||
builder.AddContent(seq++, bestName);
|
if (card != null)
|
||||||
builder.CloseElement();
|
{
|
||||||
|
builder.OpenElement(seq++, "button");
|
||||||
|
builder.AddAttribute(seq++, "class", "inline-card-btn");
|
||||||
|
builder.AddAttribute(seq++, "onclick",
|
||||||
|
EventCallback.Factory.Create(this, () => Navigate(card)));
|
||||||
|
builder.AddContent(seq++, bestName);
|
||||||
|
builder.CloseElement();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.AddContent(seq++, bestName);
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = remaining[(bestIdx + bestName.Length)..];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builder.AddContent(seq++, bestName);
|
builder.AddContent(seq++, remaining);
|
||||||
|
remaining = "";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
remaining = remaining[(bestIdx + bestName.Length)..];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builder.AddContent(seq++, remaining);
|
|
||||||
remaining = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
from { opacity: 0; }
|
from {
|
||||||
to { opacity: 1; }
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-detail {
|
.card-detail {
|
||||||
@@ -231,7 +235,8 @@
|
|||||||
text-decoration-color: #7b73ff;
|
text-decoration-color: #7b73ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@media (max-width: 768px) {
|
@
|
||||||
|
@media (max-width: 768px) {
|
||||||
.detail-layout {
|
.detail-layout {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
@page "/cards"
|
@page "/cards"
|
||||||
@inject HttpClient Http
|
@inject HttpClient Http
|
||||||
|
@inject AnalyticsService AnalyticsService
|
||||||
|
|
||||||
<PageTitle>Chrono CCG - Card Gallery</PageTitle>
|
<PageTitle>Chrono CCG - Card Gallery</PageTitle>
|
||||||
|
|
||||||
<HeadContent>
|
<HeadContent>
|
||||||
<meta name="description" content="Browse and filter all Chrono CCG cards. Explore agents, spells, and more." />
|
<meta name="description" content="Browse and filter all Chrono CCG cards. Explore agents, spells, and more."/>
|
||||||
</HeadContent>
|
</HeadContent>
|
||||||
|
|
||||||
<div class="gallery-container">
|
<div class="gallery-container">
|
||||||
@@ -21,14 +22,15 @@
|
|||||||
<button class="tab agent @(categoryFilter == "Agent" ? "active" : "")" @onclick='@(() => SetCategory("Agent"))'>
|
<button class="tab agent @(categoryFilter == "Agent" ? "active" : "")" @onclick='@(() => SetCategory("Agent"))'>
|
||||||
<i class="bi bi-person-fill"></i> Agents
|
<i class="bi bi-person-fill"></i> Agents
|
||||||
</button>
|
</button>
|
||||||
<button class="tab agent @(categoryFilter == "Immortalized" ? "active" : "")" @onclick='@(() => SetCategory("Immortalized"))'>
|
<button class="tab agent @(categoryFilter == "Immortalized" ? "active" : "")"
|
||||||
|
@onclick='@(() => SetCategory("Immortalized"))'>
|
||||||
<i class="bi bi-person-fill"></i> Immortalized
|
<i class="bi bi-person-fill"></i> Immortalized
|
||||||
</button>
|
</button>
|
||||||
<!-- //Todo make agent being linked to immortal for side by side sorting
|
<!-- //Todo make agent being linked to immortal for side by side sorting
|
||||||
<button class="tab agent @(agentLink ? "active" : "")" @onclick='@(() => ToggleAgentLink())'>
|
<button class="tab agent @(agentLink ? "active" : "")" @onclick='@(() => ToggleAgentLink())'>
|
||||||
<i class="bi bi-person-fill"></i> Link
|
<i class="bi bi-person-fill"></i> Link
|
||||||
</button>
|
</button>
|
||||||
-->
|
-->
|
||||||
<button class="tab spell @(categoryFilter == "Spell" ? "active" : "")" @onclick='@(() => SetCategory("Spell"))'>
|
<button class="tab spell @(categoryFilter == "Spell" ? "active" : "")" @onclick='@(() => SetCategory("Spell"))'>
|
||||||
<i class="bi bi-wand"></i> Spells
|
<i class="bi bi-wand"></i> Spells
|
||||||
</button>
|
</button>
|
||||||
@@ -118,7 +120,7 @@
|
|||||||
{
|
{
|
||||||
<div class="card-grid @(showDetailedView ? "detailed-view" : "")">
|
<div class="card-grid @(showDetailedView ? "detailed-view" : "")">
|
||||||
@{ var idx = 0; }
|
@{ var idx = 0; }
|
||||||
@foreach (var card in filteredCards.Where(a=>a.Category is "Agent" or "Spell" or "Immortalized"))
|
@foreach (var card in filteredCards.Where(a => a.Category is "Agent" or "Spell" or "Immortalized"))
|
||||||
{
|
{
|
||||||
<div class="card-cell @(selectedCard == card ? "selected" : "")"
|
<div class="card-cell @(selectedCard == card ? "selected" : "")"
|
||||||
style="--i: @idx"
|
style="--i: @idx"
|
||||||
@@ -171,7 +173,7 @@
|
|||||||
|
|
||||||
@if (selectedCard != null)
|
@if (selectedCard != null)
|
||||||
{
|
{
|
||||||
<CardDialog Card="selectedCard" OnClose="CloseDetail" OnNavigate="SelectCard" />
|
<CardDialog Card="selectedCard" OnClose="CloseDetail" OnNavigate="SelectCard"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@@ -234,11 +236,13 @@
|
|||||||
private void SetCategory(string cat)
|
private void SetCategory(string cat)
|
||||||
{
|
{
|
||||||
categoryFilter = categoryFilter == cat ? "" : cat;
|
categoryFilter = categoryFilter == cat ? "" : cat;
|
||||||
|
_ = AnalyticsService.TrackEvent("filter_category", new { category = categoryFilter });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearCategoryFilter()
|
private void ClearCategoryFilter()
|
||||||
{
|
{
|
||||||
categoryFilter = "";
|
categoryFilter = "";
|
||||||
|
_ = AnalyticsService.TrackEvent("filter_category", new { category = "All" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearFactionFilter()
|
private void ClearFactionFilter()
|
||||||
@@ -264,6 +268,7 @@
|
|||||||
private void SelectCard(CardData card)
|
private void SelectCard(CardData card)
|
||||||
{
|
{
|
||||||
selectedCard = card;
|
selectedCard = card;
|
||||||
|
_ = AnalyticsService.TrackEvent("select_item", new { item_name = card.Name, item_category = card.Category });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseDetail()
|
private void CloseDetail()
|
||||||
@@ -278,4 +283,5 @@
|
|||||||
factionFilter = "";
|
factionFilter = "";
|
||||||
costFilter = "";
|
costFilter = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
using Shared.Services;
|
||||||
using Web;
|
using Web;
|
||||||
|
|
||||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||||
@@ -8,6 +9,7 @@ builder.RootComponents.Add<HeadOutlet>("head::after");
|
|||||||
|
|
||||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||||
builder.Services.AddTelerikBlazor();
|
builder.Services.AddTelerikBlazor();
|
||||||
builder.Services.AddSingleton<Shared.Services.CardRenderingService>();
|
builder.Services.AddSingleton<CardRenderingService>();
|
||||||
|
builder.Services.AddScoped<AnalyticsService>();
|
||||||
|
|
||||||
await builder.Build().RunAsync();
|
await builder.Build().RunAsync();
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
|
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -21,6 +21,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Model\Model.csproj"/>
|
<ProjectReference Include="..\Model\Model.csproj"/>
|
||||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
<ProjectReference Include="..\Shared\Shared.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
@using Shared.Layout
|
@using Shared.Layout
|
||||||
@using Shared.Pages
|
@using Shared.Pages
|
||||||
|
@using Shared.Services
|
||||||
|
@using Shared.Components
|
||||||
@using Chrono.Components
|
@using Chrono.Components
|
||||||
@using Telerik.Blazor
|
@using Telerik.Blazor
|
||||||
@using Telerik.Blazor.Components
|
@using Telerik.Blazor.Components
|
||||||
|
|||||||
@@ -257,9 +257,6 @@ a, .btn-link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.inline-card-btn {
|
.inline-card-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
@@ -6,26 +6,29 @@
|
|||||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||||
<title>Chrono CCG - Card Gallery</title>
|
<title>Chrono CCG - Card Gallery</title>
|
||||||
<base href="/"/>
|
<base href="/"/>
|
||||||
<meta name="description" content="Explore the full collection of Chrono CCG cards. Filter by cost, faction, and type."/>
|
<meta content="Explore the full collection of Chrono CCG cards. Filter by cost, faction, and type."
|
||||||
<meta name="keywords" content="Chrono CCG, Reference, Card Gallery, DB"/>
|
name="description"/>
|
||||||
|
<meta content="Chrono CCG, Reference, Card Gallery, DB" name="keywords"/>
|
||||||
|
|
||||||
<!-- Open Graph / Facebook -->
|
<!-- Open Graph / Facebook -->
|
||||||
<meta property="og:type" content="website"/>
|
<meta content="website" property="og:type"/>
|
||||||
<meta property="og:url" content="https://chronoccg.com/"/>
|
<meta content="https://chronoccg.com/" property="og:url"/>
|
||||||
<meta property="og:title" content="Chrono CCG - Card Gallery"/>
|
<meta content="Chrono CCG - Card Gallery" property="og:title"/>
|
||||||
<meta property="og:description" content="Explore the full collection of Chrono CCG cards. Filter by cost, faction, and type."/>
|
<meta content="Explore the full collection of Chrono CCG cards. Filter by cost, faction, and type."
|
||||||
<meta property="og:image" content="https://chronoccg.com/favicon.png"/>
|
property="og:description"/>
|
||||||
|
<meta content="https://chronoccg.com/favicon.png" property="og:image"/>
|
||||||
|
|
||||||
<!-- Twitter -->
|
<!-- Twitter -->
|
||||||
<meta property="twitter:card" content="summary_large_image"/>
|
<meta content="summary_large_image" property="twitter:card"/>
|
||||||
<meta property="twitter:url" content="https://chronoccg.com/"/>
|
<meta content="https://chronoccg.com/" property="twitter:url"/>
|
||||||
<meta property="twitter:title" content="Chrono CCG - Card Gallery"/>
|
<meta content="Chrono CCG - Card Gallery" property="twitter:title"/>
|
||||||
<meta property="twitter:description" content="Explore the full collection of Chrono CCG cards. Filter by cost, faction, and type."/>
|
<meta content="Explore the full collection of Chrono CCG cards. Filter by cost, faction, and type."
|
||||||
<meta property="twitter:image" content="https://chronoccg.com/favicon.png"/>
|
property="twitter:description"/>
|
||||||
|
<meta content="https://chronoccg.com/favicon.png" property="twitter:image"/>
|
||||||
|
|
||||||
<link href="manifest.json" rel="manifest" />
|
<link href="manifest.json" rel="manifest"/>
|
||||||
<link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
|
<link href="icon-512.png" rel="apple-touch-icon" sizes="512x512"/>
|
||||||
<link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
|
<link href="icon-192.png" rel="apple-touch-icon" sizes="192x192"/>
|
||||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||||
<link crossorigin href="https://fonts.gstatic.com" rel="preconnect"/>
|
<link crossorigin href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||||
@@ -37,6 +40,26 @@
|
|||||||
<script defer src="/_content/Telerik.UI.for.Blazor/js/telerik-blazor.js"></script>
|
<script defer src="/_content/Telerik.UI.for.Blazor/js/telerik-blazor.js"></script>
|
||||||
<link href="/favicon.png" rel="icon" type="image/png"/>
|
<link href="/favicon.png" rel="icon" type="image/png"/>
|
||||||
<script type="importmap"></script>
|
<script type="importmap"></script>
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-HVMP2QEJLR"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'G-HVMP2QEJLR');
|
||||||
|
|
||||||
|
window.trackPageView = (path) => {
|
||||||
|
gtag('event', 'page_view', {
|
||||||
|
page_path: path,
|
||||||
|
page_location: window.location.origin + path
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
// In development, always fetch from the network and do not cache.
|
// In development, always fetch from the network and do not cache.
|
||||||
// This is appropriate during development as the service worker will wake up and fetch resources from the network.
|
// This is appropriate during development as the service worker will wake up and fetch resources from the network.
|
||||||
self.addEventListener('fetch', () => { });
|
self.addEventListener('fetch', () => {
|
||||||
|
});
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ self.addEventListener('fetch', event => event.respondWith(onFetch(event)));
|
|||||||
|
|
||||||
const cacheNamePrefix = 'offline-cache-';
|
const cacheNamePrefix = 'offline-cache-';
|
||||||
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
|
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
|
||||||
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
|
const offlineAssetsInclude = [/\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/];
|
||||||
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
|
const offlineAssetsExclude = [/^service-worker\.js$/];
|
||||||
|
|
||||||
async function onInstall(event) {
|
async function onInstall(event) {
|
||||||
console.info('Service worker installing');
|
console.info('Service worker installing');
|
||||||
@@ -18,7 +18,7 @@ async function onInstall(event) {
|
|||||||
const assetsRequests = self.assetsManifest.assets
|
const assetsRequests = self.assetsManifest.assets
|
||||||
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
|
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
|
||||||
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
|
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
|
||||||
.map(asset => new Request(asset.url, { integrity: asset.hash, cache: 'no-cache' }));
|
.map(asset => new Request(asset.url, {integrity: asset.hash, cache: 'no-cache'}));
|
||||||
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
|
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
{
|
{
|
||||||
"navigationFallback": {
|
"navigationFallback": {
|
||||||
"rewrite": "/index.html",
|
"rewrite": "/index.html",
|
||||||
"exclude": ["/css/*", "/lib/*", "/_framework/*", "/_content/*", "/sample-data/*"]
|
"exclude": [
|
||||||
|
"/css/*",
|
||||||
|
"/lib/*",
|
||||||
|
"/_framework/*",
|
||||||
|
"/_content/*",
|
||||||
|
"/sample-data/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"id": "frontmatter-folder-organizer",
|
"id": "frontmatter-folder-organizer",
|
||||||
"name": "Frontmatter Folder Organizer",
|
"name": "Frontmatter Folder Organizer",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"minAppVersion": "1.0.0",
|
"minAppVersion": "1.0.0",
|
||||||
"description": "Organize markdown files into folders based on frontmatter hierarchy.",
|
"description": "Organize markdown files into folders based on frontmatter hierarchy.",
|
||||||
"author": "Obsidian",
|
"author": "Obsidian",
|
||||||
"authorUrl": "https://obsidian.md",
|
"authorUrl": "https://obsidian.md",
|
||||||
"isDesktopOnly": false
|
"isDesktopOnly": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ archetypes:
|
|||||||
imageLink: "[[Aardvark Precinct Captain.png]]"
|
imageLink: "[[Aardvark Precinct Captain.png]]"
|
||||||
ranking: A
|
ranking: A
|
||||||
---
|
---
|
||||||
I feel like it easy to always make this card sprout 5, so +5/+5 worth of stats for two man. Plus at that point, it will Immortalize as a +3/+3 and activate [[Deadly Fauna]].
|
|
||||||
|
I feel like it easy to always make this card sprout 5, so +5/+5 worth of stats for two man. Plus at that point, it will
|
||||||
|
Immortalize as a +3/+3 and activate [[Deadly Fauna]].
|
||||||
|
|
||||||
![[Aardvark Precinct Captain.png]]
|
![[Aardvark Precinct Captain.png]]
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ archetypes:
|
|||||||
- "[[Rewound]]"
|
- "[[Rewound]]"
|
||||||
imageLink: "[[Divergence Assassin.png]]"
|
imageLink: "[[Divergence Assassin.png]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
![[Divergence Assassin.png]]
|
![[Divergence Assassin.png]]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ archetypes:
|
|||||||
imageLink: "[[Scuttling Spares.png]]"
|
imageLink: "[[Scuttling Spares.png]]"
|
||||||
rank: S
|
rank: S
|
||||||
---
|
---
|
||||||
|
|
||||||
I haven't played this card, but it sounds like it obviously enables discard.
|
I haven't played this card, but it sounds like it obviously enables discard.
|
||||||
|
|
||||||
![[Scuttling Spares.png]]
|
![[Scuttling Spares.png]]
|
||||||
|
|||||||
@@ -2,4 +2,5 @@
|
|||||||
category: Debuff
|
category: Debuff
|
||||||
description: Set this Agent's strength to 0 until Round End.
|
description: Set this Agent's strength to 0 until Round End.
|
||||||
---
|
---
|
||||||
|
|
||||||
Reduce attack to zero.
|
Reduce attack to zero.
|
||||||
@@ -74,20 +74,30 @@ factions:
|
|||||||
deckCode: AUHUE2LHEBCW4ZLSM54SAQ3POB4QWY3PNZZXI4TVMN2GKZBTAADACASPCICESCQCAUFDCAYGAMCAGAQDDYBQCAYBAOTQCAYQAMDQG
|
deckCode: AUHUE2LHEBCW4ZLSM54SAQ3POB4QWY3PNZZXI4TVMN2GKZBTAADACASPCICESCQCAUFDCAYGAMCAGAQDDYBQCAYBAOTQCAYQAMDQG
|
||||||
deckType: custom
|
deckType: custom
|
||||||
---
|
---
|
||||||
The idea of this deck is to go heavy on stat-efficient cards. Like 2 for a 2/3 [[Kinetic Absorber]], 5/6 [[Lumbering Starseeker]], and 8 for a 9/14 [[Lightsteel Colossus]].
|
|
||||||
|
|
||||||
You got [[Devourer Spawn]] to help push for lethal. It's going to have a bunch of keywords on it, given how popular timelines are in the meta.
|
The idea of this deck is to go heavy on stat-efficient cards. Like 2 for a 2/3 [[Kinetic Absorber]],
|
||||||
|
5/6 [[Lumbering Starseeker]], and 8 for a 9/14 [[Lightsteel Colossus]].
|
||||||
|
|
||||||
You need to Overflow your mana once in a while, or some of your [[Supernova]] removal will be useless. Be pass heavy. And if you do end up overflowing many times [[Supernova]] can refill for mana bar, and it's worth adding some [[Snap Back]]s to the deck to use that spell multiple times.
|
You got [[Devourer Spawn]] to help push for lethal. It's going to have a bunch of keywords on it, given how popular
|
||||||
|
timelines are in the meta.
|
||||||
|
|
||||||
|
You need to Overflow your mana once in a while, or some of your [[Supernova]] removal will be useless. Be pass heavy.
|
||||||
|
And if you do end up overflowing many times [[Supernova]] can refill for mana bar, and it's worth adding
|
||||||
|
some [[Snap Back]]s to the deck to use that spell multiple times.
|
||||||
|
|
||||||
Attack aggressively with [[Brilliant Martyr]]. You really want [[Star Siphon]] to ramp.
|
Attack aggressively with [[Brilliant Martyr]]. You really want [[Star Siphon]] to ramp.
|
||||||
|
|
||||||
As divers, [[Peaceful Synthesizer]] is a 1 drop that will quickly turn into a 3/3. Can't get more stat efficient than that. [[Nonlethal Special Forces]] is to enable [[Phasetide]] for AOE [[Mute]] cards given we don't care about stat buffs. Also as it stands, it always seems to punch a above it's weight on the board given the [[Disarm]] effect.
|
As divers, [[Peaceful Synthesizer]] is a 1 drop that will quickly turn into a 3/3. Can't get more stat efficient than
|
||||||
|
that. [[Nonlethal Special Forces]] is to enable [[Phasetide]] for AOE [[Mute]] cards given we don't care about stat
|
||||||
|
buffs. Also as it stands, it always seems to punch a above it's weight on the board given the [[Disarm]] effect.
|
||||||
|
|
||||||
So ya, [[Curb the Anomalies]] can weaken the enemy board, by shutting off all there better stats, activates, and synergies. Hopefully destroy the entire enemy board in combat.
|
So ya, [[Curb the Anomalies]] can weaken the enemy board, by shutting off all there better stats, activates, and
|
||||||
|
synergies. Hopefully destroy the entire enemy board in combat.
|
||||||
|
|
||||||
And I suppose [[Bearer of the Broth]]. Since the deck has so much raw stats, you will probably find somewhere to heal. Like healing [[Kinetic Absorber]] so it can keep killing after it Immortalizes.
|
And I suppose [[Bearer of the Broth]]. Since the deck has so much raw stats, you will probably find somewhere to heal.
|
||||||
|
Like healing [[Kinetic Absorber]] so it can keep killing after it Immortalizes.
|
||||||
|
|
||||||
Also in practice [[Bearer of the Broth]] has proven to be an insane and reliable draw engine for this deck.
|
Also in practice [[Bearer of the Broth]] has proven to be an insane and reliable draw engine for this deck.
|
||||||
|
|
||||||
[[Gunnery Captain]] helps clear up the board. Tokens are just 1 to 2 cost units that grew to absurd sizes. And [[Army of the Sun]] helps in the mirror match, given how common this deck is due to the precon.
|
[[Gunnery Captain]] helps clear up the board. Tokens are just 1 to 2 cost units that grew to absurd sizes.
|
||||||
|
And [[Army of the Sun]] helps in the mirror match, given how common this deck is due to the precon.
|
||||||
@@ -62,11 +62,13 @@ factions:
|
|||||||
deckCode: AUMU65TFOJTGY33XNFXGOICTMVRXK4TJOR4SAQ3POB4QWY3PNZZXI4TVMN2GKZBRACQAAANZAEBZEAI6AQFTSAYCAMOQGBADAEBQCAZ2AMCAGGQDAQBQCAY
|
deckCode: AUMU65TFOJTGY33XNFXGOICTMVRXK4TJOR4SAQ3POB4QWY3PNZZXI4TVMN2GKZBRACQAAANZAEBZEAI6AQFTSAYCAMOQGBADAEBQCAZ2AMCAGGQDAQBQCAY
|
||||||
deckType: custom
|
deckType: custom
|
||||||
---
|
---
|
||||||
|
|
||||||
Built deck as a joke, but it kind of feels nuts in limited testing.
|
Built deck as a joke, but it kind of feels nuts in limited testing.
|
||||||
|
|
||||||
Mulligan everything for [[Radiant Channeling]] and [[Supernova]]. You are hoping that limited removal keeps you alive.
|
Mulligan everything for [[Radiant Channeling]] and [[Supernova]]. You are hoping that limited removal keeps you alive.
|
||||||
|
|
||||||
If they heavy buff something out from your removal range, you might still have enough reserve to [[Throw into the Sun]] that big target.
|
If they heavy buff something out from your removal range, you might still have enough reserve to [[Throw into the Sun]]
|
||||||
|
that big target.
|
||||||
|
|
||||||
If you survive, start scaling your board with [[Awakened Security System]] or [[Limit Breaker]].
|
If you survive, start scaling your board with [[Awakened Security System]] or [[Limit Breaker]].
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
---
|
---
|
||||||
category: Faction
|
category: Faction
|
||||||
---
|
---
|
||||||
|
|
||||||
Concepts:
|
Concepts:
|
||||||
|
|
||||||
- Wide Boards
|
- Wide Boards
|
||||||
- Overpower
|
- Overpower
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
---
|
---
|
||||||
category: Faction
|
category: Faction
|
||||||
---
|
---
|
||||||
|
|
||||||
Concepts:
|
Concepts:
|
||||||
|
|
||||||
- Healing
|
- Healing
|
||||||
-
|
-
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
---
|
---
|
||||||
category: Faction
|
category: Faction
|
||||||
---
|
---
|
||||||
|
|
||||||
Concepts:
|
Concepts:
|
||||||
|
|
||||||
- Activatable Agents
|
- Activatable Agents
|
||||||
-
|
-
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
---
|
---
|
||||||
category: Faction
|
category: Faction
|
||||||
---
|
---
|
||||||
|
|
||||||
Concepts:
|
Concepts:
|
||||||
|
|
||||||
- Discard
|
- Discard
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
---
|
---
|
||||||
category: Faction
|
category: Faction
|
||||||
---
|
---
|
||||||
|
|
||||||
# Energy Reserves
|
# Energy Reserves
|
||||||
|
|
||||||
Care about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is you [[Overflow]] your energy reserve.
|
Care about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is
|
||||||
|
you [[Overflow]] your energy reserve.
|
||||||
|
|
||||||
Concepts:
|
Concepts:
|
||||||
|
|
||||||
- Ramp
|
- Ramp
|
||||||
- Using and Replenishing Reserved Energy
|
- Using and Replenishing Reserved Energy
|
||||||
-
|
-
|
||||||
@@ -17,4 +17,5 @@ archetypes:
|
|||||||
- "[[Keyword/Sprout]]"
|
- "[[Keyword/Sprout]]"
|
||||||
imageLink: "[[Horticulturist Oswald.png]]"
|
imageLink: "[[Horticulturist Oswald.png]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
![[Horticulturist Oswald.png]]
|
![[Horticulturist Oswald.png]]
|
||||||
@@ -17,4 +17,5 @@ archetypes:
|
|||||||
- "[[Rewound]]"
|
- "[[Rewound]]"
|
||||||
imageLink: "[[Violet Inquisitioner]]"
|
imageLink: "[[Violet Inquisitioner]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
![[Violent Inquisitioner.png]]
|
![[Violent Inquisitioner.png]]
|
||||||
@@ -17,4 +17,5 @@ archetypes:
|
|||||||
- N/A
|
- N/A
|
||||||
imageLink: "[[Scoot Sparkles.png]]"
|
imageLink: "[[Scoot Sparkles.png]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
![[Scoot Sparkles.png]]
|
![[Scoot Sparkles.png]]
|
||||||
@@ -17,4 +17,5 @@ archetypes:
|
|||||||
- N/A
|
- N/A
|
||||||
imageLink: "[[The Ripper.png]]"
|
imageLink: "[[The Ripper.png]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
![[The Ripper.png]]
|
![[The Ripper.png]]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ category: Pass
|
|||||||
---
|
---
|
||||||
|
|
||||||
| Tier | Reward |
|
| Tier | Reward |
|
||||||
| ---- | -------------------------------- |
|
|------|----------------------------------|
|
||||||
| 1 | Sprouts Record |
|
| 1 | Sprouts Record |
|
||||||
| 2 | 120 Core Charges |
|
| 2 | 120 Core Charges |
|
||||||
| 3 | Burn Precon |
|
| 3 | Burn Precon |
|
||||||
@@ -18,5 +18,5 @@ category: Pass
|
|||||||
| 10 | 240 Core Charges, 1 Draft Ticket |
|
| 10 | 240 Core Charges, 1 Draft Ticket |
|
||||||
|
|
||||||
| Core Charges | Flux |
|
| Core Charges | Flux |
|
||||||
| ------------ | ---- |
|
|--------------|------|
|
||||||
| 660 | 75 |
|
| 660 | 75 |
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
category: Quest
|
category: Quest
|
||||||
---
|
---
|
||||||
|
|
||||||
1: 30cc 30xp
|
1: 30cc 30xp
|
||||||
2: 20cc 25xp
|
2: 20cc 25xp
|
||||||
3: 20cc 20xp
|
3: 20cc 20xp
|
||||||
|
|||||||
Reference in New Issue
Block a user