Save
@ -21,6 +21,8 @@ namespace CatherineLynwood.Controllers
|
|||||||
|
|
||||||
public async Task<IActionResult> Index(bool showThanks)
|
public async Task<IActionResult> Index(bool showThanks)
|
||||||
{
|
{
|
||||||
|
ViewData["VpnWarning"] = HttpContext.Items.ContainsKey("IsVpn") && (bool)HttpContext.Items["IsVpn"];
|
||||||
|
|
||||||
Questions questions = await _dataAccess.GetQuestionsAsync();
|
Questions questions = await _dataAccess.GetQuestionsAsync();
|
||||||
questions.ShowThanks = showThanks;
|
questions.ShowThanks = showThanks;
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,12 @@ namespace CatherineLynwood.Controllers
|
|||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
|
[Route("collaboration-inquiry")]
|
||||||
|
public IActionResult Honeypot()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
[Route("about-catherine-lynwood")]
|
[Route("about-catherine-lynwood")]
|
||||||
public IActionResult AboutCatherineLynwood()
|
public IActionResult AboutCatherineLynwood()
|
||||||
{
|
{
|
||||||
@ -43,6 +49,8 @@ namespace CatherineLynwood.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> ContactCatherine()
|
public async Task<IActionResult> ContactCatherine()
|
||||||
{
|
{
|
||||||
|
ViewData["VpnWarning"] = HttpContext.Items.ContainsKey("IsVpn") && (bool)HttpContext.Items["IsVpn"];
|
||||||
|
|
||||||
Contact contact = new Contact();
|
Contact contact = new Contact();
|
||||||
|
|
||||||
return View(contact);
|
return View(contact);
|
||||||
@ -155,6 +163,12 @@ namespace CatherineLynwood.Controllers
|
|||||||
return View();
|
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
|
// Helper method to convert the original image URL to a 400px JPEG URL in the "jpg" folder
|
||||||
private string ConvertToJpgUrl(string originalFileName)
|
private string ConvertToJpgUrl(string originalFileName)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -105,6 +105,11 @@ namespace CatherineLynwood.Controllers
|
|||||||
{
|
{
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
[Route("chapters/chapter-13-susie")]
|
||||||
|
public IActionResult Chapter13()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
[Route("characters")]
|
[Route("characters")]
|
||||||
public IActionResult Characters()
|
public IActionResult Characters()
|
||||||
|
|||||||
56
CatherineLynwood/Middleware/HoneypotLoggingMiddleware.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
81
CatherineLynwood/Middleware/IpqsBlockMiddleware.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
38
CatherineLynwood/Middleware/RefererValidationMiddleware.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -25,6 +25,8 @@ namespace CatherineLynwood
|
|||||||
// Add IHttpContextAccessor for accessing HTTP context in tag helpers
|
// Add IHttpContextAccessor for accessing HTTP context in tag helpers
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
|
|
||||||
// ✅ Add session services (in-memory only)
|
// ✅ Add session services (in-memory only)
|
||||||
builder.Services.AddSession(options =>
|
builder.Services.AddSession(options =>
|
||||||
{
|
{
|
||||||
@ -59,7 +61,11 @@ namespace CatherineLynwood
|
|||||||
{
|
{
|
||||||
options.AllowMinificationInDevelopmentEnvironment = true;
|
options.AllowMinificationInDevelopmentEnvironment = true;
|
||||||
})
|
})
|
||||||
.AddHtmlMinification();
|
.AddHtmlMinification()
|
||||||
|
.AddHttpCompression()
|
||||||
|
.AddXmlMinification()
|
||||||
|
.AddXhtmlMinification();
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
@ -70,19 +76,18 @@ namespace CatherineLynwood
|
|||||||
app.UseHsts(); // Adds the HSTS (HTTP Strict Transport Security) header
|
app.UseHsts(); // Adds the HSTS (HTTP Strict Transport Security) header
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseMiddleware<BlockPhpRequestsMiddleware>(); // Add custom middleware
|
app.UseMiddleware<BlockPhpRequestsMiddleware>();
|
||||||
app.UseMiddleware<RedirectToWwwMiddleware>(); // Add custom middleware
|
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.UseStaticFiles();
|
||||||
|
|
||||||
app.UseRouting();
|
|
||||||
|
|
||||||
app.UseWebMarkupMin();
|
app.UseWebMarkupMin();
|
||||||
|
app.UseRouting();
|
||||||
// ✅ Enable session BEFORE authorization
|
|
||||||
app.UseSession();
|
app.UseSession();
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.MapControllerRoute(
|
app.MapControllerRoute(
|
||||||
|
|||||||
@ -17,19 +17,9 @@ namespace CatherineLynwood.Services
|
|||||||
{
|
{
|
||||||
private readonly List<AccessCode> _accessCodes;
|
private readonly List<AccessCode> _accessCodes;
|
||||||
|
|
||||||
public AccessCodeService()
|
public AccessCodeService(DataAccess dataAccess)
|
||||||
{
|
{
|
||||||
_accessCodes = new List<AccessCode>
|
_accessCodes = dataAccess.GetAccessCodes();
|
||||||
{
|
|
||||||
// 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 }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<(int pageNumber, int wordIndex)> GetCurrentChallengeAsync()
|
public Task<(int pageNumber, int wordIndex)> GetCurrentChallengeAsync()
|
||||||
@ -46,7 +36,7 @@ namespace CatherineLynwood.Services
|
|||||||
if (match != null)
|
if (match != null)
|
||||||
return Task.FromResult((match.AccessLevel, match.BookNumber));
|
return Task.FromResult((match.AccessLevel, match.BookNumber));
|
||||||
|
|
||||||
return Task.FromResult((0, 0)); // invalid
|
return Task.FromResult((0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Data;
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
using CatherineLynwood.Models;
|
using CatherineLynwood.Models;
|
||||||
|
|
||||||
@ -21,6 +22,46 @@ namespace CatherineLynwood.Services
|
|||||||
_connectionString = connectionString;
|
_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()
|
public async Task<Questions> GetQuestionsAsync()
|
||||||
{
|
{
|
||||||
Questions questions = new Questions();
|
Questions questions = new Questions();
|
||||||
@ -309,6 +350,38 @@ namespace CatherineLynwood.Services
|
|||||||
return success;
|
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)
|
public async Task<bool> AddQuestionAsync(Question question)
|
||||||
{
|
{
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
|
|||||||
@ -32,6 +32,11 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h1>Ask A Question</h1>
|
<h1>Ask A Question</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@if (ViewData["VpnWarning"] is true)
|
||||||
|
{
|
||||||
|
<partial name="_VPNWarning" />
|
||||||
|
}
|
||||||
|
|
||||||
<div class="col-12">
|
<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
|
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.
|
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 -->
|
<!-- Placeholder Button and Submit Button -->
|
||||||
<div class="d-grid">
|
<div class="d-grid">
|
||||||
<button type="button" class="btn btn-secondary mb-3" id="fakeSubmitButton">Ask Question</button>
|
@if (ViewData["VpnWarning"] is true)
|
||||||
<button type="submit" class="btn btn-dark mb-3 d-none" id="submitButton">Ask Question</button>
|
{
|
||||||
|
<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>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -26,8 +26,12 @@
|
|||||||
<!-- Audio and Text -->
|
<!-- Audio and Text -->
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="bg-white rounded-5 border border-3 border-dark shadow-lg p-3">
|
<div class="bg-white rounded-5 border border-3 border-dark shadow-lg p-3">
|
||||||
|
<div class="hero-video-container">
|
||||||
<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>
|
<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 -->
|
<!-- Audio Player -->
|
||||||
<div class="audio-player text-center">
|
<div class="audio-player text-center">
|
||||||
|
|||||||
@ -90,7 +90,12 @@
|
|||||||
<!-- Section 4 -->
|
<!-- Section 4 -->
|
||||||
<div class="scrapbook-section flex-row-reverse">
|
<div class="scrapbook-section flex-row-reverse">
|
||||||
<div class="scrapbook-image rotate-4">
|
<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>
|
||||||
<div class="scrapbook-text">
|
<div class="scrapbook-text">
|
||||||
<h5>Maggie in Her Jumpsuit</h5>
|
<h5>Maggie in Her Jumpsuit</h5>
|
||||||
|
|||||||
@ -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>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>
|
<p>Use the form below to send Catherine a message.</p>
|
||||||
</div>
|
</div>
|
||||||
|
@if (ViewData["VpnWarning"] is true)
|
||||||
|
{
|
||||||
|
<partial name="_VPNWarning" />
|
||||||
|
}
|
||||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
<div class="col-12 text-dark">
|
<div class="col-12 text-dark">
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
@ -42,7 +46,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-grid">
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
41
CatherineLynwood/Views/Home/Honeypot.cshtml
Normal 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>
|
||||||
@ -12,31 +12,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</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="row align-items-center mb-5">
|
||||||
<div class="col-md-5 text-center">
|
<div class="col-md-5 text-center">
|
||||||
@ -47,10 +22,8 @@
|
|||||||
Your browser does not support the video tag.
|
Your browser does not support the video tag.
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
<!-- Overlaid Text -->
|
<!-- New overlay image -->
|
||||||
<div class="hero-overlay-text hero-title">The Alpha Flame</div>
|
<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 class="hero-overlay-text hero-subtitle">Discovery</div>
|
|
||||||
<div class="hero-overlay-text hero-author">Catherine Lynwood</div>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
19
CatherineLynwood/Views/Home/Offline.cshtml
Normal 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>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en-GB">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
@ -53,18 +53,23 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="bg-primary text-white">
|
<body class="bg-primary text-white">
|
||||||
<div id="background-wrapper">
|
<div id="background-wrapper">
|
||||||
<!-- Fallback image shown by default -->
|
<div class="video-background">
|
||||||
<div class="fixed-background"></div>
|
<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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<!-- Content wrapper to keep everything on top of the background -->
|
<!-- Content wrapper to keep everything on top of the background -->
|
||||||
<header>
|
<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">
|
<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">
|
<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"
|
<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">
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
@ -98,7 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<div class="container-lg" style="margin-top: 70px;">
|
<div class="container-lg" style="margin-top: 90px;">
|
||||||
<main role="main" class="pb-3">
|
<main role="main" class="pb-3">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
</main>
|
</main>
|
||||||
@ -111,14 +116,25 @@
|
|||||||
<div class="row justify-content-center align-items-center" >
|
<div class="row justify-content-center align-items-center" >
|
||||||
<div class="col-md-4 text-center order-md-2">
|
<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>
|
<social-media-share title="Catherine Lynwood Blog" url="@Context.Request.Path" class="text-center m-3"></social-media-share>
|
||||||
© 2024 - Catherine Lynwood
|
© 2024 - @DateTime.Now.Year - Catherine Lynwood
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 text-center order-md-1">
|
<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>
|
||||||
|
|
||||||
<div class="col-md-4 text-center order-md-3">
|
<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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -130,29 +146,7 @@
|
|||||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
<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/dist/jquery.validate.min.js"></script>
|
||||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.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>
|
<script src="https://cdn.plyr.io/3.7.2/plyr.polyfilled.js"></script>
|
||||||
@ -160,7 +154,20 @@
|
|||||||
const player = new Plyr('audio');
|
const player = new Plyr('audio');
|
||||||
</script>
|
</script>
|
||||||
@RenderSection("Scripts", required: false)
|
@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>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
5
CatherineLynwood/Views/Shared/_VPNWarning.cshtml
Normal 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, we’ve 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>
|
||||||
@ -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="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="Index">The Alpha Flame</a></li>
|
||||||
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="DIscovery">Discovery</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>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
@ -17,11 +17,8 @@
|
|||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="text-center mb-5">
|
<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 exclusive glimpse into Beth's story</p>
|
||||||
<p>
|
|
||||||
An excerpt from Chapter 1 of The Alpha Flame, titled "Drowning in Silence - Beth."
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Excerpt Content -->
|
<!-- Excerpt Content -->
|
||||||
@ -39,7 +36,11 @@
|
|||||||
<video controls="controls" poster="/images/Chapter-1.png" class="rounded-5">
|
<video controls="controls" poster="/images/Chapter-1.png" class="rounded-5">
|
||||||
<source src="~/videos/Chapter-1-preview.mp4" type="video/mp4"/>
|
<source src="~/videos/Chapter-1-preview.mp4" type="video/mp4"/>
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<p class="text-center text-muted small pt-2">
|
||||||
|
Watch Beth narrating part of Chapter 1 - Drowning in Silence.
|
||||||
|
</p>
|
||||||
<!-- Audio Player -->
|
<!-- Audio Player -->
|
||||||
<div class="audio-player text-center">
|
<div class="audio-player text-center">
|
||||||
<audio controls>
|
<audio controls>
|
||||||
@ -47,7 +48,7 @@
|
|||||||
Your browser does not support the audio element.
|
Your browser does not support the audio element.
|
||||||
</audio>
|
</audio>
|
||||||
<p class="text-center text-muted small">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- Text Content -->
|
<!-- Text Content -->
|
||||||
@ -77,10 +78,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section Meta {
|
@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"
|
<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-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"
|
meta-keywords="The Alpha Flame, Chapter 1, Maggie, Catherine Lynwood, 1980s fiction, family secrets, strong female characters, captivating novels, fiction by Catherine Lynwood"
|
||||||
|
|||||||
165
CatherineLynwood/Views/TheAlphaFlame/Chapter13.cshtml
Normal 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 wasn’t 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 he’s a punter for God’s sake. That said, guys aren’t exactly queueing up to take me out, and he certainly seemed quite harmless, although perhaps a little needy. I didn’t feel threatened by him at all, and I’d 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 wasn’t exactly huge, so I didn’t 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 hadn’t 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 wasn’t working tonight; I’d have frozen my tits off, I thought.</em></p>
|
||||||
|
<p><em>As I crossed the road, I saw Ben’s 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 you’d 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. “That’s so nice of you. No one’s ever bought me flowers before.”</p>
|
||||||
|
<p><em>Ben’s 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. It’s just that most guys seem to drive a lot faster.”</em></p>
|
||||||
|
<p>“I don’t 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. That’s why I’m 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 don’t want this to be weird. So as far as I’m concerned, yesterday didn’t happen. We’re just on a date because… well, I like you. I think you’re gorgeous.”</p>
|
||||||
|
<p>“Thank you,” I said, feeling a blush creep up my cheeks.</p>
|
||||||
|
<p>“And I’m 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 doesn’t 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 you’re going on a date with me?”</em></p>
|
||||||
|
<p>“Yeah. What’s wrong with that?”</p>
|
||||||
|
<p>“Did you tell him I’m a prostitute?”</p>
|
||||||
|
<p><em>Ben gave a half-smile. “I thought we agreed what each of us does doesn’t matter?”</em></p>
|
||||||
|
<p>“It doesn’t.”</p>
|
||||||
|
<p>“Exactly. But if you must know, I just told him I had a date with a beautiful girl. That’s all.”</p>
|
||||||
|
<p>“So, you’re embarrassed to be seen with me?”</p>
|
||||||
|
<p><em>Ben looked flustered. “No, not at all. If I was, I wouldn’t have asked you out. I’ll shout it from the top of that hill over there if you like, but it won’t 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 I’ll 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 wasn’t 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>
|
||||||
|
|
||||||
|
}
|
||||||
@ -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="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="Index">The Alpha Flame</a></li>
|
||||||
<li class="breadcrumb-item"><a asp-controller="TheAlphaFlame" asp-action="DIscovery">Discovery</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>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
@ -17,18 +17,15 @@
|
|||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="text-center mb-5">
|
<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 exclusive glimpse into Maggie's story</p>
|
||||||
<p>
|
|
||||||
An excerpt from Chapter 2 of The Alpha Flame, titled "The Last Lesson - Maggie."
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Excerpt Content -->
|
<!-- Excerpt Content -->
|
||||||
<div class="row gx-5">
|
<div class="row gx-5">
|
||||||
<!-- Scene Image -->
|
<!-- Scene Image -->
|
||||||
<div class="col-lg-5 mb-4 mb-lg-0">
|
<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>
|
</div>
|
||||||
|
|
||||||
@ -42,7 +39,7 @@
|
|||||||
Your browser does not support the audio element.
|
Your browser does not support the audio element.
|
||||||
</audio>
|
</audio>
|
||||||
<p class="text-center text-muted small">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -80,10 +77,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section Meta {
|
@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"
|
<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-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"
|
meta-keywords="The Alpha Flame, Chapter 2, Maggie, Catherine Lynwood, 1980s fiction, family secrets, strong female characters, captivating novels, fiction by Catherine Lynwood"
|
||||||
|
|||||||
@ -113,16 +113,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-4">
|
<div class="col-md-4 mb-4">
|
||||||
<div class="card h-100 character-card">
|
<div class="card h-100 character-card">
|
||||||
<a asp-action="Characters">
|
<a asp-action="Chapter13">
|
||||||
<responsive-image src="discovery-epilogue.png" class="fit-image" alt="Maggie Grant, The Alpha Flame" display-width-percentage="50"></responsive-image>
|
<responsive-image src="pub-from-chapter-13.png" class="fit-image" alt="Pub from Chapter 13" display-width-percentage="50"></responsive-image>
|
||||||
</a>
|
</a>
|
||||||
<div class="card-body border-top border-3 border-dark">
|
<div class="card-body border-top border-3 border-dark">
|
||||||
<h3 class="card-title">Meet the Characters</h3>
|
<h3 class="card-title">Chapter 13: A Name She Never Owned - Susie</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">Susie goes out for a drink with a punter. What on earth could go wrong...</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="Chapter13" class="btn btn-dark">Read More</a></div>
|
||||||
<p class="card-text">Explore the mind of Rob, the gadget-obsessed photographer whose quiet determination matches his deep connection to Maggie. Then there’s Zoe, the sharp-witted ex-policewoman who’s full of surprises.</p>
|
|
||||||
|
|
||||||
<div class="text-end"><a asp-action="Characters" class="btn btn-dark">Read More</a></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -177,6 +174,21 @@
|
|||||||
|
|
||||||
|
|
||||||
@section Meta{
|
@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 Lynwood’s 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">
|
<script type="application/ld+json">
|
||||||
{
|
{
|
||||||
"@@context": "https://schema.org",
|
"@@context": "https://schema.org",
|
||||||
|
|||||||
@ -65,6 +65,36 @@
|
|||||||
</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">
|
||||||
|
<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="row mb-4">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card h-100 shadow-sm border-start border-3 border-dark position-relative">
|
<div class="card h-100 shadow-sm border-start border-3 border-dark position-relative">
|
||||||
@ -130,6 +160,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section Meta {
|
@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>
|
<style>
|
||||||
.placeholder-blur {
|
.placeholder-blur {
|
||||||
filter: blur(4px);
|
filter: blur(4px);
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 9.4 KiB |
@ -1,2 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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>
|
||||||
@ -14,7 +14,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 95vh;
|
min-height: 93vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default background for larger screens (Extra large and up) */
|
/* Default background for larger screens (Extra large and up) */
|
||||||
@ -24,7 +24,7 @@ html {
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
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-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
@ -34,7 +34,7 @@ html {
|
|||||||
/* Extra small devices (portrait phones, less than 576px) */
|
/* Extra small devices (portrait phones, less than 576px) */
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
.fixed-background {
|
.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-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
@ -44,7 +44,7 @@ html {
|
|||||||
/* Small devices (landscape phones, 576px and up) */
|
/* Small devices (landscape phones, 576px and up) */
|
||||||
@media (min-width: 576px) and (max-width: 767.98px) {
|
@media (min-width: 576px) and (max-width: 767.98px) {
|
||||||
.fixed-background {
|
.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-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
@ -54,7 +54,7 @@ html {
|
|||||||
/* Medium devices (tablets, 768px and up) */
|
/* Medium devices (tablets, 768px and up) */
|
||||||
@media (min-width: 768px) and (max-width: 991.98px) {
|
@media (min-width: 768px) and (max-width: 991.98px) {
|
||||||
.fixed-background {
|
.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-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
@ -64,7 +64,7 @@ html {
|
|||||||
/* Large devices (desktops, 992px and up) */
|
/* Large devices (desktops, 992px and up) */
|
||||||
@media (min-width: 992px) and (max-width: 1199.98px) {
|
@media (min-width: 992px) and (max-width: 1199.98px) {
|
||||||
.fixed-background {
|
.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-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
@ -74,7 +74,7 @@ html {
|
|||||||
/* Extra large devices (larger desktops, 1200px and up) */
|
/* Extra large devices (larger desktops, 1200px and up) */
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
.fixed-background {
|
.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-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
|
|||||||
2
CatherineLynwood/wwwroot/css/site.min.css
vendored
@ -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}
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 511 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
BIN
CatherineLynwood/wwwroot/images/catherine-lynwood-logo.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 30 KiB |
BIN
CatherineLynwood/wwwroot/images/jpg/pub-from-chapter-13-400.jpg
Normal file
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 24 KiB |
BIN
CatherineLynwood/wwwroot/images/maggie-in-her-jumpsuit.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
CatherineLynwood/wwwroot/images/pub-from-chapter-13.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 928 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 261 KiB After Width: | Height: | Size: 295 KiB |
|
Before Width: | Height: | Size: 347 KiB After Width: | Height: | Size: 391 KiB |
|
Before Width: | Height: | Size: 412 KiB |
|
Before Width: | Height: | Size: 611 KiB After Width: | Height: | Size: 688 KiB |
|
Before Width: | Height: | Size: 650 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 4.3 MiB |
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 290 KiB |
|
After Width: | Height: | Size: 314 KiB |
|
After Width: | Height: | Size: 472 KiB |
|
After Width: | Height: | Size: 624 KiB |
|
After Width: | Height: | Size: 673 KiB |
|
After Width: | Height: | Size: 891 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 360 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 132 KiB |