This commit is contained in:
Nick 2025-06-09 20:54:05 +01:00
parent 0e0d9ec183
commit 0d133a7bef
111 changed files with 782 additions and 172 deletions

View File

@ -21,6 +21,8 @@ namespace CatherineLynwood.Controllers
public async Task<IActionResult> Index(bool showThanks)
{
ViewData["VpnWarning"] = HttpContext.Items.ContainsKey("IsVpn") && (bool)HttpContext.Items["IsVpn"];
Questions questions = await _dataAccess.GetQuestionsAsync();
questions.ShowThanks = showThanks;

View File

@ -33,6 +33,12 @@ namespace CatherineLynwood.Controllers
#region Public Methods
[Route("collaboration-inquiry")]
public IActionResult Honeypot()
{
return View();
}
[Route("about-catherine-lynwood")]
public IActionResult AboutCatherineLynwood()
{
@ -43,6 +49,8 @@ namespace CatherineLynwood.Controllers
[HttpGet]
public async Task<IActionResult> ContactCatherine()
{
ViewData["VpnWarning"] = HttpContext.Items.ContainsKey("IsVpn") && (bool)HttpContext.Items["IsVpn"];
Contact contact = new Contact();
return View(contact);
@ -155,6 +163,12 @@ namespace CatherineLynwood.Controllers
return View();
}
[Route("offline")]
public IActionResult Offline()
{
return View();
}
// Helper method to convert the original image URL to a 400px JPEG URL in the "jpg" folder
private string ConvertToJpgUrl(string originalFileName)
{

View File

@ -105,6 +105,11 @@ namespace CatherineLynwood.Controllers
{
return View();
}
[Route("chapters/chapter-13-susie")]
public IActionResult Chapter13()
{
return View();
}
[Route("characters")]
public IActionResult Characters()

View File

@ -0,0 +1,56 @@
using CatherineLynwood.Services;
using System.Text.Json;
namespace CatherineLynwood.Middleware
{
public class HoneypotLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<HoneypotLoggingMiddleware> _logger;
private DataAccess _dataAccess;
public HoneypotLoggingMiddleware(RequestDelegate next, ILogger<HoneypotLoggingMiddleware> logger, DataAccess dataAccess)
{
_next = next;
_logger = logger;
_dataAccess = dataAccess;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.StartsWithSegments("/collaboration-inquiry"))
{
var ip = context.Connection.RemoteIpAddress?.ToString();
var userAgent = context.Request.Headers["User-Agent"].ToString();
var referrer = context.Request.Headers["Referer"].ToString();
// Optional: Call an external API for country info
string country = "Unknown";
using (var client = new HttpClient())
{
try
{
var response = await client.GetStringAsync($"http://ip-api.com/json/{ip}");
var json = JsonDocument.Parse(response);
country = json.RootElement.GetProperty("country").GetString();
}
catch (Exception ex)
{
// Fail silently
}
}
_logger.LogInformation("HONEYPOT ACCESS: {Time} | IP: {IP} | Country: {Country} | UA: {UA} | Ref: {Ref}",
DateTime.UtcNow, ip, country, userAgent, referrer);
await _dataAccess.Addhoneypot(DateTime.UtcNow, ip, country, userAgent, referrer);
}
await _next(context);
}
}
}

View File

@ -0,0 +1,81 @@
using System.Net;
namespace CatherineLynwood.Middleware
{
public class IpqsBlockMiddleware
{
private readonly RequestDelegate _next;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<IpqsBlockMiddleware> _logger;
private const string ApiKey = "MQUwnYmhKZzHpt6FyxV97EFg8JxlByZt"; // Replace with your IPQS API key
private static readonly string[] ProtectedPaths = new[]
{
"/ask-a-question",
"/contact-catherine"
};
public IpqsBlockMiddleware(RequestDelegate next, IHttpClientFactory httpClientFactory, ILogger<IpqsBlockMiddleware> logger)
{
_next = next;
_httpClientFactory = httpClientFactory;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
var path = context.Request.Path.Value?.ToLower();
if (!ProtectedPaths.Any(p => path.StartsWith(p)))
{
await _next(context);
return;
}
var ip = context.Connection.RemoteIpAddress?.ToString();
//ip = "18.130.131.76";
// skip localhost
if (string.IsNullOrWhiteSpace(ip) || IPAddress.IsLoopback(IPAddress.Parse(ip)))
{
await _next(context);
return;
}
try
{
var client = _httpClientFactory.CreateClient();
var url = $"https://ipqualityscore.com/api/json/ip/{ApiKey}/{ip}?strictness=1&fast=true";
var response = await client.GetFromJsonAsync<IpqsResponse>(url);
if (response != null && (response.is_proxy || response.is_vpn || response.fraud_score >= 85))
{
if (context.Request.Method == HttpMethods.Post)
{
_logger.LogWarning("Blocked VPN/Proxy on POST: IP={IP}", ip);
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync("Access denied.");
return;
}
// Mark for GET requests so the view can show a warning
context.Items["IsVpn"] = true;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "IPQS lookup failed");
}
await _next(context);
}
public class IpqsResponse
{
public bool is_proxy { get; set; }
public bool is_vpn { get; set; }
public int fraud_score { get; set; }
}
}
}

View File

@ -0,0 +1,38 @@
namespace CatherineLynwood.Middleware
{
public class RefererValidationMiddleware
{
private readonly RequestDelegate _next;
// Whitelist of valid referer prefixes
private static readonly string[] AllowedReferers = new[]
{
"https://www.catherinelynwood.com",
"http://localhost",
"https://localhost"
};
public RefererValidationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Method == HttpMethods.Post)
{
var referer = context.Request.Headers["Referer"].ToString();
if (string.IsNullOrEmpty(referer) || !AllowedReferers.Any(r => referer.StartsWith(r, StringComparison.OrdinalIgnoreCase)))
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync("Invalid referer.");
return;
}
}
await _next(context);
}
}
}

View File

@ -25,6 +25,8 @@ namespace CatherineLynwood
// Add IHttpContextAccessor for accessing HTTP context in tag helpers
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient();
// ✅ Add session services (in-memory only)
builder.Services.AddSession(options =>
{
@ -59,7 +61,11 @@ namespace CatherineLynwood
{
options.AllowMinificationInDevelopmentEnvironment = true;
})
.AddHtmlMinification();
.AddHtmlMinification()
.AddHttpCompression()
.AddXmlMinification()
.AddXhtmlMinification();
var app = builder.Build();
@ -70,19 +76,18 @@ namespace CatherineLynwood
app.UseHsts(); // Adds the HSTS (HTTP Strict Transport Security) header
}
app.UseMiddleware<BlockPhpRequestsMiddleware>(); // Add custom middleware
app.UseMiddleware<RedirectToWwwMiddleware>(); // Add custom middleware
app.UseMiddleware<BlockPhpRequestsMiddleware>();
app.UseMiddleware<RedirectToWwwMiddleware>();
app.UseMiddleware<RefererValidationMiddleware>();
app.UseMiddleware<HoneypotLoggingMiddleware>();
app.UseMiddleware<IpqsBlockMiddleware>();
app.UseHttpsRedirection(); // Redirect HTTP requests to HTTPS
app.UseHttpsRedirection();
app.UseResponseCompression();
app.UseStaticFiles();
app.UseRouting();
app.UseWebMarkupMin();
// ✅ Enable session BEFORE authorization
app.UseRouting();
app.UseSession();
app.UseAuthorization();
app.MapControllerRoute(

View File

@ -17,19 +17,9 @@ namespace CatherineLynwood.Services
{
private readonly List<AccessCode> _accessCodes;
public AccessCodeService()
public AccessCodeService(DataAccess dataAccess)
{
_accessCodes = new List<AccessCode>
{
// Book 1 codes
new AccessCode { PageNumber = 168, WordIndex = 3, ExpectedWord = "apple", AccessLevel = 1, BookNumber = 1 },
new AccessCode { PageNumber = 168, WordIndex = 3, ExpectedWord = "forest", AccessLevel = 2, BookNumber = 1 },
new AccessCode { PageNumber = 168, WordIndex = 3, ExpectedWord = "phoenix", AccessLevel = 3, BookNumber = 1 },
// Future: Book 2 codes (example)
new AccessCode { PageNumber = 304, WordIndex = 6, ExpectedWord = "ember", AccessLevel = 2, BookNumber = 2 },
new AccessCode { PageNumber = 304, WordIndex = 6, ExpectedWord = "ashes", AccessLevel = 3, BookNumber = 2 }
};
_accessCodes = dataAccess.GetAccessCodes();
}
public Task<(int pageNumber, int wordIndex)> GetCurrentChallengeAsync()
@ -46,7 +36,7 @@ namespace CatherineLynwood.Services
if (match != null)
return Task.FromResult((match.AccessLevel, match.BookNumber));
return Task.FromResult((0, 0)); // invalid
return Task.FromResult((0, 0));
}
}

View File

@ -1,4 +1,5 @@
using System.Data;
using System.ComponentModel;
using System.Data;
using CatherineLynwood.Models;
@ -21,6 +22,46 @@ namespace CatherineLynwood.Services
_connectionString = connectionString;
}
public List<AccessCode> GetAccessCodes()
{
List<AccessCode> accessCodes = new List<AccessCode>();
using (SqlConnection conn = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetAccessCodes";
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
accessCodes.Add(new AccessCode
{
PageNumber = GetDataInt(rdr, "PageNumber"),
WordIndex = GetDataInt(rdr, "WordIndex"),
ExpectedWord = GetDataString(rdr, "ExpectedWord"),
AccessLevel = GetDataInt(rdr, "AccessLevel"),
BookNumber = GetDataInt(rdr, "BookNumber")
});
}
}
}
catch (Exception ex)
{
}
}
}
return accessCodes;
}
public async Task<Questions> GetQuestionsAsync()
{
Questions questions = new Questions();
@ -309,6 +350,38 @@ namespace CatherineLynwood.Services
return success;
}
public async Task<bool> Addhoneypot(DateTime dateTime, string ip, string country, string userAgent, string referer)
{
bool success = true;
using (SqlConnection conn = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
await conn.OpenAsync();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SaveHoneypot";
cmd.Parameters.AddWithValue("@DateTime", dateTime);
cmd.Parameters.AddWithValue("@IP", ip);
cmd.Parameters.AddWithValue("@Country", country);
cmd.Parameters.AddWithValue("@UserAgent", userAgent);
cmd.Parameters.AddWithValue("@Referer", referer);
await cmd.ExecuteNonQueryAsync();
}
catch (Exception ex)
{
success = false;
}
}
}
return success;
}
public async Task<bool> AddQuestionAsync(Question question)
{
bool visible = false;

View File

@ -32,6 +32,11 @@
<div class="col-12">
<h1>Ask A Question</h1>
</div>
@if (ViewData["VpnWarning"] is true)
{
<partial name="_VPNWarning" />
}
<div class="col-12">
The questions shown below have already been suggested, and are ones I plan to respond to in my upcoming podcast. If you have a question you'd like me
to answer, please use the form below to ask it. Try to make sure no one else has asked it previously.
@ -147,8 +152,16 @@
<!-- Placeholder Button and Submit Button -->
<div class="d-grid">
<button type="button" class="btn btn-secondary mb-3" id="fakeSubmitButton">Ask Question</button>
<button type="submit" class="btn btn-dark mb-3 d-none" id="submitButton">Ask Question</button>
@if (ViewData["VpnWarning"] is true)
{
<button type="button" class="btn btn-secondary mb-3" disabled>Ask Question</button>
}
else
{
<button type="button" class="btn btn-secondary mb-3" id="fakeSubmitButton">Ask Question</button>
<button type="submit" class="btn btn-dark mb-3 d-none" id="submitButton">Ask Question</button>
}
</div>
</form>

View File

@ -26,8 +26,12 @@
<!-- Audio and Text -->
<div class="col-12">
<div class="bg-white rounded-5 border border-3 border-dark shadow-lg p-3">
<responsive-image src="discovery-epilogue.png" class="card-img-top" alt="The Gang Having a Drink at The Barnt Green Inn" display-width-percentage="100"></responsive-image>
<div class="hero-video-container">
<video autoplay muted loop playsinline poster="/images/discovery-epilogue.png">
<source src="/videos/discovery-epilogue.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<!-- Audio Player -->
<div class="audio-player text-center">

View File

@ -90,7 +90,12 @@
<!-- Section 4 -->
<div class="scrapbook-section flex-row-reverse">
<div class="scrapbook-image rotate-4">
<responsive-image src="maggie-in-her-jump-suit.png" class="img-fluid" alt="Maggie in Her Jumpsuit" display-width-percentage="50"></responsive-image>
<div class="hero-video-container">
<video autoplay muted loop playsinline poster="/images/maggie-in-her-jumpsuit.png">
<source src="/videos/maggie-in-her-jumpsuit.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
</div>
<div class="scrapbook-text">
<h5>Maggie in Her Jumpsuit</h5>

View File

@ -23,6 +23,10 @@
<p>I would love to hear your thoughts regarding my work. Please feel free to contact me and I will try my best to reply as soon as I can.</p>
<p>Use the form below to send Catherine a message.</p>
</div>
@if (ViewData["VpnWarning"] is true)
{
<partial name="_VPNWarning" />
}
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="col-12 text-dark">
<div class="form-floating mb-3">
@ -42,7 +46,15 @@
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark btn-block mb-3">Send Message</button>
@if (ViewData["VpnWarning"] is true)
{
<button type="submit" class="btn btn-dark btn-block mb-3" disabled>Send Message</button>
}
else
{
<button type="submit" class="btn btn-dark btn-block mb-3">Send Message</button>
}
</div>
</form>
</div>

View File

@ -0,0 +1,41 @@
@{
ViewData["Title"] = "Collaboration Inquiry";
}
<meta name="robots" content="noindex, nofollow">
<div class="container mt-5">
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card p-4 shadow-sm border-0">
<h2 class="mb-3">Work with Catherine Lynwood</h2>
<p>
Thank you for your interest in collaborating with <strong>Catherine Lynwood Publishing</strong>.
We welcome proposals from literary promoters, content marketers, and industry professionals who share our values
of authenticity, quality storytelling, and long-term reader engagement.
</p>
<p>
Please review our official media pack below for details on Catherine Lynwood, the <em>Alpha Flame</em> trilogy,
available editions, audience reach, and contact information.
</p>
<div class="my-4 text-center">
<a class="btn btn-primary btn-lg" href="/downloads/CatherineLynwood_MediaPack.pdf" target="_blank" rel="noopener">
📄 Download Media Pack (PDF)
</a>
</div>
<p>
If you represent a press or promotional outlet, or are interested in licensing or interview opportunities, please contact us via
<a href="mailto:catherine@catherinelynwood.com">catherine@catherinelynwood.com</a> with a detailed overview of your proposal.
</p>
<hr>
<p class="text-muted small">
Please note: All external submissions are logged and reviewed to ensure authenticity. We take fraudulent or misrepresented approaches seriously and have systems in place to validate all incoming traffic and track abuse.
</p>
</div>
</div>
</div>
</div>

View File

@ -12,31 +12,6 @@
</div>
</div>
<!-- Hero Section -->
@* <div class="row align-items-center mb-5">
<div class="col-md-5 text-center">
<a asp-controller="TheAlphaFlame" asp-action="Discovery">
<responsive-image src="the-alpha-flame-11.png" alt="The Alpha Flame: Discovery" class="img-fluid rounded-5 border border-3 border-dark shadow-lg" display-width-percentage="50"></responsive-image>
</a>
</div>
<div class="col-md-7 pt-2 pt-md-0">
<h1 class="display-5 fw-bold">The Alpha Flame: <span class="fw-light">Discovery</span></h1>
<p class="lead fst-italic">Some girls survive. Others set the world on fire.</p>
<p>
When Maggie Grant finds Beth, bruised, terrified, and alone, she has no idea the rescue will ignite a chain of secrets buried deep in her own past. Set in 1980s Britain, <em>The Alpha Flame: Discovery</em> is a story of sisterhood, survival, and the power of fire to both destroy and redeem.
</p>
<div class="d-flex gap-3 flex-wrap">
<a href="/the-alpha-flame/discovery" class="btn btn-dark">Explore the Book</a>
<a href="/the-alpha-flame/extras" class="btn btn-outline-dark">Unlock Extras</a>
</div>
<p class="mt-4">
<em>The Alpha Flame: Discovery</em>, writen by <a asp-controller="Home" asp-action="AboutCatherineLynwood" class="link-dark fw-semibold">Catherine Lynwood</a>, is the first in a powerful trilogy following the tangled lives of Maggie and Beth , two women bound by fate, fire, and secrets too dangerous to stay buried.
The journey continues in <strong>Reckoning</strong> (Spring 2026) and concludes with <strong>Redemption</strong> (Autumn 2026).
Learn more about the full trilogy on the <a asp-controller="TheAlphaFlame" asp-action="Index" class="link-dark fw-semibold">Alpha Flame series page</a>.
</p>
</div>
</div> *@
<div class="row align-items-center mb-5">
<div class="col-md-5 text-center">
@ -47,10 +22,8 @@
Your browser does not support the video tag.
</video>
<!-- Overlaid Text -->
<div class="hero-overlay-text hero-title">The Alpha Flame</div>
<div class="hero-overlay-text hero-subtitle">Discovery</div>
<div class="hero-overlay-text hero-author">Catherine Lynwood</div>
<!-- New overlay image -->
<responsive-image src="the-alpha-flame-discovery-overlay.png" class="hero-overlay-image" alt="The Alpha Flame: Discovery by Catherine Lynwood" display-width-percentage="50"></responsive-image>
</div>
</a>
</div>

View File

@ -0,0 +1,19 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml"; // If using a shared layout
ViewBag.Title = "Offline Mode";
}
<div class="container text-center py-5">
<h1 class="display-4 text-primary mb-4">You're offline</h1>
<p class="lead mb-4">
It looks like your internet connection is currently unavailable. But don't worry — you're not alone in the dark.
</p>
<img src="/images/logo-512.png" alt="Catherine Lynwood" width="128" height="128" class="mb-4" />
<p class="mb-4">
You can still access some features you've already visited, or come back when you're back online.
</p>
<a href="/" class="btn btn-primary btn-lg">Return Home</a>
</div>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en-GB">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@ -53,18 +53,23 @@
</head>
<body class="bg-primary text-white">
<div id="background-wrapper">
<!-- Fallback image shown by default -->
<div class="fixed-background"></div>
<div class="video-background">
<video autoplay muted loop playsinline poster="/images/webp/maggie-5-1920.webp">
<source src="/videos/background-3.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<div class="video-overlay"></div>
</div>
</div>
<div class="content">
<!-- Content wrapper to keep everything on top of the background -->
<header>
<nav class="navbar fixed-top navbar-expand-sm navbar-toggleable-sm navbar-dark border-bottom border-2 border-primary box-shadow mb-3 bg-dark">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Catherine Lynwood</a>
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">
<img src="~/images/catherine-lynwood-banner-logo-small.png" alt="Catherine Lynwood Logo Banner" class="img-fluid" style="height: 50px;" />
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
@ -98,7 +103,7 @@
</div>
</nav>
</header>
<div class="container-lg" style="margin-top: 70px;">
<div class="container-lg" style="margin-top: 90px;">
<main role="main" class="pb-3">
@RenderBody()
</main>
@ -111,14 +116,25 @@
<div class="row justify-content-center align-items-center" >
<div class="col-md-4 text-center order-md-2">
<social-media-share title="Catherine Lynwood Blog" url="@Context.Request.Path" class="text-center m-3"></social-media-share>
&copy; 2024 - Catherine Lynwood
&copy; 2024 - @DateTime.Now.Year - Catherine Lynwood
</div>
<div class="col-md-4 text-center order-md-1">
<a class="text-light" asp-area="" asp-controller="Home" asp-action="ContactCatherine">Contact Catherine</a>
<p>
<a class="text-light" asp-area="" asp-controller="Home" asp-action="ContactCatherine">Contact Catherine</a>
</p>
<p>
<a class="text-light" asp-area="" asp-controller="Publishing" asp-action="Index">Catherine Lynwood Publishing</a>
</p>
</div>
<div class="col-md-4 text-center order-md-3">
<a class="text-light" asp-area="" asp-controller="Publishing" asp-action="Index">Catherine Lynwood Publishing</a>
<p>
<a class="text-light" asp-area="" asp-controller="Home" asp-action="AboutCatherineLynwood">About Catherine Lynwood</a>
</p>
<p>
<a class="text-light" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy Policy</a>
</p>
</div>
</div>
@ -130,29 +146,7 @@
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script>
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
const allowVideo = !connection || (
!connection.saveData &&
!connection.effectiveType.includes("2g") &&
!connection.effectiveType.includes("3g")
);
if (allowVideo) {
const wrapper = document.getElementById("background-wrapper");
wrapper.innerHTML = `
<div class="video-background">
<video autoplay muted loop playsinline poster="/images/webp/maggie-5-1920.webp">
<source src="/videos/background-3.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<div class="video-overlay"></div>
</div>
`;
}
</script>
<script src="https://cdn.plyr.io/3.7.2/plyr.polyfilled.js"></script>
@ -160,7 +154,20 @@
const player = new Plyr('audio');
</script>
@RenderSection("Scripts", required: false)
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/service-worker.js')
.then(function (registration) {
console.log('ServiceWorker registered with scope:', registration.scope);
}, function (err) {
console.log('ServiceWorker registration failed:', err);
});
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,5 @@
<div class="col-12">
<div class="alert alert-warning">
We've noticed you're using a VPN or proxy. To help prevent spam and abuse, weve restricted form submissions from these types of connections. If you're a real visitor and need to get in touch, please try again from a standard connection. We really appreciate your understanding.
</div>
</div>

View File

@ -9,7 +9,7 @@
<li class="breadcrumb-item"><a asp-controller="Home" asp-action="Index">Home</a></li>
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="Index">The Alpha Flame</a></li>
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="DIscovery">Discovery</a></li>
<li class="breadcrumb-item active" aria-current="page">Chapter 1 Excerpt</li>
<li class="breadcrumb-item active" aria-current="page">Chapter 1 - Drowning in Silence</li>
</ol>
</nav>
</div>
@ -17,11 +17,8 @@
<!-- Header -->
<div class="text-center mb-5">
<h1 class="fw-bold">The Alpha Flame - Chapter 1 Excerpt</h1>
<h1 class="fw-bold">Chapter 1 - Drowning in Silence - Beth</h1>
<p>An exclusive glimpse into Beth's story</p>
<p>
An excerpt from Chapter 1 of The Alpha Flame, titled "Drowning in Silence - Beth."
</p>
</div>
<!-- Excerpt Content -->
@ -39,7 +36,11 @@
<video controls="controls" poster="/images/Chapter-1.png" class="rounded-5">
<source src="~/videos/Chapter-1-preview.mp4" type="video/mp4"/>
</video>
</div>
<p class="text-center text-muted small pt-2">
Watch Beth narrating part of Chapter 1 - Drowning in Silence.
</p>
<!-- Audio Player -->
<div class="audio-player text-center">
<audio controls>
@ -47,7 +48,7 @@
Your browser does not support the audio element.
</audio>
<p class="text-center text-muted small">
Listen to Beth narrating chapter 1 - Drowning in Silence.
Listen to Beth narrating the complete Chapter 1 - Drowning in Silence.
</p>
</div>
<!-- Text Content -->
@ -77,10 +78,6 @@
</div>
@section Meta {
<meta name="description" content="Dive into Chapter 1 of 'The Alpha Flame' by Catherine Lynwood. Follow Beth's journey in a gripping tale of mystery, family, and resilience set in the 1980s." />
<meta name="keywords" content="The Alpha Flame, Chapter 1, Beth, Catherine Lynwood, mystery novel, 1980s fiction, family drama, book chapters, gripping novels, fiction by Catherine Lynwood" />
<meta name="author" content="Catherine Lynwood" />
<MetaTag meta-title="Chapter 1: Beth - The Alpha Flame by Catherine Lynwood"
meta-description="Explore Chapter 1 of 'The Alpha Flame' by Catherine Lynwood. Discover Maggie's captivating story, full of determination and secrets, set in the vivid 1980s."
meta-keywords="The Alpha Flame, Chapter 1, Maggie, Catherine Lynwood, 1980s fiction, family secrets, strong female characters, captivating novels, fiction by Catherine Lynwood"

View File

@ -0,0 +1,165 @@
@{
ViewData["Title"] = "The Alpha Flame | Chapter 2 Excerpt";
}
<div class="row">
<div class="col-12">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a asp-controller="Home" asp-action="Index">Home</a></li>
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="Index">The Alpha Flame</a></li>
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="DIscovery">Discovery</a></li>
<li class="breadcrumb-item active" aria-current="page">Chapter 13 - A Name She Never Owned</li>
</ol>
</nav>
</div>
</div>
<!-- Header -->
<div class="text-center mb-5">
<h1 class="fw-bold">Chapter 13 - A Name She Never Owned - Susie</h1>
<p>An exclusive glimpse into Susie's story</p>
</div>
<!-- Excerpt Content -->
<div class="row gx-5">
<!-- Scene Image -->
<div class="col-lg-5 mb-4 mb-lg-0">
<responsive-image src="pub-from-chapter-13.png" alt="The Pub from Chapter 13" class="img-fluid rounded-5 border border-3 border-dark shadow-lg" display-width-percentage="50"></responsive-image>
</div>
<!-- Audio and Text -->
<div class="col-lg-7">
<div class="bg-white rounded-5 border border-3 border-dark shadow-lg p-3">
<!-- Audio Player -->
<div class="audio-player text-center">
<audio controls>
<source src="/audio/the-alpha-flame-discovery-chapter-13.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<p class="text-center text-muted small">
Listen to Susie narrating a large excerpt from Chapter 13 - A Name She Never Owned
</p>
</div>
<!-- Text Content -->
<div class="chapter-text">
<p class="chapter-title">A Name She Never Owned - Susie</p>
<p><em>I wasnt sure this was a good idea. Not the date itself, hell, I deserved a decent night out for once, but who I was going with. I mean hes a punter for Gods sake. That said, guys arent exactly queueing up to take me out, and he certainly seemed quite harmless, although perhaps a little needy. I didnt feel threatened by him at all, and Id definitely learned how to defend myself over the past three years, so I had no worries there.</em></p>
<p><em>My biggest problem was my wardrobe, if you can call it that. It wasnt exactly huge, so I didnt have many clothes to choose from. Having spent half my time in short skirts and stockings in the past three years, I decided to go for jeans and a pretty top. I had the nice one that Maggie gave me back at the beginning of the year that I hadnt worn that much, and over the top I decided to wear my leather jacket. Yeah, that would do just perfect.</em></p>
<p><em>I looked at my watch. Nearly eight. I grabbed my handbag and pulled the door shut behind me, heading downstairs and out of the block. Opening the door to the street, the cold hit me like a smack in the face. Good job I wasnt working tonight; Id have frozen my tits off, I thought.</em></p>
<p><em>As I crossed the road, I saw Bens car waiting in the layby. He waved as I approached. I opened the door and got in.</em></p>
<p>“Hi,” he said, smiling nervously. “I wondered if youd remember.”</p>
<p>“Of course,” I replied, returning his smile.</p>
<p><em>He leant over, I thought he was going to try and kiss me, and for a split second I panicked, reaching for the door handle, but instead he reached behind the seat, picking something up. He brought his hand around in front of me, presenting the most amazing bunch of red roses I had ever seen.</em></p>
<p>“These are for you.”</p>
<p>“Wow! Thank you,” I said, genuinely blown away. “Thats so nice of you. No ones ever bought me flowers before.”</p>
<p><em>Bens smile deepened. “Are you ready?”</em></p>
<p>“Sure.”</p>
<p><em>He started the car and pulled away, driving slowly, a little nervously.</em></p>
<p>“Have you been driving long?” I asked after a few moments.</p>
<p><em>Ben glanced across. “About a year. Am I that bad?”</em></p>
<p><em>I laughed softly. “No, not at all. Its just that most guys seem to drive a lot faster.”</em></p>
<p>“I dont really like driving that much. It makes me a little nervous, but I have to do it… otherwise I would never get out of the house.”</p>
<p>“Do you live on your own?”</p>
<p>“Yes.” His expression darkened slightly. “My parents died last year… in a car crash. Thats why Im nervous. I only drive because I have to.”</p>
<p><em>I reached over and rested my hand on his knee for a second, trying to offer some comfort. Ben gave my hand a gentle squeeze in acknowledgment.</em></p>
<p>“Listen,” he said, glancing at me again. “I dont want this to be weird. So as far as Im concerned, yesterday didnt happen. Were just on a date because… well, I like you. I think youre gorgeous.”</p>
<p>“Thank you,” I said, feeling a blush creep up my cheeks.</p>
<p>“And Im not expecting anything either,” he added quickly, looking flustered. “Sex wise, I mean. This is just two people going out for a drink. What either of us does for a living doesnt matter. Okay?”</p>
<p><em>I smiled, warmed by his awkward honesty. “Suits me.”</em></p>
<p><em>We drove for about fifteen minutes, down a few country lanes and up a steep hill, until we came to a lovely country pub nestled into the hillside. Ben pulled into the car park and switched off the engine.</em></p>
<p>“This looks nice. Have you been here before?” I asked.</p>
<p>“No, never. A friend told me about it when I asked him where we could go.”</p>
<p><em>Shocked, I stared at him. “You told your mate youre going on a date with me?”</em></p>
<p>“Yeah. Whats wrong with that?”</p>
<p>“Did you tell him Im a prostitute?”</p>
<p><em>Ben gave a half-smile. “I thought we agreed what each of us does doesnt matter?”</em></p>
<p>“It doesnt.”</p>
<p>“Exactly. But if you must know, I just told him I had a date with a beautiful girl. Thats all.”</p>
<p>“So, youre embarrassed to be seen with me?”</p>
<p><em>Ben looked flustered. “No, not at all. If I was, I wouldnt have asked you out. Ill shout it from the top of that hill over there if you like, but it wont change the way I feel.”</em></p>
<p><em>I was quite touched.</em></p>
<p><em>We got out of the car and Ben locked the doors. The car park was surrounded by a low stone wall. Ben led the way over to some steps that wound up to the pub entrance above. When we reached the door, he held it open for me.</em></p>
<p><em>The pub was lovely. Very old-fashioned, with a big solid oak bar, a few assorted tables, and a mixture of traditional chairs and cosy lounge sofas scattered around. The scent of woodsmoke filled the air.</em></p>
<p>“Do you want to go and sit down, and Ill get the drinks?” Ben asked, glancing at the bar.</p>
<p>“Yeah, okay. Can I have a vodka and Coke, please?”</p>
<p><em>I headed towards a sumptuous-looking sofa in the corner by the open fire and slumped down. It was beautifully soft, and for the first time in ages I started to relax. A thought flashed through my mind… maybe I should have dressed up more. Ben seemed nice. I felt a little underdressed now. Maybe next time, I thought.</em></p>
<p><em>It wasnt long before Ben returned with the drinks. He placed mine carefully in front of me.</em></p>
</div>
</div>
</div>
</div>
@section Meta {
<MetaTag meta-title="Chapter 2: Maggie - The Alpha Flame by Catherine Lynwood"
meta-description="Explore Chapter 13 of 'The Alpha Flame' by Catherine Lynwood. Discover Susie's captivating story, full of determination and secrets, set in the vivid 1980s."
meta-keywords="The Alpha Flame, Chapter 13, Susie, Catherine Lynwood, 1980s fiction, family secrets, strong female characters, captivating novels, fiction by Catherine Lynwood"
meta-author="Catherine Lynwood"
meta-url="https://www.catherinelynwood.com/the-alpha-flame/chapters/chapter-2-maggie"
meta-image="https://www.catherinelynwood.com/images/webp/maggie-grant-43-600.webp"
meta-image-alt="Maggie from 'The Alpha Flame' by Catherine Lynwood"
og-site-name="Catherine Lynwood - The Alpha Flame"
article-published-time="@new DateTime(2024, 11, 20)"
article-modified-time="@new DateTime(2024, 11, 20)"
twitter-card-type="player"
twitter-site-handle="@@CathLynwood"
twitter-creator-handle="@@CathLynwood"
twitter-player-width="480"
twitter-player-height="80" />
<script type="application/ld+json">
{
"@@context": "https://schema.org",
"@@type": "Chapter",
"name": "Chapter 13: A Name She Never Owned - Susie",
"url": "https://www.catherinelynwood.com/the-alpha-flame/chapters/chapter-2-maggie",
"description": "Maggie Grant bursts onto the page with wit, confidence, and a fiery spirit. As she faces challenges at college and flirts with independence, her strength and secrets begin to unfold.",
"position": 13,
"inLanguage": "en-GB",
"isPartOf": {
"@@type": "Book",
"name": "The Alpha Flame: Discovery",
"author": {
"@@type": "Person",
"name": "Catherine Lynwood",
"url": "https://www.catherinelynwood.com"
},
"publisher": {
"@@type": "Organization",
"name": "Catherine Lynwood"
},
"inLanguage": "en-GB",
"workExample": [
{
"@@type": "Book",
"bookFormat": "https://schema.org/Hardcover",
"isbn": "978-1-0682258-0-2",
"name": "The Alpha Flame: Discovery Hardback"
},
{
"@@type": "Book",
"bookFormat": "https://schema.org/Paperback",
"isbn": "978-1-0682258-1-9",
"name": "The Alpha Flame: Discovery Softback"
},
{
"@@type": "Book",
"bookFormat": "https://schema.org/Paperback",
"isbn": "978-1-0682258-2-6",
"name": "The Alpha Flame: Discovery Amazon Edition"
},
{
"@@type": "Book",
"bookFormat": "https://schema.org/EBook",
"isbn": "978-1-0682258-3-3",
"name": "The Alpha Flame: Discovery eBook"
}
]
}
}
</script>
}

View File

@ -9,7 +9,7 @@
<li class="breadcrumb-item"><a asp-controller="Home" asp-action="Index">Home</a></li>
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="Index">The Alpha Flame</a></li>
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="DIscovery">Discovery</a></li>
<li class="breadcrumb-item active" aria-current="page">Chapter 2 Excerpt</li>
<li class="breadcrumb-item active" aria-current="page">Chapter 2 - The Last Lesson</li>
</ol>
</nav>
</div>
@ -17,18 +17,15 @@
<!-- Header -->
<div class="text-center mb-5">
<h1 class="fw-bold">The Alpha Flame - Chapter 2 Excerpt</h1>
<h1 class="fw-bold">Chapter 2- The Last Lesson - Maggie</h1>
<p>An exclusive glimpse into Maggie's story</p>
<p>
An excerpt from Chapter 2 of The Alpha Flame, titled "The Last Lesson - Maggie."
</p>
</div>
<!-- Excerpt Content -->
<div class="row gx-5">
<!-- Scene Image -->
<div class="col-lg-5 mb-4 mb-lg-0">
<responsive-image src="maggie-grant-43.png" alt="Scene from Maggie's story" class="img-fluid rounded-5 border border-3 border-dark shadow-lg" display-width-percentage="50"></responsive-image>
<responsive-image src="maggie-with-her-tr6-2.png" alt="Maggie With Her TR6" class="img-fluid rounded-5 border border-3 border-dark shadow-lg" display-width-percentage="50"></responsive-image>
</div>
@ -42,7 +39,7 @@
Your browser does not support the audio element.
</audio>
<p class="text-center text-muted small">
Listen to Maggie narrating Chapter 2 - The Last Lesson,
Listen to Maggie narrating the complete Chapter 2 - The Last Lesson,
</p>
</div>
@ -80,10 +77,6 @@
</div>
@section Meta {
<meta name="description" content="Explore Chapter 2 of 'The Alpha Flame' by Catherine Lynwood. Discover Maggie's captivating story, full of determination and secrets, set in the vivid 1980s." />
<meta name="keywords" content="The Alpha Flame, Chapter 2, Maggie, Catherine Lynwood, 1980s fiction, family secrets, strong female characters, captivating novels, fiction by Catherine Lynwood" />
<meta name="author" content="Catherine Lynwood" />
<MetaTag meta-title="Chapter 2: Maggie - The Alpha Flame by Catherine Lynwood"
meta-description="Explore Chapter 2 of 'The Alpha Flame' by Catherine Lynwood. Discover Maggie's captivating story, full of determination and secrets, set in the vivid 1980s."
meta-keywords="The Alpha Flame, Chapter 2, Maggie, Catherine Lynwood, 1980s fiction, family secrets, strong female characters, captivating novels, fiction by Catherine Lynwood"

View File

@ -113,16 +113,13 @@
</div>
<div class="col-md-4 mb-4">
<div class="card h-100 character-card">
<a asp-action="Characters">
<responsive-image src="discovery-epilogue.png" class="fit-image" alt="Maggie Grant, The Alpha Flame" display-width-percentage="50"></responsive-image>
<a asp-action="Chapter13">
<responsive-image src="pub-from-chapter-13.png" class="fit-image" alt="Pub from Chapter 13" display-width-percentage="50"></responsive-image>
</a>
<div class="card-body border-top border-3 border-dark">
<h3 class="card-title">Meet the Characters</h3>
<p class="card-text">Dive into the vibrant world of The Alpha Flame and discover the unforgettable cast of characters that bring this story to life.</p>
<p class="card-text">Get to know Maggie, the fiery and magnetic heart of the tale, and Beth, whose troubled past contrasts with her unyielding strength. Meet Rosie, Maggie's best friend, who brings warmth and humor to every scene, and Rebecca, a steady presence with a hidden depth.</p>
<p class="card-text">Explore the mind of Rob, the gadget-obsessed photographer whose quiet determination matches his deep connection to Maggie. Then theres Zoe, the sharp-witted ex-policewoman whos full of surprises.</p>
<div class="text-end"><a asp-action="Characters" class="btn btn-dark">Read More</a></div>
<h3 class="card-title">Chapter 13: A Name She Never Owned - Susie</h3>
<p class="card-text">Susie goes out for a drink with a punter. What on earth could go wrong...</p>
<div class="text-end"><a asp-action="Chapter13" class="btn btn-dark">Read More</a></div>
</div>
</div>
</div>
@ -177,6 +174,21 @@
@section Meta{
<MetaTag meta-title="The Alpha Flame: Discovery by Catherine Lynwood"
meta-description="Start the journey with 'The Alpha Flame: Discovery' the gripping first novel in Catherine Lynwoods trilogy set in 1983 Birmingham. Family secrets, resilience, and a powerful bond between sisters await."
meta-keywords="The Alpha Flame Discovery, Catherine Lynwood, 1983 novel, twin sisters, suspense fiction, Rubery, Birmingham fiction, historical drama, family secrets"
meta-author="Catherine Lynwood"
meta-url="https://www.catherinelynwood.com/the-alpha-flame/discovery"
meta-image="https://www.catherinelynwood.com/images/webp/the-alpha-flame-11-600.webp"
meta-image-alt="Maggie from 'The Alpha Flame: Discovery' by Catherine Lynwood"
og-site-name="Catherine Lynwood - The Alpha Flame: Discovery"
article-published-time="@new DateTime(2024, 11, 20)"
article-modified-time="@new DateTime(2025, 06, 07)"
twitter-card-type="summary_large_image"
twitter-site-handle="@@CathLynwood"
twitter-creator-handle="@@CathLynwood" />
<script type="application/ld+json">
{
"@@context": "https://schema.org",

View File

@ -65,6 +65,36 @@
</div>
</div>
<div class="row mb-4">
<div class="col-12">
<div class="card h-100 shadow-sm border-start border-3 border-dark position-relative">
<div class="row g-0">
<a asp-action="Characters">
</a>
<div class="col-md-8 d-none d-md-block">
<a asp-action="Characters">
<responsive-image src="discovery-epilogue.png" class="img-fluid rounded-start-3" alt="Meet The Characters" display-width-percentage="50"></responsive-image>
</a>
</div>
<div class="col-md-8 d-md-none">
<a asp-action="Characters">
<responsive-image src="discovery-epilogue.png" class="img-fluid rounded-top-3" alt="Meet The Characters" display-width-percentage="50"></responsive-image>
</a>
</div>
<div class="col-md-4">
<div class="card-body">
<h5 class="card-title">Meet the Characters</h5>
<p class="card-text">Dive into the vibrant world of The Alpha Flame and discover the unforgettable cast of characters that bring this story to life.</p>
<p class="card-text">Get to know Maggie, the fiery and magnetic heart of the tale, and Beth, whose troubled past contrasts with her unyielding strength. Meet Rosie, Maggie's best friend, who brings warmth and humor to every scene, and Rebecca, a steady presence with a hidden depth.</p>
<div class="text-end"><a asp-action="Characters" class="btn btn-dark">Read More</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-12">
<div class="card h-100 shadow-sm border-start border-3 border-dark position-relative">
@ -130,6 +160,20 @@
</div>
@section Meta {
<MetaTag meta-title="The Alpha Flame Trilogy by Catherine Lynwood"
meta-description="Discover 'The Alpha Flame' trilogy by Catherine Lynwood. A powerful 1980s-set story of identity, resilience, and family secrets across three gripping novels."
meta-keywords="The Alpha Flame trilogy, Catherine Lynwood, 1980s fiction, family saga, twin sisters, Birmingham novel, suspense fiction, indie fiction series"
meta-author="Catherine Lynwood"
meta-url="https://www.catherinelynwood.com/the-alpha-flame"
meta-image="https://www.catherinelynwood.com/images/webp/the-alpha-flame-trilogy-banner.webp"
meta-image-alt="The Alpha Flame trilogy banner image showing three covers of the series by Catherine Lynwood"
og-site-name="Catherine Lynwood - The Alpha Flame Trilogy"
article-published-time="@new DateTime(2024, 11, 20)"
article-modified-time="@new DateTime(2025, 06, 07)"
twitter-card-type="summary_large_image"
twitter-site-handle="@@CathLynwood"
twitter-creator-handle="@@CathLynwood" />
<style>
.placeholder-blur {
filter: blur(4px);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#17C8EB</TileColor></tile></msapplication></browserconfig>
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>

View File

@ -14,7 +14,7 @@ html {
}
.content {
min-height: 95vh;
min-height: 93vh;
}
/* Default background for larger screens (Extra large and up) */
@ -24,7 +24,7 @@ html {
left: 0;
width: 100vw;
height: 100vh;
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/maggie-5-1920.webp'); /* Path to the largest image */
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/the-alpha-flame-discovery-blank-1920.webp'); /* Path to the largest image */
background-size: cover;
background-repeat: no-repeat;
background-position: top;
@ -34,7 +34,7 @@ html {
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575.98px) {
.fixed-background {
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/maggie-5-400.webp'); /* Path to smallest image */
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/the-alpha-flame-discovery-blank-400.webp'); /* Path to smallest image */
background-size: cover;
background-repeat: no-repeat;
background-position: top;
@ -44,7 +44,7 @@ html {
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767.98px) {
.fixed-background {
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/maggie-5-768.webp'); /* Path to small image */
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/the-alpha-flame-discovery-blank-768.webp'); /* Path to small image */
background-size: cover;
background-repeat: no-repeat;
background-position: top;
@ -54,7 +54,7 @@ html {
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991.98px) {
.fixed-background {
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/maggie-5-992.webp'); /* Path to medium image */
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/the-alpha-flame-discovery-blank-992.webp'); /* Path to medium image */
background-size: cover;
background-repeat: no-repeat;
background-position: top;
@ -64,7 +64,7 @@ html {
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199.98px) {
.fixed-background {
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/maggie-5-1200.webp'); /* Path to large image */
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/the-alpha-flame-discovery-blank-1200.webp'); /* Path to large image */
background-size: cover;
background-repeat: no-repeat;
background-position: top;
@ -74,7 +74,7 @@ html {
/* Extra large devices (larger desktops, 1200px and up) */
@media (min-width: 1200px) {
.fixed-background {
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/maggie-5-1920.webp'); /* Path to extra-large image */
background: linear-gradient(rgba(23, 200, 235, 0.5), rgba(23, 200, 235, 0.5)), url('/images/webp/the-alpha-flame-discovery-blank-1920.webp'); /* Path to extra-large image */
background-size: cover;
background-repeat: no-repeat;
background-position: top;

View File

@ -1 +1 @@
html{font-size:14px}@media(min-width:768px){html{font-size:16px}}html{position:relative}.content{min-height:95vh}.fixed-background{position:fixed;top:0;left:0;width:100vw;height:100vh;background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/maggie-5-1920.webp');background-size:cover;background-repeat:no-repeat;background-position:top;z-index:-1}@media(max-width:575.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/maggie-5-400.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:576px) and (max-width:767.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/maggie-5-768.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:768px) and (max-width:991.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/maggie-5-992.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:992px) and (max-width:1199.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/maggie-5-1200.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:1200px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/maggie-5-1920.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}.content{position:relative;z-index:1}section{padding-bottom:10px}.w-sm-50{width:100%}@media(min-width:576px){.w-sm-50{width:50%}}.w-md-50{width:100%}@media(min-width:768px){.w-md-50{width:50%}}.excerpt-section{background-color:#f8f9fa}.scene-image{max-width:100%;height:auto;border-radius:10px}.audio-player{margin:1rem 0}.chapter-text{font-family:'Georgia',serif;font-size:1.1rem;line-height:1.6;color:#333}.chapter-title{font-size:1.5rem;font-weight:bold;color:#555;margin-bottom:1rem}.responsive-border{border-right:3px solid #000}@media(max-width:575.98px){.responsive-border{border-right:0;border-bottom:3px solid #000}}.fit-image{width:100%;height:100%;object-fit:cover;object-position:center;display:block}.share-button{padding:8px 12px;margin-left:10px;margin-right:10px;color:#fff;text-decoration:none;border-radius:4px;font-size:14px}.share-button.facebook{background-color:#3b5998}.share-button.twitter{background-color:#1da1f2}.share-button.linkedin{background-color:#0077b5}.share-button.pinterest{background-color:#bd081c}.share-button.instagram{background-color:#e4405f}.share-button.tiktok{background-color:#010101}#synopsis-body{overflow-y:auto}
html{font-size:14px}@media(min-width:768px){html{font-size:16px}}html{position:relative}.content{min-height:93vh}.fixed-background{position:fixed;top:0;left:0;width:100vw;height:100vh;background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/the-alpha-flame-discovery-blank-1920.webp');background-size:cover;background-repeat:no-repeat;background-position:top;z-index:-1}@media(max-width:575.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/the-alpha-flame-discovery-blank-400.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:576px) and (max-width:767.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/the-alpha-flame-discovery-blank-768.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:768px) and (max-width:991.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/the-alpha-flame-discovery-blank-992.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:992px) and (max-width:1199.98px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/the-alpha-flame-discovery-blank-1200.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}@media(min-width:1200px){.fixed-background{background:linear-gradient(rgba(23,200,235,.5),rgba(23,200,235,.5)),url('/images/webp/the-alpha-flame-discovery-blank-1920.webp');background-size:cover;background-repeat:no-repeat;background-position:top}}.content{position:relative;z-index:1}section{padding-bottom:10px}.w-sm-50{width:100%}@media(min-width:576px){.w-sm-50{width:50%}}.w-md-50{width:100%}@media(min-width:768px){.w-md-50{width:50%}}.excerpt-section{background-color:#f8f9fa}.scene-image{max-width:100%;height:auto;border-radius:10px}.audio-player{margin:1rem 0}.chapter-text{font-family:'Georgia',serif;font-size:1.1rem;line-height:1.6;color:#333}.chapter-title{font-size:1.5rem;font-weight:bold;color:#555;margin-bottom:1rem}.responsive-border{border-right:3px solid #000}@media(max-width:575.98px){.responsive-border{border-right:0;border-bottom:3px solid #000}}.fit-image{width:100%;height:100%;object-fit:cover;object-position:center;display:block}.share-button{padding:8px 12px;margin-left:10px;margin-right:10px;color:#fff;text-decoration:none;border-radius:4px;font-size:14px}.share-button.facebook{background-color:#3b5998}.share-button.twitter{background-color:#1da1f2}.share-button.linkedin{background-color:#0077b5}.share-button.pinterest{background-color:#bd081c}.share-button.instagram{background-color:#e4405f}.share-button.tiktok{background-color:#010101}#synopsis-body{overflow-y:auto}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 928 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 KiB

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 611 KiB

After

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Some files were not shown because too many files have changed in this diff Show More