api 마켓 스타일 적용

This commit is contained in:
현성필
2025-11-26 15:36:49 +09:00
parent b6141512b6
commit 3e059a9642
51 changed files with 2233 additions and 1256 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 910 B

@@ -12,5 +12,4 @@ html {
body { body {
margin: 0; margin: 0;
background: #fafafa;
} }
@@ -61,7 +61,7 @@
transition: $transition-base; transition: $transition-base;
&:hover { &:hover {
transform: translateY(-5px); //transform: translateY(-5px);
box-shadow: $shadow-lg; box-shadow: $shadow-lg;
} }
} }
@@ -141,4 +141,4 @@
border-radius: 50%; border-radius: 50%;
opacity: 0.1; opacity: 0.1;
position: absolute; position: absolute;
} }
@@ -28,11 +28,6 @@ $gray-800: #1F2937; // Dark gray
$gray-900: #111827; // Darker gray $gray-900: #111827; // Darker gray
// Gradients
$gradient-primary: linear-gradient(135deg, $primary-blue 0%, $secondary-blue 100%);
$gradient-accent: linear-gradient(135deg, $accent-cyan 0%, $primary-blue 100%);
$gradient-warm: linear-gradient(135deg, $accent-yellow 0%, $accent-orange 100%);
// Shadows // Shadows
$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05); $shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05);
$shadow-md: 0 4px 12px rgba(75, 155, 255, 0.1); $shadow-md: 0 4px 12px rgba(75, 155, 255, 0.1);
@@ -313,12 +313,6 @@
left: -50%; left: -50%;
width: 200%; width: 200%;
height: 200%; height: 200%;
background: linear-gradient(
45deg,
transparent 30%,
rgba(255, 255, 255, 0.2) 50%,
transparent 70%
);
transform: rotate(45deg); transform: rotate(45deg);
transition: transform 0.6s ease; transition: transform 0.6s ease;
transform: translateX(-200%); transform: translateX(-200%);
@@ -327,4 +321,4 @@
&:hover::before { &:hover::before {
transform: translateX(200%) rotate(45deg); transform: translateX(200%) rotate(45deg);
} }
} }
@@ -76,19 +76,6 @@ p {
} }
} }
// Text utilities
.text-gradient {
@include gradient-text($gradient-primary);
}
.text-gradient-accent {
@include gradient-text($gradient-accent);
}
.text-gradient-warm {
@include gradient-text($gradient-warm);
}
.text-primary { .text-primary {
color: $primary-blue; color: $primary-blue;
} }
@@ -216,4 +203,4 @@ hr {
border: none; border: none;
border-top: 1px solid $border-gray; border-top: 1px solid $border-gray;
margin: $spacing-xl 0; margin: $spacing-xl 0;
} }
@@ -280,16 +280,9 @@
} }
.bg-gradient-primary { .bg-gradient-primary {
background: $gradient-primary;
} }
.bg-gradient-accent {
background: $gradient-accent;
}
.bg-gradient-warm {
background: $gradient-warm;
}
// Border utilities // Border utilities
.border { .border {
@@ -494,4 +487,4 @@
.transition-none { .transition-none {
transition: none; transition: none;
} }
@@ -23,9 +23,6 @@
.faq-question { .faq-question {
color: $primary-blue; color: $primary-blue;
//&::before {
// background: $gradient-primary;
//}
.faq-icon { .faq-icon {
transform: rotate(180deg); transform: rotate(180deg);
@@ -240,7 +237,7 @@
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
color: $text-dark; color: $text-dark;
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
background: $gradient-primary;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@@ -46,8 +46,8 @@
} }
&-secondary { &-secondary {
background: $secondary-blue; background: #E5E7EB;
color: #6e7780; color: #5F666C;
&:hover { &:hover {
background: $light-bg; background: $light-bg;
@@ -56,7 +56,6 @@
} }
&-accent { &-accent {
background: $gradient-accent;
color: $white; color: $white;
box-shadow: $shadow-md; box-shadow: $shadow-md;
@@ -67,7 +66,6 @@
} }
&-warm { &-warm {
background: $gradient-warm;
color: $white; color: $white;
box-shadow: $shadow-md; box-shadow: $shadow-md;
@@ -200,7 +198,7 @@
right: $spacing-xl; right: $spacing-xl;
width: 60px; width: 60px;
height: 60px; height: 60px;
background: $gradient-primary;
border: none; border: none;
border-radius: $border-radius-circle; border-radius: $border-radius-circle;
color: $white; color: $white;
@@ -306,7 +304,7 @@
// Primary action buttons (new, submit, confirm) // Primary action buttons (new, submit, confirm)
.action-btn-new, .action-btn-new,
.action-btn-primary { .action-btn-primary {
background: $gradient-primary;
color: $white; color: $white;
&:hover { &:hover {
@@ -383,7 +381,7 @@
} }
&.btn-edit { &.btn-edit {
background: $gradient-primary;
color: $white; color: $white;
&:hover { &:hover {
@@ -430,7 +428,7 @@
.btn-action { .btn-action {
padding: $spacing-sm $spacing-lg; padding: $spacing-sm $spacing-lg;
background: $gradient-primary;
color: $white; color: $white;
border: none; border: none;
border-radius: $border-radius-md; border-radius: $border-radius-md;
@@ -16,12 +16,7 @@
left: -50%; left: -50%;
width: 200%; width: 200%;
height: 200%; height: 200%;
background: linear-gradient( background: #3BA4ED;
45deg,
transparent 30%,
rgba($primary-blue, 0.03) 50%,
transparent 70%
);
transform: rotate(45deg); transform: rotate(45deg);
transition: $transition-slow; transition: $transition-slow;
opacity: 0; opacity: 0;
@@ -41,19 +36,17 @@
&:hover { &:hover {
border-color: $primary-blue; border-color: $primary-blue;
transform: translateY(-8px); //transform: translateY(-8px);
} }
// Popular variant // Popular variant
&-popular { &-popular {
border-color: $accent-yellow; border-color: $accent-yellow;
background: linear-gradient(180deg, rgba($accent-yellow, 0.05) 0%, $white 100%);
} }
// New variant // New variant
&-new { &-new {
border-color: $accent-green; border-color: $accent-green;
background: linear-gradient(180deg, rgba($accent-green, 0.05) 0%, $white 100%);
} }
// API badge // API badge
@@ -95,7 +88,7 @@
&:hover .api-icon { &:hover .api-icon {
transform: scale(1.1); transform: scale(1.1);
background: $gradient-primary;
color: $white; color: $white;
} }
@@ -160,7 +153,7 @@
margin: 0 auto $spacing-lg; margin: 0 auto $spacing-lg;
@include flex-center; @include flex-center;
font-size: $font-size-xl; font-size: $font-size-xl;
background: $gradient-primary;
color: $white; color: $white;
border-radius: $border-radius-xl; border-radius: $border-radius-xl;
} }
@@ -213,7 +206,7 @@
width: 48px; width: 48px;
height: 48px; height: 48px;
@include flex-center; @include flex-center;
background: $gradient-primary;
color: $white; color: $white;
border-radius: $border-radius-lg; border-radius: $border-radius-lg;
font-size: $font-size-xl; font-size: $font-size-xl;
@@ -306,7 +299,7 @@
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
padding: $spacing-xs $spacing-md; padding: $spacing-xs $spacing-md;
background: $gradient-primary;
color: $white; color: $white;
border-radius: $border-radius-full; border-radius: $border-radius-full;
font-size: $font-size-xs; font-size: $font-size-xs;
@@ -341,7 +334,6 @@
.amount { .amount {
font-size: $font-size-4xl; font-size: $font-size-4xl;
font-weight: $font-weight-extrabold; font-weight: $font-weight-extrabold;
@include gradient-text($gradient-primary);
} }
.period { .period {
@@ -383,4 +375,4 @@
.pricing-cta { .pricing-cta {
margin-top: auto; margin-top: auto;
} }
} }
@@ -5,6 +5,6 @@
.final-cta { .final-cta {
position: relative; position: relative;
padding: $spacing-6xl * 1.5 0; padding: $spacing-6xl * 1.5 0;
background: $gradient-primary;
overflow: hidden; overflow: hidden;
} }
@@ -283,7 +283,7 @@ select.form-control {
// File upload button (label) // File upload button (label)
.file-upload-btn { .file-upload-btn {
padding: $spacing-md $spacing-lg; padding: $spacing-md $spacing-lg;
background: $gradient-primary;
color: $white; color: $white;
border-radius: $border-radius-md; border-radius: $border-radius-md;
font-size: $font-size-sm; font-size: $font-size-sm;
@@ -375,4 +375,4 @@ select.form-control {
flex-shrink: 0; flex-shrink: 0;
} }
} }
} }
@@ -132,7 +132,7 @@
.profile-header { .profile-header {
padding: $spacing-lg; padding: $spacing-lg;
background: $gradient-primary;
color: $white; color: $white;
text-align: center; text-align: center;
@@ -222,7 +222,7 @@
// =========================== // ===========================
.drawer-user-info { .drawer-user-info {
padding: $spacing-lg; padding: $spacing-lg;
background: $gradient-primary;
border-bottom: 1px solid rgba(255, 255, 255, 0.2); border-bottom: 1px solid rgba(255, 255, 255, 0.2);
.drawer-profile { .drawer-profile {
@@ -1,5 +1,7 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Modal styles // Modal styles - KJBank Design (Figma node 985:1912)
// Close button positioned outside the modal (top-right)
// Gradient header with light blue to white
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Modal backdrop // Modal backdrop
@@ -9,7 +11,7 @@
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.6);
z-index: $z-index-modal-backdrop; z-index: $z-index-modal-backdrop;
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
@@ -26,53 +28,121 @@
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; width: 100%;
bottom: 0; height: 100vh;
z-index: $z-index-modal; z-index: 1000;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: $spacing-lg; padding: $spacing-lg;
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
transition: $transition-base; transition: opacity 0.3s ease, visibility 0.3s ease;
pointer-events: none;
overflow-y: auto;
&.show { &.show {
opacity: 1; opacity: 1;
visibility: visible; visibility: visible;
pointer-events: auto;
.modal-dialog { .modal-dialog {
transform: scale(1); transform: scale(1);
} }
} }
// Responsive adjustments
@media (max-width: $breakpoint-sm) {
padding: $spacing-md;
}
}
// Modal container (includes close button outside)
.modal-container {
position: relative;
max-width: 820px;
width: 100%;
// Size variations
&.modal-sm {
max-width: 500px;
}
&.modal-lg {
max-width: 1000px;
}
&.modal-xl {
max-width: 1200px;
}
@media (max-width: $breakpoint-sm) {
max-width: 100%;
}
}
// Close button - positioned outside modal (top-right)
.modal-close {
position: absolute;
top: 0;
right: 0;
transform: translate(100%, -100%);
width: 50px;
height: 50px;
background: #0049b4;
border: none;
border-radius: 50%;
color: $white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: $z-index-modal;
transition: $transition-base;
box-shadow: $shadow-lg;
svg {
width: 14px;
height: 14px;
}
i {
font-size: 16px;
}
@media (max-width: $breakpoint-sm) {
width: 40px;
height: 40px;
svg {
width: 12px;
height: 12px;
}
i {
font-size: 14px;
}
}
} }
// Modal dialog // Modal dialog
.modal-dialog { .modal-dialog {
margin-top: 150px;
position: relative; position: relative;
background: $white; background: $white;
border-radius: $border-radius-xl; border-radius: $border-radius-lg;
box-shadow: $shadow-xl; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
max-width: 500px; max-width: 700px;
width: 100%; width: calc(100% - 2 * $spacing-lg);
max-height: 90vh; max-height: 85vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transform: scale(0.95); transform: scale(0.95);
transition: $transition-base; transition: transform 0.3s ease;
z-index: $z-index-modal;
// Size variations margin-left: auto;
&.modal-sm { margin-right: auto;
max-width: 400px;
}
&.modal-lg {
max-width: 800px;
}
&.modal-xl {
max-width: 1200px;
}
&.modal-fullscreen { &.modal-fullscreen {
max-width: 100%; max-width: 100%;
@@ -83,75 +153,146 @@
} }
} }
// Modal header // Modal header with gradient background
.modal-header { .modal-header {
padding: $spacing-lg; padding: 30px 50px 20px;
border-bottom: 1px solid $border-gray; background: #C7EAFF;
border-bottom: none;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
border-top-left-radius: $border-radius-lg;
border-top-right-radius: $border-radius-lg;
.modal-title { .modal-title {
font-size: $font-size-xl; font-size: $font-size-xl;
font-weight: $font-weight-semibold; font-weight: $font-weight-semibold;
color: $text-dark; color: #212529;
margin: 0; margin: 0;
} }
.modal-close { @media (max-width: $breakpoint-sm) {
width: 32px; padding: 20px 24px 16px;
height: 32px;
@include flex-center;
background: transparent;
border: none;
border-radius: $border-radius-md;
color: $text-gray;
font-size: $font-size-xl;
cursor: pointer;
transition: $transition-base;
&:hover { .modal-title {
background: $gray-bg; font-size: 18px;
color: $text-dark;
} }
} }
} }
// Modal body // Modal body
.modal-body { .modal-body {
padding: $spacing-lg; padding: 30px 50px;
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
color: $text-dark; color: #212529;
font-size: 20px;
line-height: $line-height-normal; line-height: $line-height-normal;
p {
margin: 0;
& + p {
margin-top: $spacing-md;
}
}
// Center text variant
&.text-center {
text-align: center;
}
@media (max-width: $breakpoint-sm) {
padding: 20px 24px;
font-size: 16px;
}
} }
// Modal footer // Modal footer with buttons
.modal-footer { .modal-footer {
padding: $spacing-lg; padding: 20px 50px 40px;
border-top: 1px solid $border-gray;
display: flex; display: flex;
gap: $spacing-md; gap: 10px;
justify-content: flex-end; justify-content: center;
border-top: none;
&.modal-footer-center { &.modal-footer-end {
justify-content: center; justify-content: flex-end;
} }
&.modal-footer-between { &.modal-footer-between {
justify-content: space-between; justify-content: space-between;
} }
// Cancel button (Figma node 985:1990)
.btn-modal-cancel {
min-width: 150px;
height: 50px;
padding: 10px 40px;
background: $white;
border: 1px solid #dadada;
border-radius: 50px;
font-size: 16px;
font-weight: $font-weight-bold;
color: #5f666c;
cursor: pointer;
transition: $transition-base;
&:hover {
background: #f5f5f5;
border-color: #c0c0c0;
}
&:active {
transform: scale(0.98);
}
}
// Confirm button (Figma node 985:1989)
.btn-modal-confirm {
min-width: 150px;
height: 50px;
padding: 10px 40px;
background: #0049b4;
border: none;
border-radius: 50px;
font-size: 16px;
font-weight: $font-weight-bold;
color: $white;
cursor: pointer;
transition: $transition-base;
&:hover {
background: #003a91;
}
&:active {
transform: scale(0.98);
}
}
@media (max-width: $breakpoint-sm) {
padding: 16px 24px 24px;
flex-direction: column;
.btn-modal-cancel,
.btn-modal-confirm {
width: 100%;
height: 46px;
font-size: 15px;
}
}
} }
// Alert modal // Alert modal
.modal-alert { .modal-alert {
.modal-dialog { .modal-container {
max-width: 400px; max-width: 500px;
} }
.modal-body { .modal-body {
text-align: center; text-align: center;
padding: $spacing-xl; padding: $spacing-xl 50px;
.alert-icon { .alert-icon {
width: 64px; width: 64px;
@@ -191,6 +332,7 @@
.alert-message { .alert-message {
color: $text-gray; color: $text-gray;
font-size: $font-size-base;
} }
} }
} }
@@ -334,7 +334,7 @@
//button { //button {
// padding: $spacing-sm $spacing-lg; // padding: $spacing-sm $spacing-lg;
// background: $gradient-primary; //
// color: $white; // color: $white;
// border: none; // border: none;
// border-radius: $border-radius-md; // border-radius: $border-radius-md;
@@ -63,16 +63,7 @@
background: $light-bg; background: $light-bg;
} }
&-gradient {
background: linear-gradient(180deg, $white 0%, $light-bg 100%);
}
&-gradient-reverse {
background: linear-gradient(180deg, $light-bg 0%, $white 100%);
}
&-primary { &-primary {
background: $gradient-primary;
color: $white; color: $white;
} }
@@ -115,7 +106,6 @@
} }
.title-highlight { .title-highlight {
@include gradient-text($gradient-accent);
} }
} }
@@ -155,4 +145,4 @@
.inner-content { .inner-content {
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
@@ -22,11 +22,6 @@
--light-bg: #EFF6FF; --light-bg: #EFF6FF;
--border-gray: #E2E8F0; --border-gray: #E2E8F0;
// Gradients
--gradient-primary: linear-gradient(135deg, #4B9BFF 0%, #2E7FF7 100%);
--gradient-accent: linear-gradient(135deg, #00D4FF 0%, #4B9BFF 100%);
--gradient-warm: linear-gradient(135deg, #FFD93D 0%, #FF6B6B 100%);
// Shadows // Shadows
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05); --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(75, 155, 255, 0.1); --shadow-md: 0 4px 12px rgba(75, 155, 255, 0.1);
@@ -429,7 +424,6 @@
justify-content: center; justify-content: center;
gap: 8px; gap: 8px;
padding: 14px 20px; padding: 14px 20px;
background: var(--gradient-primary);
color: var(--white); color: var(--white);
text-decoration: none; text-decoration: none;
border-radius: 12px; border-radius: 12px;
@@ -706,7 +700,6 @@
align-items: center; align-items: center;
gap: 8px; gap: 8px;
text-decoration: none; text-decoration: none;
background: var(--gradient-primary);
color: var(--white); color: var(--white);
padding: 12px 24px; padding: 12px 24px;
border-radius: 50px; border-radius: 50px;
+1
View File
@@ -33,6 +33,7 @@
@import 'components/header-auth'; @import 'components/header-auth';
@import 'components/tables'; @import 'components/tables';
@import 'components/accordion'; @import 'components/accordion';
@import 'components/page-title-banner';
// 5. Page-specific styles // 5. Page-specific styles
@import 'pages/index'; @import 'pages/index';
@@ -8,18 +8,18 @@
min-height: 100vh; min-height: 100vh;
background-color: $white; background-color: $white;
position: relative; position: relative;
margin-bottom: 20px;
} }
// Sidebar Navigation // Sidebar Navigation
.api-market-sidebar { .api-market-sidebar {
width: 283px; width: 283px;
background-color: #FDFDFD; background-color: #F8FBFD;
border-radius: 20px; border-radius: 20px;
padding: $spacing-2xl $spacing-lg; padding: $spacing-2xl $spacing-lg;
position: sticky; position: sticky;
top: $spacing-lg; top: $spacing-lg;
height: calc(100vh - 32px); height: calc(100vh - 32px);
overflow-y: auto;
flex-shrink: 0; flex-shrink: 0;
margin: $spacing-md; margin: $spacing-md;
@@ -69,8 +69,8 @@
.menu-title { .menu-title {
padding: 16px 10px; padding: 16px 10px;
font-size: $font-size-sm; font-size: $font-size-lg;
font-weight: $font-weight-semibold; font-weight: $font-weight-regular;
color: $text-dark; color: $text-dark;
cursor: pointer; cursor: pointer;
transition: $transition-base; transition: $transition-base;
@@ -84,20 +84,8 @@
} }
&.active { &.active {
color: $secondary-blue; font-weight: $font-weight-bold;
color: $primary-blue;
&::after {
content: '';
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border-style: solid;
border-width: 6px 0 6px 8px;
border-color: transparent transparent transparent $text-dark;
}
} }
.api-count { .api-count {
@@ -121,11 +109,60 @@
} }
} }
// Level 2: API List // Accordion Section
.accordion-section {
.menu-title.accordion-trigger {
.menu-title-text {
flex: 1;
}
.accordion-icon {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
transition: transform 0.3s ease;
i {
font-size: 12px;
color: $text-gray;
transition: $transition-base;
}
}
&:hover .accordion-icon i {
color: $primary-blue;
}
&.expanded .accordion-icon {
transform: rotate(180deg);
}
&.active .accordion-icon i {
color: $primary-blue;
}
}
}
// Level 2: API List (Accordion Content)
.api-list { .api-list {
padding-left: $spacing-md; padding-left: $spacing-md;
margin-top: $spacing-xs; margin-top: 0;
margin-bottom: $spacing-sm; margin-bottom: 0;
// Accordion animation
&.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease, padding 0.3s ease, margin 0.3s ease;
&.expanded {
max-height: 500px; // Enough height for content
margin-top: $spacing-xs;
margin-bottom: $spacing-sm;
}
}
} }
.api-item { .api-item {
@@ -179,7 +216,9 @@
// Main Content Area // Main Content Area
.api-market-content { .api-market-content {
flex: 1; flex: 1;
padding: $spacing-2xl $spacing-3xl; padding-top: $spacing-5xl;
padding-left: $spacing-sm;
padding-right: $spacing-sm;
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -187,6 +226,18 @@
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
padding: $spacing-lg $spacing-md; padding: $spacing-lg $spacing-md;
} }
// Result Count (inside header)
.api-result-count {
font-size: $font-size-lg;
color: $black;
white-space: nowrap;
strong {
color: $primary-blue;
font-weight: $font-weight-semibold;
}
}
} }
// Mobile Menu Toggle // Mobile Menu Toggle
@@ -197,7 +248,7 @@
right: $spacing-lg; right: $spacing-lg;
width: 56px; width: 56px;
height: 56px; height: 56px;
background: $gradient-primary;
border-radius: $border-radius-circle; border-radius: $border-radius-circle;
border: none; border: none;
color: $white; color: $white;
@@ -228,7 +279,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: $spacing-2xl; margin-bottom: $spacing-lg;
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
flex-direction: column; flex-direction: column;
@@ -320,17 +371,7 @@
} }
} }
// Result Count
.api-result-count {
font-size: $font-size-base;
color: $text-gray;
margin-bottom: $spacing-xl;
strong {
color: $primary-blue;
font-weight: $font-weight-semibold;
}
}
// Card Grid // Card Grid
.api-card-grid { .api-card-grid {
@@ -555,12 +596,12 @@
} }
} }
// API Overview Card // API Overview Card (Flat Style)
.api-overview-card { .api-overview-card {
background: $white; background: transparent;
border-radius: $border-radius-lg; border-radius: 0;
padding: $spacing-xl; padding: 0;
box-shadow: $shadow-sm; padding-bottom: $spacing-xl;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: $spacing-lg; gap: $spacing-lg;
@@ -578,12 +619,14 @@
} }
.api-method-badge { .api-method-badge {
background: $primary-blue;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-shrink: 0; flex-shrink: 0;
padding: 8px 16px; padding: 8px 16px;
background: $gradient-primary; height: 100%;
color: $white; color: $white;
font-size: $font-size-sm; font-size: $font-size-sm;
font-weight: $font-weight-semibold; font-weight: $font-weight-semibold;
@@ -637,16 +680,17 @@
gap: $spacing-lg; gap: $spacing-lg;
} }
// API Detail Card // API Detail Card (Flat Style)
.api-detail-card { .api-detail-card {
background: $white; background: transparent;
border-radius: $border-radius-lg; border-radius: 0;
padding: $spacing-xl; padding: 0;
box-shadow: $shadow-sm; padding-bottom: $spacing-xl;
transition: $transition-base; border-bottom: 1px solid $border-gray;
&:hover { &:last-child {
box-shadow: $shadow-md; border-bottom: none;
padding-bottom: 0;
} }
h3 { h3 {
@@ -654,8 +698,8 @@
font-weight: $font-weight-semibold; font-weight: $font-weight-semibold;
color: $text-dark; color: $text-dark;
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
padding-bottom: $spacing-sm; padding-bottom: 0;
border-bottom: 2px solid $light-bg; border-bottom: none;
} }
.detail-content { .detail-content {
File diff suppressed because it is too large Load Diff
@@ -1464,13 +1464,6 @@
.stats-divider { .stats-divider {
width: 1px; width: 1px;
height: 240px; height: 240px;
background: linear-gradient(
to bottom,
transparent 0%,
rgba(255, 255, 255, 0.2) 20%,
rgba(255, 255, 255, 0.2) 80%,
transparent 100%
);
margin: 0 60px; margin: 0 60px;
flex-shrink: 0; flex-shrink: 0;
@@ -31,7 +31,6 @@
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
color: $text-dark; color: $text-dark;
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
background: $gradient-primary;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@@ -320,7 +319,6 @@
.detail-header { .detail-header {
padding: $spacing-3xl $spacing-2xl $spacing-xl; padding: $spacing-3xl $spacing-2xl $spacing-xl;
border-bottom: 2px solid $border-gray; border-bottom: 2px solid $border-gray;
background: linear-gradient(180deg, $light-bg 0%, $white 100%);
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
padding: $spacing-2xl $spacing-lg $spacing-md; padding: $spacing-2xl $spacing-lg $spacing-md;
@@ -542,7 +540,6 @@
} }
&.btn-edit { &.btn-edit {
background: $gradient-primary;
color: $white; color: $white;
&:hover { &:hover {
@@ -51,7 +51,6 @@
align-items: center; align-items: center;
gap: $spacing-sm; gap: $spacing-sm;
padding: 12px 24px; padding: 12px 24px;
background: $gradient-primary;
color: $white; color: $white;
border: none; border: none;
border-radius: $border-radius-lg; border-radius: $border-radius-lg;
@@ -121,7 +120,6 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
width: 4px; width: 4px;
background: $gradient-primary;
transform: scaleY(0); transform: scaleY(0);
transform-origin: top; transform-origin: top;
transition: transform 0.3s ease; transition: transform 0.3s ease;
@@ -273,7 +271,6 @@
align-items: center; align-items: center;
gap: $spacing-sm; gap: $spacing-sm;
padding: 14px 32px; padding: 14px 32px;
background: $gradient-primary;
color: $white; color: $white;
border: none; border: none;
border-radius: $border-radius-lg; border-radius: $border-radius-lg;
@@ -340,4 +337,4 @@
font-size: 60px; font-size: 60px;
} }
} }
} }
@@ -31,7 +31,6 @@
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
color: $text-dark; color: $text-dark;
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
background: $gradient-primary;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@@ -89,7 +88,6 @@
.detail-header { .detail-header {
padding: $spacing-3xl $spacing-2xl $spacing-xl; padding: $spacing-3xl $spacing-2xl $spacing-xl;
border-bottom: 2px solid $border-gray; border-bottom: 2px solid $border-gray;
background: linear-gradient(180deg, $light-bg 0%, $white 100%);
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
padding: $spacing-2xl $spacing-lg $spacing-md; padding: $spacing-2xl $spacing-lg $spacing-md;
@@ -4,63 +4,6 @@
@import '../abstracts/variables'; @import '../abstracts/variables';
@import '../abstracts/mixins'; @import '../abstracts/mixins';
// Page Title Banner
.page-title-banner {
position: relative;
width: 100%;
height: 220px;
background: linear-gradient(to right, #E8F4FD 0%, #F0F8FF 100%);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h100v100H0z' fill='%23ffffff' opacity='0.03'/%3E%3C/svg%3E");
background-size: 50px 50px;
opacity: 0.5;
}
.title-image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 220px;
width: auto;
z-index: 1;
}
h1 {
position: relative;
font-size: $font-size-3xl;
font-weight: $font-weight-bold;
color: $text-dark;
margin: 0;
z-index: 2;
letter-spacing: -0.5px;
}
@include respond-to('sm') {
height: 120px;
margin-bottom: $spacing-xl;
.title-image {
height: 120px;
}
h1 {
font-size: $font-size-xl;
}
}
}
// Main Registration Container // Main Registration Container
.org-register-page { .org-register-page {
min-height: 100vh; min-height: 100vh;
@@ -169,7 +112,6 @@
// Info Notice // Info Notice
.org-info-notice { .org-info-notice {
background: linear-gradient(135deg, #EFF6FF 0%, #F0F9FF 100%);
padding: $spacing-lg; padding: $spacing-lg;
border-radius: $border-radius-md; border-radius: $border-radius-md;
margin-bottom: $spacing-xl; margin-bottom: $spacing-xl;
@@ -421,12 +363,8 @@
} }
.org-btn-primary { .org-btn-primary {
background: linear-gradient(135deg, $primary-blue 0%, $secondary-blue 100%);
color: $white; color: $white;
&:not(:disabled):hover {
background: linear-gradient(135deg, $secondary-blue 0%, $primary-blue 100%);
}
} }
.org-btn-secondary { .org-btn-secondary {
@@ -511,7 +449,6 @@
.org-file-notice { .org-file-notice {
margin-top: $spacing-md; margin-top: $spacing-md;
padding: $spacing-md; padding: $spacing-md;
background: linear-gradient(135deg, #FFF7ED 0%, #FFFBEB 100%);
border-radius: $border-radius-sm; border-radius: $border-radius-sm;
p { p {
@@ -106,27 +106,11 @@
} }
.signup-btn-individual { .signup-btn-individual {
background: linear-gradient(90deg, #0049B4 0%, #0049B4 100%); background: #0049B4;
&:hover {
background: linear-gradient(90deg, darken(#0049B4, 5%) 0%, darken(#0049B4, 5%) 100%);
}
&:active {
background: linear-gradient(90deg, darken(#0049B4, 10%) 0%, darken(#0049B4, 10%) 100%);
}
} }
.signup-btn-organization { .signup-btn-organization {
background: linear-gradient(90deg, #00A1D7 0%, #00A1D7 100%); background: #00A1D7;
&:hover {
background: linear-gradient(90deg, darken(#00A1D7, 5%) 0%, darken(#00A1D7, 5%) 100%);
}
&:active {
background: linear-gradient(90deg, darken(#00A1D7, 10%) 0%, darken(#00A1D7, 10%) 100%);
}
} }
.signup-navigation { .signup-navigation {
@@ -32,7 +32,6 @@
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
color: $text-dark; color: $text-dark;
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
background: $gradient-primary;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@@ -328,7 +328,6 @@
// Profile Card // Profile Card
.user-profile-card { .user-profile-card {
background: linear-gradient(135deg, $primary-blue 0%, $secondary-blue 100%);
color: $white; color: $white;
margin-bottom: $spacing-xl; margin-bottom: $spacing-xl;
position: relative; position: relative;
@@ -2,39 +2,53 @@
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/kjbank_base_layout}"> layout:decorate="~{layout/kjbank_title_layout}">
<body> <body>
<th:block layout:fragment="title">
<div class="page-title-banner" style="margin-bottom: 24px;">
<h1>API 마켓</h1>
</div>
</th:block>
<th:block layout:fragment="contentFragment"> <th:block layout:fragment="contentFragment">
<section class="api-market-container"> <section class="api-market-container">
<!-- Sidebar Navigation --> <!-- Sidebar Navigation -->
<aside class="api-market-sidebar" id="apiSidebar"> <aside class="api-market-sidebar" id="apiSidebar">
<div class="api-sidebar-header">
<img th:src="@{/img/api_sidebar.png}" alt="API">
</div>
<nav class="api-sidebar-nav"> <nav class="api-sidebar-nav">
<!-- All APIs --> <!-- All APIs -->
<div class="menu-section"> <div class="menu-section">
<div class="menu-title" th:classappend="${selected == '-1'} ? 'active'" data-group=""> <a class="menu-title" th:classappend="${selected == '-1'} ? 'active'" th:href="@{/apis}">
전체 전체
<span class="api-count" th:text="${totalApiCount}">0</span> </a>
</div>
</div> </div>
<!-- Service Categories --> <!-- Service Categories (Accordion) -->
<div class="menu-section" th:each="service : ${services}"> <div class="menu-section accordion-section" th:each="service : ${services}">
<div class="menu-title" <div class="menu-title accordion-trigger"
th:classappend="${selected == service.id} ? 'active'" th:classappend="${selected == service.id} ? 'active expanded'"
th:data-group="${service.id}"> th:data-group="${service.id}">
[[${service.groupName}]] <span class="menu-title-text">[[${service.groupName}]]</span>
<span class="api-count" th:text="${service.apiGroupApiList.size()}">0</span> <span class="accordion-icon">
<i class="fas fa-chevron-down"></i>
</span>
</div> </div>
<!-- Level 2: API List --> <!-- Level 2: API List (Accordion Content) -->
<div class="api-list" th:if="${service.apiGroupApiList != null and !service.apiGroupApiList.isEmpty()}"> <div class="api-list accordion-content"
th:if="${service.apiGroupApiList != null and !service.apiGroupApiList.isEmpty()}"
th:classappend="${selected == service.id} ? 'expanded'">
<div class="api-item" <div class="api-item"
th:each="api : ${service.apiGroupApiList}" th:each="api : ${service.apiGroupApiList}"
th:data-api-id="${api.apiId}" th:data-api-id="${api.apiId}"
th:attr="data-href=@{/apis/detail(apiId=${api.apiId})}"> th:classappend="${apiSpecInfo != null and apiSpecInfo.apiId == api.apiId} ? 'active'"
th:attr="data-href=@{/apis/detail(id=${api.apiId})}">
<span class="api-name" th:text="${api.apiDesc}">API Name</span> <span class="api-name" th:text="${api.apiDesc}">API Name</span>
</div> </div>
</div> </div>
@@ -73,74 +87,83 @@
<div class="tab-content active" id="api-info-tab"> <div class="tab-content active" id="api-info-tab">
<!-- API Overview Card (Merged with Additional Information) --> <!-- API Overview Card (Merged with Additional Information) -->
<div class="api-overview-card"> <div class="api-overview-card">
<div class="api-overview-header"> <div class="org-section-header org-section-header--agreement">
<div class="api-method-badge" th:text="${apiSpecInfo.apiMethod}">GET</div> <h3>기본 정보</h3>
<div class="api-endpoint">
<code th:text="${apiSpecInfo.apiUrl}">/api/v1/example</code>
</div> </div>
</div> <div class="api-overview-header">
<!-- API Information Table --> <div class="api-method-badge" th:text="${apiSpecInfo.apiMethod}">GET</div>
<div class="api-overview-info"> <div class="api-endpoint">
<table class="api-info-table"> <code th:text="${apiSpecInfo.apiUrl}">/api/v1/example</code>
<tr th:if="${apiSpecInfo.apiContentType != null}"> </div>
<th>Content Type</th> </div>
<td th:text="${apiSpecInfo.apiContentType}">application/json</td> <!-- API Information Table -->
</tr> <div class="api-overview-info">
</table> <table class="api-info-table">
</div> <tr th:if="${apiSpecInfo.apiContentType != null}">
<div class="api-simple-description" th:if="${apiSpecInfo.apiSimpleDescription != null}"> <th>Content Type</th>
<p th:text="${apiSpecInfo.apiSimpleDescription}">Simple API description</p> <td th:text="${apiSpecInfo.apiContentType}">application/json</td>
</div> </tr>
<div class="detail-content" th:utext="${apiSpecInfo.description}"> </table>
Detailed API description </div>
</div> <div class="api-simple-description" th:if="${apiSpecInfo.apiSimpleDescription != null}">
</div> <p th:text="${apiSpecInfo.apiSimpleDescription}">Simple API description</p>
</div>
<!-- API Details Grid --> <div class="detail-content" th:utext="${apiSpecInfo.description}">
<div class="api-details-grid"> Detailed API description
<!-- Request Specification -->
<div class="api-detail-card" th:if="${apiSpecInfo.apiRequestSpec != null}">
<h3>Request Specification</h3>
<div class="detail-content" th:utext="${apiSpecInfo.apiRequestSpec}">
Request spec
</div> </div>
</div> </div>
<!-- Sample Request --> <!-- API Details Grid -->
<div class="api-detail-card" th:if="${apiSpecInfo.sampleRequest != null}"> <div class="api-details-grid">
<h3>샘플 요청</h3>
<div class="detail-content">
<pre><code th:text="${apiSpecInfo.sampleRequest}">Sample request</code></pre>
</div>
</div>
<!-- Response Specification --> <!-- Request Specification -->
<div class="api-detail-card" th:if="${apiSpecInfo.apiResponseSpec != null}"> <div class="api-detail-card" th:if="${apiSpecInfo.apiRequestSpec != null}">
<h3>Response Specification</h3> <div class="org-section-header org-section-header--agreement">
<div class="detail-content" th:utext="${apiSpecInfo.apiResponseSpec}"> <h3>Request Specification</h3>
Response spec </div>
<div class="detail-content" th:utext="${apiSpecInfo.apiRequestSpec}">
Request spec
</div>
</div> </div>
</div>
<!-- Sample Response --> <!-- Sample Request -->
<div class="api-detail-card" th:if="${apiSpecInfo.sampleResponse != null}"> <div class="api-detail-card" th:if="${apiSpecInfo.sampleRequest != null}">
<h3>샘플 응답</h3> <div class="org-section-header org-section-header--agreement">
<div class="detail-content"> <h3>샘플 요청</h3>
<pre><code th:text="${apiSpecInfo.sampleResponse}">Sample response</code></pre> </div>
<div class="detail-content">
<pre><code th:text="${apiSpecInfo.sampleRequest}">Sample request</code></pre>
</div>
</div>
<!-- Response Specification -->
<div class="api-detail-card" th:if="${apiSpecInfo.apiResponseSpec != null}">
<div class="org-section-header org-section-header--agreement">
<h3>Response Specification</h3>
</div>
<div class="detail-content" th:utext="${apiSpecInfo.apiResponseSpec}">
Response spec
</div>
</div>
<!-- Sample Response -->
<div class="api-detail-card" th:if="${apiSpecInfo.sampleResponse != null}">
<div class="org-section-header org-section-header--agreement">
<h3>샘플 응답</h3>
</div>
<div class="detail-content">
<pre><code th:text="${apiSpecInfo.sampleResponse}">Sample response</code></pre>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Testbed Tab Content --> <!-- Testbed Tab Content -->
<div class="tab-content" id="testbed-tab"> <div class="tab-content" id="testbed-tab">
<link rel="stylesheet" type="text/css" th:href="@{/plugins/swaggerUI/swagger-ui.css}"/> <link rel="stylesheet" type="text/css" th:href="@{/plugins/swaggerUI/swagger-ui.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/plugins/swaggerUI/index.css}"/> <link rel="stylesheet" type="text/css" th:href="@{/plugins/swaggerUI/index.css}"/>
<div class="api-overview-card"> <div id="swagger-ui"></div>
<div id="swagger-ui"></div>
</div>
</div> </div>
</div> </div>
@@ -207,7 +230,31 @@
}); });
}); });
// Category/Service Selection - removed as not needed in detail page // Accordion Toggle Functionality
const accordionTriggers = document.querySelectorAll('.accordion-trigger');
accordionTriggers.forEach(function(trigger) {
trigger.addEventListener('click', function(e) {
e.preventDefault();
const menuSection = this.closest('.accordion-section');
const accordionContent = menuSection.querySelector('.accordion-content');
if (accordionContent) {
// Toggle expanded state
const isExpanded = this.classList.contains('expanded');
if (isExpanded) {
// Close this accordion
this.classList.remove('expanded');
accordionContent.classList.remove('expanded');
} else {
// Open this accordion
this.classList.add('expanded');
accordionContent.classList.add('expanded');
}
}
});
});
// Mobile Menu Toggle // Mobile Menu Toggle
if (mobileToggle && sidebar && mobileOverlay) { if (mobileToggle && sidebar && mobileOverlay) {
@@ -6,7 +6,7 @@
<body> <body>
<th:block layout:fragment="title"> <th:block layout:fragment="title">
<div class="page-title-banner" style="margin-bottom: 40px;"> <div class="page-title-banner" style="margin-bottom: 24px;">
<h1>API 마켓</h1> <h1>API 마켓</h1>
</div> </div>
</th:block> </th:block>
@@ -26,7 +26,6 @@
<div class="menu-section"> <div class="menu-section">
<div class="menu-title" th:classappend="${selected == '-1'} ? 'active'" data-group=""> <div class="menu-title" th:classappend="${selected == '-1'} ? 'active'" data-group="">
전체 전체
<span class="api-count" th:text="${totalApiCount}">0</span>
</div> </div>
</div> </div>
@@ -36,7 +35,6 @@
th:classappend="${selected == service.id} ? 'active'" th:classappend="${selected == service.id} ? 'active'"
th:data-group="${service.id}"> th:data-group="${service.id}">
[[${service.groupName}]] [[${service.groupName}]]
<span class="api-count" th:text="${service.apiGroupApiList.size()}">0</span>
</div> </div>
</div> </div>
</nav> </nav>
@@ -53,8 +51,11 @@
<!-- Main Content --> <!-- Main Content -->
<main class="api-market-content"> <main class="api-market-content">
<!-- Header --> <!-- Header: Result Count + Search -->
<div class="api-market-header"> <div class="api-market-header">
<div class="api-result-count">
<strong th:text="${selectedApiCount}">0</strong>
</div>
<div class="api-market-search"> <div class="api-market-search">
<form id="searchForm" th:action="@{/apis}" method="get"> <form id="searchForm" th:action="@{/apis}" method="get">
<input type="hidden" name="groupIds" th:value="${search.groupIds != null and !search.groupIds.isEmpty() ? search.groupIds[0] : ''}"/> <input type="hidden" name="groupIds" th:value="${search.groupIds != null and !search.groupIds.isEmpty() ? search.groupIds[0] : ''}"/>
@@ -64,17 +65,14 @@
th:value="${search.keyword}" th:value="${search.keyword}"
placeholder="어떤 API를 찾고 계신가요?"> placeholder="어떤 API를 찾고 계신가요?">
<button type="submit" class="search-submit-btn" aria-label="검색"> <button type="submit" class="search-submit-btn" aria-label="검색">
<span class="search-icon">🔍</span> <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.23047 0C14.3285 0 18.4618 4.0539 18.4619 9.05469C18.4619 11.1083 17.7634 13.0014 16.5889 14.5205C16.5913 14.5229 16.5942 14.5249 16.5967 14.5273L19.5498 17.4238C20.1502 18.0131 20.1501 18.9683 19.5498 19.5576C18.949 20.147 17.9748 20.147 17.374 19.5576L14.4209 16.6621C14.3966 16.6383 14.3749 16.6119 14.3525 16.5869C12.8868 17.5478 11.1257 18.1094 9.23047 18.1094C4.13258 18.1092 0 14.0554 0 9.05469C0.000110268 4.05404 4.13265 0.000222701 9.23047 0ZM9.23047 3.01855C5.83201 3.01878 3.07726 5.721 3.07715 9.05469C3.07715 12.3885 5.83194 15.0916 9.23047 15.0918C12.6292 15.0918 15.3848 12.3886 15.3848 9.05469C15.3847 5.72086 12.6291 3.01855 9.23047 3.01855Z" fill="#515961"/>
</svg>
</button> </button>
</form> </form>
</div> </div>
</div> </div>
<!-- Result Count -->
<div class="api-result-count">
<strong th:text="${selectedApiCount}">0</strong>
</div>
<!-- API Cards Grid --> <!-- API Cards Grid -->
<div class="api-card-grid" th:if="${apis != null and !apis.isEmpty()}"> <div class="api-card-grid" th:if="${apis != null and !apis.isEmpty()}">
<div class="api-card" <div class="api-card"