feat: 블로그 시즌 연동 — 홈페이지 세무 정보 섹션 시즌화
- TaxSeason / CurrentSeasonDto에 RelatedCategorySlug 추가 - TaxSeasonCalendar 각 시즌에 카테고리 슬러그 매핑 (income-tax→income-tax, vat-1st/2nd→vat, 종부세→real-estate-tax 등) - IBlogPostRepository.GetByCategorySlugAsync 추가 - BlogService.GetSeasonalPostsAsync: 시즌 관련 글 2개 우선 + 나머지 최신 글로 채움 - IndexModel: SeasonalPosts / RecentPosts 분리 로드 - Index.cshtml 블로그 섹션: 시즌 중 "이번 시즌 추천" 배지 + 시즌별 전체보기 버튼 - site.css: blog-card--seasonal, seasonal-blog-tag, btn-seasonal 스타일 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,9 @@ public class BlogServiceTests
|
|||||||
return Task.FromResult<(IEnumerable<BlogPost>, int)>((items, items.Count));
|
return Task.FromResult<(IEnumerable<BlogPost>, int)>((items, items.Count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<BlogPost>> GetByCategorySlugAsync(string categorySlug, int limit, CancellationToken cancellationToken = default) =>
|
||||||
|
Task.FromResult<IEnumerable<BlogPost>>(Posts.Where(x => x.IsPublished).Take(limit).ToList());
|
||||||
|
|
||||||
public Task<IEnumerable<BlogPost>> GetAllForAdminAsync(CancellationToken cancellationToken = default) =>
|
public Task<IEnumerable<BlogPost>> GetAllForAdminAsync(CancellationToken cancellationToken = default) =>
|
||||||
Task.FromResult<IEnumerable<BlogPost>>(Posts);
|
Task.FromResult<IEnumerable<BlogPost>>(Posts);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public record CurrentSeasonDto
|
|||||||
public string HeroSubtext { get; init; } = "";
|
public string HeroSubtext { get; init; } = "";
|
||||||
public string UrgencyBadge { get; init; } = "";
|
public string UrgencyBadge { get; init; } = "";
|
||||||
public string FocusService { get; init; } = "";
|
public string FocusService { get; init; } = "";
|
||||||
|
public string RelatedCategorySlug { get; init; } = "";
|
||||||
public string CtaText { get; init; } = "상담 신청하기";
|
public string CtaText { get; init; } = "상담 신청하기";
|
||||||
public int DaysUntilDeadline { get; init; }
|
public int DaysUntilDeadline { get; init; }
|
||||||
public DateTime Deadline { get; init; }
|
public DateTime Deadline { get; init; }
|
||||||
|
|||||||
@@ -15,4 +15,6 @@ public record TaxSeason
|
|||||||
public string UrgencyBadge { get; init; } = "";
|
public string UrgencyBadge { get; init; } = "";
|
||||||
public string FocusService { get; init; } = "";
|
public string FocusService { get; init; } = "";
|
||||||
public string CtaText { get; init; } = "상담 신청하기";
|
public string CtaText { get; init; } = "상담 신청하기";
|
||||||
|
/// <summary>블로그 시즌 연동 시 우선 노출할 카테고리 slug (categories.slug 참조)</summary>
|
||||||
|
public string RelatedCategorySlug { get; init; } = "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "일반과세 사업자 확정신고 · 기한 내 신고로 가산세 방지",
|
HeroSubtext = "일반과세 사업자 확정신고 · 기한 내 신고로 가산세 방지",
|
||||||
UrgencyBadge = "D-{n}일 | 부가세 마감",
|
UrgencyBadge = "D-{n}일 | 부가세 마감",
|
||||||
FocusService = "business-tax",
|
FocusService = "business-tax",
|
||||||
CtaText = "부가세 신고 상담"
|
CtaText = "부가세 신고 상담",
|
||||||
|
RelatedCategorySlug = "vat"
|
||||||
},
|
},
|
||||||
new TaxSeason
|
new TaxSeason
|
||||||
{
|
{
|
||||||
@@ -30,7 +31,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "직원이 있는 사업자 원천징수 신고 · 환급 최대화",
|
HeroSubtext = "직원이 있는 사업자 원천징수 신고 · 환급 최대화",
|
||||||
UrgencyBadge = "연말정산 진행 중",
|
UrgencyBadge = "연말정산 진행 중",
|
||||||
FocusService = "business-tax",
|
FocusService = "business-tax",
|
||||||
CtaText = "연말정산 상담"
|
CtaText = "연말정산 상담",
|
||||||
|
RelatedCategorySlug = "business-tax"
|
||||||
},
|
},
|
||||||
new TaxSeason
|
new TaxSeason
|
||||||
{
|
{
|
||||||
@@ -42,7 +44,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "법인사업자 결산 · 세무조정 · 절세 전략 수립",
|
HeroSubtext = "법인사업자 결산 · 세무조정 · 절세 전략 수립",
|
||||||
UrgencyBadge = "D-{n}일 | 법인세 마감",
|
UrgencyBadge = "D-{n}일 | 법인세 마감",
|
||||||
FocusService = "business-tax",
|
FocusService = "business-tax",
|
||||||
CtaText = "법인세 신고 상담"
|
CtaText = "법인세 신고 상담",
|
||||||
|
RelatedCategorySlug = "business-tax"
|
||||||
},
|
},
|
||||||
new TaxSeason
|
new TaxSeason
|
||||||
{
|
{
|
||||||
@@ -54,7 +57,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "개인사업자 · 임대소득 · 프리랜서 · 기타소득 모두 해당",
|
HeroSubtext = "개인사업자 · 임대소득 · 프리랜서 · 기타소득 모두 해당",
|
||||||
UrgencyBadge = "D-{n}일 | 종합소득세 마감",
|
UrgencyBadge = "D-{n}일 | 종합소득세 마감",
|
||||||
FocusService = "business-tax",
|
FocusService = "business-tax",
|
||||||
CtaText = "종합소득세 상담"
|
CtaText = "종합소득세 상담",
|
||||||
|
RelatedCategorySlug = "income-tax"
|
||||||
},
|
},
|
||||||
new TaxSeason
|
new TaxSeason
|
||||||
{
|
{
|
||||||
@@ -66,7 +70,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "일반과세 사업자 1기 확정신고 · 매입세액 공제 점검",
|
HeroSubtext = "일반과세 사업자 1기 확정신고 · 매입세액 공제 점검",
|
||||||
UrgencyBadge = "D-{n}일 | 부가세 마감",
|
UrgencyBadge = "D-{n}일 | 부가세 마감",
|
||||||
FocusService = "business-tax",
|
FocusService = "business-tax",
|
||||||
CtaText = "부가세 신고 상담"
|
CtaText = "부가세 신고 상담",
|
||||||
|
RelatedCategorySlug = "vat"
|
||||||
},
|
},
|
||||||
new TaxSeason
|
new TaxSeason
|
||||||
{
|
{
|
||||||
@@ -78,7 +83,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "다주택자 · 임대사업자 세부담 분석 · 분납·합산배제 검토",
|
HeroSubtext = "다주택자 · 임대사업자 세부담 분석 · 분납·합산배제 검토",
|
||||||
UrgencyBadge = "D-{n}일 | 종부세 납부",
|
UrgencyBadge = "D-{n}일 | 종부세 납부",
|
||||||
FocusService = "real-estate-tax",
|
FocusService = "real-estate-tax",
|
||||||
CtaText = "종부세 절세 상담"
|
CtaText = "종부세 절세 상담",
|
||||||
|
RelatedCategorySlug = "real-estate-tax"
|
||||||
},
|
},
|
||||||
new TaxSeason
|
new TaxSeason
|
||||||
{
|
{
|
||||||
@@ -90,7 +96,8 @@ public static class TaxSeasonCalendar
|
|||||||
HeroSubtext = "증여 공제 한도 · 자산 이전 · 법인전환 연간 마감",
|
HeroSubtext = "증여 공제 한도 · 자산 이전 · 법인전환 연간 마감",
|
||||||
UrgencyBadge = "D-{n}일 | 연간 증여 한도 마감",
|
UrgencyBadge = "D-{n}일 | 연간 증여 한도 마감",
|
||||||
FocusService = "family-asset",
|
FocusService = "family-asset",
|
||||||
CtaText = "연말 절세 상담"
|
CtaText = "연말 절세 상담",
|
||||||
|
RelatedCategorySlug = "family-asset"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,19 @@ public class BlogService(IBlogPostRepository repository, IMemoryCache memoryCach
|
|||||||
public async Task<BlogPost?> GetBySlugAsync(string slug, CancellationToken ct = default) =>
|
public async Task<BlogPost?> GetBySlugAsync(string slug, CancellationToken ct = default) =>
|
||||||
await repository.GetBySlugAsync(slug, ct);
|
await repository.GetBySlugAsync(slug, ct);
|
||||||
|
|
||||||
|
/// <summary>카테고리 슬러그 기준 시즌 관련 글 조회. 부족 시 최신 글로 채워 total개 반환.</summary>
|
||||||
|
public async Task<(IEnumerable<BlogPost> Seasonal, IEnumerable<BlogPost> Latest)> GetSeasonalPostsAsync(
|
||||||
|
string categorySlug, int seasonalCount, int totalCount, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
var seasonal = (await repository.GetByCategorySlugAsync(categorySlug, seasonalCount, ct)).ToList();
|
||||||
|
var seasonalIds = seasonal.Select(p => p.Id).ToHashSet();
|
||||||
|
|
||||||
|
var (latestAll, _) = await repository.GetPublishedPagedAsync(1, totalCount + seasonalCount, null, ct);
|
||||||
|
var latest = latestAll.Where(p => !seasonalIds.Contains(p.Id)).Take(totalCount - seasonal.Count).ToList();
|
||||||
|
|
||||||
|
return (seasonal, latest);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<(IEnumerable<BlogPost>, int)> GetPublishedPagedAsync(
|
public async Task<(IEnumerable<BlogPost>, int)> GetPublishedPagedAsync(
|
||||||
int page, int pageSize, int? categoryId = null, CancellationToken ct = default) =>
|
int page, int pageSize, int? categoryId = null, CancellationToken ct = default) =>
|
||||||
await repository.GetPublishedPagedAsync(NormalizePage(page), NormalizePageSize(pageSize), categoryId, ct);
|
await repository.GetPublishedPagedAsync(NormalizePage(page), NormalizePageSize(pageSize), categoryId, ct);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class SeasonalMarketingService
|
|||||||
HeroSubtext = season.HeroSubtext,
|
HeroSubtext = season.HeroSubtext,
|
||||||
UrgencyBadge = season.UrgencyBadge.Replace("{n}", days.ToString()),
|
UrgencyBadge = season.UrgencyBadge.Replace("{n}", days.ToString()),
|
||||||
FocusService = season.FocusService,
|
FocusService = season.FocusService,
|
||||||
|
RelatedCategorySlug = season.RelatedCategorySlug,
|
||||||
CtaText = season.CtaText,
|
CtaText = season.CtaText,
|
||||||
DaysUntilDeadline = days,
|
DaysUntilDeadline = days,
|
||||||
Deadline = end
|
Deadline = end
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public interface IBlogPostRepository
|
|||||||
Task<BlogPost?> GetBySlugAsync(string slug, CancellationToken cancellationToken = default);
|
Task<BlogPost?> GetBySlugAsync(string slug, CancellationToken cancellationToken = default);
|
||||||
Task<(IEnumerable<BlogPost> Items, int Total)> GetPublishedPagedAsync(
|
Task<(IEnumerable<BlogPost> Items, int Total)> GetPublishedPagedAsync(
|
||||||
int page, int pageSize, int? categoryId = null, CancellationToken cancellationToken = default);
|
int page, int pageSize, int? categoryId = null, CancellationToken cancellationToken = default);
|
||||||
|
Task<IEnumerable<BlogPost>> GetByCategorySlugAsync(string categorySlug, int limit, CancellationToken cancellationToken = default);
|
||||||
Task<IEnumerable<BlogPost>> GetAllForAdminAsync(CancellationToken cancellationToken = default);
|
Task<IEnumerable<BlogPost>> GetAllForAdminAsync(CancellationToken cancellationToken = default);
|
||||||
Task<(IEnumerable<BlogPost> Items, int Total)> GetAdminPagedAsync(
|
Task<(IEnumerable<BlogPost> Items, int Total)> GetAdminPagedAsync(
|
||||||
int page, int pageSize, CancellationToken cancellationToken = default);
|
int page, int pageSize, CancellationToken cancellationToken = default);
|
||||||
|
|||||||
@@ -58,6 +58,21 @@ public class BlogPostRepository(IDbConnectionFactory connectionFactory) : BaseRe
|
|||||||
return (items, total);
|
return (items, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<BlogPost>> GetByCategorySlugAsync(string categorySlug, int limit, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
using var conn = Conn();
|
||||||
|
return await conn.QueryAsync<BlogPost>(
|
||||||
|
@"SELECT bp.id, bp.title, bp.slug, bp.category_id, bp.tags,
|
||||||
|
bp.published_at, bp.view_count, bp.seo_description, bp.thumbnail_url,
|
||||||
|
bp.is_published, bp.created_at, bp.updated_at, c.name AS category_name
|
||||||
|
FROM blog_posts bp
|
||||||
|
LEFT JOIN categories c ON bp.category_id = c.id
|
||||||
|
WHERE bp.is_published = TRUE AND c.slug = @CategorySlug
|
||||||
|
ORDER BY bp.published_at DESC
|
||||||
|
LIMIT @Limit",
|
||||||
|
new { CategorySlug = categorySlug, Limit = limit });
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<BlogPost>> GetAllForAdminAsync(CancellationToken cancellationToken = default)
|
public async Task<IEnumerable<BlogPost>> GetAllForAdminAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
using var conn = Conn();
|
using var conn = Conn();
|
||||||
|
|||||||
@@ -273,33 +273,79 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- 최근 블로그 -->
|
<!-- 세무 정보 블로그 -->
|
||||||
<section class="py-5">
|
<section class="py-5">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="text-center mb-5">
|
<div class="text-center mb-5">
|
||||||
<h2 class="section-title">세무 정보</h2>
|
@if (season != null)
|
||||||
<p class="text-muted">최신 세법 변화와 실무 팁을 공유합니다</p>
|
{
|
||||||
|
<div class="seasonal-blog-header mb-2">
|
||||||
|
<span class="seasonal-blog-tag">📅 @season.Name 시즌</span>
|
||||||
|
</div>
|
||||||
|
<h2 class="section-title">이번 시즌 세무 정보</h2>
|
||||||
|
<p class="text-muted">@season.Name 관련 절세 팁과 신고 가이드를 확인하세요</p>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<h2 class="section-title">세무 정보</h2>
|
||||||
|
<p class="text-muted">최신 세법 변화와 실무 팁을 공유합니다</p>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (Model.RecentPosts?.Count > 0)
|
@{
|
||||||
|
var hasSeasonalPosts = Model.SeasonalPosts?.Count > 0;
|
||||||
|
var hasRecentPosts = Model.RecentPosts?.Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (hasSeasonalPosts || hasRecentPosts)
|
||||||
{
|
{
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
@foreach (var post in Model.RecentPosts.Take(3))
|
@* 시즌 관련 글 (배지 강조) *@
|
||||||
|
@if (hasSeasonalPosts)
|
||||||
{
|
{
|
||||||
<div class="col-lg-4 col-md-6">
|
@foreach (var post in Model.SeasonalPosts!)
|
||||||
<div class="card blog-card h-100">
|
{
|
||||||
<div class="blog-placeholder">📝</div>
|
<div class="col-lg-4 col-md-6">
|
||||||
<div class="card-body">
|
<div class="card blog-card h-100 blog-card--seasonal">
|
||||||
<small class="badge bg-primary-badge">@post.CategoryName</small>
|
<div class="blog-seasonal-ribbon">이번 시즌 추천</div>
|
||||||
<h4 class="card-title mt-3">@post.Title</h4>
|
<div class="blog-placeholder">🗓️</div>
|
||||||
<p class="text-muted small">@post.CreatedAt.ToString("yyyy년 MM월 dd일")</p>
|
<div class="card-body">
|
||||||
<a href="/taxbaik/blog/@post.Slug" class="btn btn-sm btn-primary">글 내용 보기</a>
|
<small class="badge bg-season-badge">@post.CategoryName</small>
|
||||||
|
<h4 class="card-title mt-3">@post.Title</h4>
|
||||||
|
<p class="text-muted small">@((post.PublishedAt ?? post.CreatedAt).ToString("yyyy년 MM월 dd일"))</p>
|
||||||
|
<a href="/taxbaik/blog/@post.Slug" class="btn btn-sm btn-seasonal">자세히 보기</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
|
}
|
||||||
|
@* 최신 글 (나머지 채우기) *@
|
||||||
|
@if (hasRecentPosts)
|
||||||
|
{
|
||||||
|
@foreach (var post in Model.RecentPosts!)
|
||||||
|
{
|
||||||
|
<div class="col-lg-4 col-md-6">
|
||||||
|
<div class="card blog-card h-100">
|
||||||
|
<div class="blog-placeholder">📝</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<small class="badge bg-primary-badge">@post.CategoryName</small>
|
||||||
|
<h4 class="card-title mt-3">@post.Title</h4>
|
||||||
|
<p class="text-muted small">@((post.PublishedAt ?? post.CreatedAt).ToString("yyyy년 MM월 dd일"))</p>
|
||||||
|
<a href="/taxbaik/blog/@post.Slug" class="btn btn-sm btn-primary">글 내용 보기</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-5">
|
|
||||||
|
<div class="text-center mt-5 d-flex justify-content-center gap-3 flex-wrap">
|
||||||
|
@if (season != null && !string.IsNullOrEmpty(season.RelatedCategorySlug))
|
||||||
|
{
|
||||||
|
<a href="/taxbaik/blog?category=@season.RelatedCategorySlug" class="btn btn-outline-seasonal btn-lg">
|
||||||
|
📅 @season.Name 전체 글 보기
|
||||||
|
</a>
|
||||||
|
}
|
||||||
<a href="/taxbaik/blog" class="btn btn-outline-primary btn-lg">전체 블로그 보기</a>
|
<a href="/taxbaik/blog" class="btn btn-outline-primary btn-lg">전체 블로그 보기</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public class IndexModel : PageModel
|
|||||||
private readonly AnnouncementService _announcementService;
|
private readonly AnnouncementService _announcementService;
|
||||||
|
|
||||||
public List<BlogPost> RecentPosts { get; set; } = [];
|
public List<BlogPost> RecentPosts { get; set; } = [];
|
||||||
|
public List<BlogPost> SeasonalPosts { get; set; } = [];
|
||||||
public CurrentSeasonDto? CurrentSeason { get; set; }
|
public CurrentSeasonDto? CurrentSeason { get; set; }
|
||||||
public List<Announcement> ActiveAnnouncements { get; set; } = [];
|
public List<Announcement> ActiveAnnouncements { get; set; } = [];
|
||||||
|
|
||||||
@@ -40,12 +41,23 @@ public class IndexModel : PageModel
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 3);
|
if (CurrentSeason is not null && !string.IsNullOrEmpty(CurrentSeason.RelatedCategorySlug))
|
||||||
RecentPosts = posts.ToList();
|
{
|
||||||
|
var (seasonal, latest) = await _blogService.GetSeasonalPostsAsync(
|
||||||
|
CurrentSeason.RelatedCategorySlug, seasonalCount: 2, totalCount: 3);
|
||||||
|
SeasonalPosts = seasonal.ToList();
|
||||||
|
RecentPosts = latest.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 3);
|
||||||
|
RecentPosts = posts.ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
RecentPosts = [];
|
RecentPosts = [];
|
||||||
|
SeasonalPosts = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -641,3 +641,65 @@ img {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== 블로그 시즌 연동 ===== */
|
||||||
|
.seasonal-blog-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.seasonal-blog-tag {
|
||||||
|
display: inline-block;
|
||||||
|
background: linear-gradient(135deg, #C62828 0%, #B71C1C 100%);
|
||||||
|
color: white;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 4px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-card--seasonal {
|
||||||
|
border: 2px solid var(--color-primary) !important;
|
||||||
|
position: relative;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.blog-seasonal-ribbon {
|
||||||
|
position: absolute;
|
||||||
|
top: -12px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: var(--color-primary);
|
||||||
|
color: white;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 3px 14px;
|
||||||
|
border-radius: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-season-badge {
|
||||||
|
background-color: var(--color-primary) !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-seasonal {
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.btn-seasonal:hover {
|
||||||
|
background-color: var(--color-primary-dark);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-seasonal {
|
||||||
|
border: 2px solid var(--color-primary);
|
||||||
|
color: var(--color-primary);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.btn-outline-seasonal:hover {
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user