diff --git a/CatherineLynwood/CatherineLynwood.csproj b/CatherineLynwood/CatherineLynwood.csproj index 4d6a8f0..e7037c1 100644 --- a/CatherineLynwood/CatherineLynwood.csproj +++ b/CatherineLynwood/CatherineLynwood.csproj @@ -8,6 +8,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Never @@ -21,16 +53,16 @@ - + - - - - - + + + + + - + diff --git a/CatherineLynwood/Controllers/AccessController.cs b/CatherineLynwood/Controllers/AccessController.cs new file mode 100644 index 0000000..e9f1acd --- /dev/null +++ b/CatherineLynwood/Controllers/AccessController.cs @@ -0,0 +1,124 @@ +using CatherineLynwood.Controllers; +using CatherineLynwood.Models; +using CatherineLynwood.Services; + +using Microsoft.AspNetCore.Mvc; + +using System.Threading.Tasks; + +public class AccessController : Controller +{ + #region Private Fields + + private readonly IAccessCodeService _accessCodeService; + private readonly ILogger _logger; + private DataAccess _dataAccess; + + #endregion Private Fields + + #region Public Constructors + + public AccessController(ILogger logger, DataAccess dataAccess, IAccessCodeService accessCodeService) + { + _logger = logger; + _dataAccess = dataAccess; + _accessCodeService = accessCodeService; + } + + #endregion Public Constructors + + #region Public Methods + + [HttpGet] + public IActionResult MailingList() + { + return View(); + } + + [HttpPost] + public async Task MailingList(Marketing marketing) + { + bool success = true; + + if (!string.IsNullOrEmpty(marketing.Email)) + { + success = await _dataAccess.AddMarketingAsync(marketing); + } + + if (success) + { + // Set cookie so we don’t ask again + Response.Cookies.Append("MailingListPrompted", "true", new CookieOptions + { + Expires = DateTimeOffset.UtcNow.AddYears(5), + IsEssential = true + }); + + // Redirect back to original destination + var returnUrl = TempData["ReturnUrl"] as string ?? "/Extras"; + return Redirect(returnUrl); + } + else + { + return RedirectToAction("Prompt"); + } + } + + [HttpPost] + public IActionResult Decline() + { + // Set cookie so we don’t ask again + Response.Cookies.Append("MailingListPrompted", "true", new CookieOptions + { + Expires = DateTimeOffset.UtcNow.AddYears(5), + IsEssential = true + }); + + // Redirect back to original destination + var returnUrl = TempData["ReturnUrl"] as string ?? "/Extras"; + return Redirect(returnUrl); + } + + [HttpGet] + public async Task Prompt(string returnUrl = "/Extras") + { + var (pageNumber, wordIndex) = await _accessCodeService.GetCurrentChallengeAsync(); + + ViewBag.PageNumber = pageNumber; + ViewBag.WordIndex = wordIndex; + ViewBag.ReturnUrl = returnUrl; + + return View(); + } + + [HttpPost] + public async Task Prompt(string userWord, string returnUrl = "/Extras") + { + var (accessLevel, highestBook) = await _accessCodeService.ValidateWordAsync(userWord); + + if (accessLevel > 0 && highestBook > 0) + { + HttpContext.Session.SetInt32("BookAccessLevel", accessLevel); + HttpContext.Session.SetInt32("BookAccessMax", highestBook); + + var promptedCookie = Request.Cookies["MailingListPrompted"]; + if (string.IsNullOrEmpty(promptedCookie)) + { + TempData["ReturnUrl"] = returnUrl; + return RedirectToAction("MailingList"); + } + + return Redirect(returnUrl); + } + + var (pageNumber, wordIndex) = await _accessCodeService.GetCurrentChallengeAsync(); + ViewBag.PageNumber = pageNumber; + ViewBag.WordIndex = wordIndex; + ViewBag.ReturnUrl = returnUrl; + ViewBag.Error = "Invalid word. Please try again."; + + return View(); + } + + #endregion Public Methods +} \ No newline at end of file diff --git a/CatherineLynwood/Controllers/DiscoveryController.cs b/CatherineLynwood/Controllers/DiscoveryController.cs new file mode 100644 index 0000000..c75e261 --- /dev/null +++ b/CatherineLynwood/Controllers/DiscoveryController.cs @@ -0,0 +1,31 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CatherineLynwood.Controllers +{ + [Route("the-alpha-flame/extras/discovery")] + public class DiscoveryController : Controller + { + public IActionResult Index() + { + return View(); + } + + [Route("epilogue")] + public IActionResult Epilogue() + { + return View(); + } + + [Route("scrap-book")] + public IActionResult ScrapBook() + { + return View(); + } + + [Route("maggies-designs")] + public IActionResult MaggiesDesigns() + { + return View(); + } + } +} diff --git a/CatherineLynwood/Controllers/ErrorController.cs b/CatherineLynwood/Controllers/ErrorController.cs new file mode 100644 index 0000000..3bf71ce --- /dev/null +++ b/CatherineLynwood/Controllers/ErrorController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CatherineLynwood.Controllers +{ + public class ErrorController : Controller + { + public IActionResult AccessDenied() + { + return View(); + } + } +} diff --git a/CatherineLynwood/Controllers/HomeController.cs b/CatherineLynwood/Controllers/HomeController.cs index ac84e28..57bef4c 100644 --- a/CatherineLynwood/Controllers/HomeController.cs +++ b/CatherineLynwood/Controllers/HomeController.cs @@ -66,12 +66,6 @@ namespace CatherineLynwood.Controllers return View(contact); } - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - public IActionResult Error() - { - return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); - } - [Route("feed.xml")] [Route("rss.xml")] [Route("rss")] @@ -131,30 +125,12 @@ namespace CatherineLynwood.Controllers return File(rssBytes, "application/rss+xml", "rss.xml"); } - - - // Helper method to get the file size in bytes - private long GetFileSizeInBytes(string imageUrl) + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IActionResult Error() { - string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", imageUrl.TrimStart('/').Replace("/","\\")); - FileInfo fileInfo = new FileInfo(filePath); - return fileInfo.Exists ? fileInfo.Length : 0; + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } - // Helper method to convert the original image URL to a 400px JPEG URL in the "jpg" folder - private string ConvertToJpgUrl(string originalFileName) - { - // Get the filename without the extension - string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(originalFileName); - - // Construct the full URL for the 400px JPEG in the "jpg" folder - string jpgUrl = $"images/jpg/{fileNameWithoutExtension}-400.jpg"; - - return jpgUrl; - } - - - public async Task Index() { //await SendEmail.Execute(); @@ -173,6 +149,32 @@ namespace CatherineLynwood.Controllers return View(); } + [Route("privacy")] + public IActionResult Privacy() + { + return View(); + } + + // Helper method to convert the original image URL to a 400px JPEG URL in the "jpg" folder + private string ConvertToJpgUrl(string originalFileName) + { + // Get the filename without the extension + string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(originalFileName); + + // Construct the full URL for the 400px JPEG in the "jpg" folder + string jpgUrl = $"images/jpg/{fileNameWithoutExtension}-400.jpg"; + + return jpgUrl; + } + + // Helper method to get the file size in bytes + private long GetFileSizeInBytes(string imageUrl) + { + string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", imageUrl.TrimStart('/').Replace("/", "\\")); + FileInfo fileInfo = new FileInfo(filePath); + return fileInfo.Exists ? fileInfo.Length : 0; + } + #endregion Public Methods #region Private Methods diff --git a/CatherineLynwood/Controllers/PublishingController.cs b/CatherineLynwood/Controllers/PublishingController.cs new file mode 100644 index 0000000..e37fa96 --- /dev/null +++ b/CatherineLynwood/Controllers/PublishingController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CatherineLynwood.Controllers +{ + public class PublishingController : Controller + { + public IActionResult Index() + { + return View(); + } + } +} diff --git a/CatherineLynwood/Controllers/SitemapController.cs b/CatherineLynwood/Controllers/SitemapController.cs index a71696f..4ad1bea 100644 --- a/CatherineLynwood/Controllers/SitemapController.cs +++ b/CatherineLynwood/Controllers/SitemapController.cs @@ -40,6 +40,7 @@ namespace CatherineLynwood.Controllers new SitemapEntry { Url = Url.Action("Index", "TheAlphaFlame", null, Request.Scheme).TrimEnd('/'), LastModified = DateTime.UtcNow }, new SitemapEntry { Url = Url.Action("Blog", "TheAlphaFlame", null, Request.Scheme).TrimEnd('/'), LastModified = DateTime.UtcNow }, new SitemapEntry { Url = Url.Action("Characters", "TheAlphaFlame", null, Request.Scheme).TrimEnd('/'), LastModified = DateTime.UtcNow }, + new SitemapEntry { Url = Url.Action("Discovery", "TheAlphaFlame", null, Request.Scheme).TrimEnd('/'), LastModified = DateTime.UtcNow }, // Additional static pages }; diff --git a/CatherineLynwood/Controllers/TheAlphaFlame.cs b/CatherineLynwood/Controllers/TheAlphaFlameController.cs similarity index 92% rename from CatherineLynwood/Controllers/TheAlphaFlame.cs rename to CatherineLynwood/Controllers/TheAlphaFlameController.cs index e2dfe5a..4217fdc 100644 --- a/CatherineLynwood/Controllers/TheAlphaFlame.cs +++ b/CatherineLynwood/Controllers/TheAlphaFlameController.cs @@ -11,7 +11,7 @@ using SendGrid.Helpers.Mail; namespace CatherineLynwood.Controllers { [Route("the-alpha-flame")] - public class TheAlphaFlame : Controller + public class TheAlphaFlameController : Controller { #region Private Fields @@ -21,7 +21,7 @@ namespace CatherineLynwood.Controllers #region Public Constructors - public TheAlphaFlame(DataAccess dataAccess) + public TheAlphaFlameController(DataAccess dataAccess) { _dataAccess = dataAccess; } @@ -94,6 +94,18 @@ namespace CatherineLynwood.Controllers return View("DefaultTemplate", blog); } + [Route("chapters/chapter-1-beth")] + public IActionResult Chapter1() + { + return View(); + } + + [Route("chapters/chapter-2-maggie")] + public IActionResult Chapter2() + { + return View(); + } + [Route("characters")] public IActionResult Characters() { @@ -149,6 +161,19 @@ namespace CatherineLynwood.Controllers return RedirectToAction("BlogItem", new { slug = blogUrl, showThanks = showThanks }); } + [Route("discovery")] + public IActionResult Discovery() + { + return View(); + } + + [BookAccess(1, 1)] + [Route("extras")] + public IActionResult Extras() + { + return View(); + } + public IActionResult Index() { return View(); @@ -166,6 +191,18 @@ namespace CatherineLynwood.Controllers return View(); } + [Route("reckoning")] + public IActionResult Reckoning() + { + return View(); + } + + [Route("redemption")] + public IActionResult Redemption() + { + return View(); + } + [Route("characters/rick")] public IActionResult Rick() { @@ -196,22 +233,8 @@ namespace CatherineLynwood.Controllers return View(); } - [Route("chapters/chapter-1-beth")] - public IActionResult Chapter1() - { - return View(); - } - [Route("chapters/chapter-2-maggie")] - public IActionResult Chapter2() - { - return View(); - } - [Route("front-cover")] - public IActionResult FrontCover() - { - return View(); - } + #endregion Public Methods diff --git a/CatherineLynwood/Helpers/BookAccessAttribute.cs b/CatherineLynwood/Helpers/BookAccessAttribute.cs new file mode 100644 index 0000000..4577d7f --- /dev/null +++ b/CatherineLynwood/Helpers/BookAccessAttribute.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; + +public class BookAccessAttribute : Attribute, IAsyncAuthorizationFilter +{ + private readonly int _requiredLevel; + private readonly int _requiredBook; + + public BookAccessAttribute(int requiredLevel, int requiredBook) + { + _requiredLevel = requiredLevel; + _requiredBook = requiredBook; + } + + public Task OnAuthorizationAsync(AuthorizationFilterContext context) + { + var session = context.HttpContext.Session; + + var level = session.GetInt32("BookAccessLevel"); + var book = session.GetInt32("BookAccessMax"); + + if (level == null || book == null || level < _requiredLevel || book < _requiredBook) + { + var currentUrl = context.HttpContext.Request.Path + context.HttpContext.Request.QueryString; + context.HttpContext.Items["RequestedUrl"] = currentUrl; // store temporarily + + context.Result = new RedirectToActionResult("Prompt", "Access", new { returnUrl = currentUrl }); + } + + return Task.CompletedTask; + } + +} diff --git a/CatherineLynwood/Models/AccessCode.cs b/CatherineLynwood/Models/AccessCode.cs new file mode 100644 index 0000000..4f8ad56 --- /dev/null +++ b/CatherineLynwood/Models/AccessCode.cs @@ -0,0 +1,11 @@ +namespace CatherineLynwood.Models +{ + public class AccessCode + { + public int PageNumber { get; set; } + public int WordIndex { get; set; } + public string ExpectedWord { get; set; } + public int AccessLevel { get; set; } // 1 = basic, 2 = retail, 3 = deluxe + public int BookNumber { get; set; } // 1, 2, or 3 + } +} \ No newline at end of file diff --git a/CatherineLynwood/Models/BlogComment.cs b/CatherineLynwood/Models/BlogComment.cs index 2fd6a16..fdd9f2a 100644 --- a/CatherineLynwood/Models/BlogComment.cs +++ b/CatherineLynwood/Models/BlogComment.cs @@ -4,10 +4,9 @@ namespace CatherineLynwood.Models { public class BlogComment { - [Required(ErrorMessage = "Please enter your age.")] - [Range(18, 120, ErrorMessage = "You must be at least 18 years old.")] + [Required(ErrorMessage = "Please select your age group.")] [Display(Name = "Your Age", Prompt = "Your age")] - public int Age { get; set; } + public string Age { get; set; } public int BlogID { get; set; } diff --git a/CatherineLynwood/Models/Marketing.cs b/CatherineLynwood/Models/Marketing.cs new file mode 100644 index 0000000..c92aa14 --- /dev/null +++ b/CatherineLynwood/Models/Marketing.cs @@ -0,0 +1,34 @@ +using System.ComponentModel.DataAnnotations; + +namespace CatherineLynwood.Models +{ + public class Marketing + { + #region Public Properties + + [Required(ErrorMessage = "Please select your age group.")] + [Display(Name = "Your Age", Prompt = "Your age")] + public string Age { get; set; } + + [Required(ErrorMessage = "Please enter your email address.")] + [EmailAddress(ErrorMessage = "Please enter a valid email address.")] + [Display(Name = "Your Email Address", Prompt = "Your email address")] + public string Email { get; set; } = string.Empty; + + [Required(ErrorMessage = "Please enter your name.")] + [Display(Name = "Your Name", Prompt = "Your name")] + public string Name { get; set; } = string.Empty; + + public bool optExtras { get; set; } + + public bool optFutureBooks { get; set; } + + public bool optNews { get; set; } + + [Required(ErrorMessage = "Please select your sex, or prefer not to say option.")] + [Display(Name = "Your Sex", Prompt = "Your sex")] + public string Sex { get; set; } = string.Empty; + + #endregion Public Properties + } +} \ No newline at end of file diff --git a/CatherineLynwood/Models/PreFillContact.cs b/CatherineLynwood/Models/PreFillContact.cs index 2488a73..8091d82 100644 --- a/CatherineLynwood/Models/PreFillContact.cs +++ b/CatherineLynwood/Models/PreFillContact.cs @@ -6,7 +6,7 @@ namespace CatherineLynwood.Models { #region Public Properties - public int Age { get; set; } + public string Age { get; set; } = string.Empty; public string EmailAddress { get; set; } = string.Empty; diff --git a/CatherineLynwood/Models/Question.cs b/CatherineLynwood/Models/Question.cs index 461d97c..015da5e 100644 --- a/CatherineLynwood/Models/Question.cs +++ b/CatherineLynwood/Models/Question.cs @@ -4,10 +4,9 @@ namespace CatherineLynwood.Models { public class Question { - [Required(ErrorMessage = "Please enter your age.")] - [Range(18, 120, ErrorMessage = "You must be at least 18 years old.")] + [Required(ErrorMessage = "Please select your age group.")] [Display(Name = "Your Age", Prompt = "Your age")] - public int Age { get; set; } + public string Age { get; set; } [Required(ErrorMessage = "Please enter your question.")] [Display(Name = "Your Question", Prompt = "Your question")] diff --git a/CatherineLynwood/Program.cs b/CatherineLynwood/Program.cs index 8450143..efb753d 100644 --- a/CatherineLynwood/Program.cs +++ b/CatherineLynwood/Program.cs @@ -1,7 +1,8 @@ -using System.IO.Compression; +using System.IO.Compression; using CatherineLynwood.Middleware; using CatherineLynwood.Services; + using Microsoft.AspNetCore.ResponseCompression; using WebMarkupMin.AspNetCoreLatest; @@ -24,6 +25,17 @@ namespace CatherineLynwood // Add IHttpContextAccessor for accessing HTTP context in tag helpers builder.Services.AddHttpContextAccessor(); + // ✅ Add session services (in-memory only) + builder.Services.AddSession(options => + { + options.IdleTimeout = TimeSpan.FromMinutes(30); + options.Cookie.HttpOnly = true; + options.Cookie.IsEssential = true; + }); + + // ✅ Register the book access code service + builder.Services.AddScoped(); + // Add response compression services builder.Services.AddResponseCompression(options => { @@ -49,7 +61,6 @@ namespace CatherineLynwood }) .AddHtmlMinification(); - var app = builder.Build(); // Configure the HTTP request pipeline. @@ -69,6 +80,9 @@ namespace CatherineLynwood app.UseWebMarkupMin(); + // ✅ Enable session BEFORE authorization + app.UseSession(); + app.UseAuthorization(); app.MapControllerRoute( diff --git a/CatherineLynwood/Services/AccessCodeService.cs b/CatherineLynwood/Services/AccessCodeService.cs new file mode 100644 index 0000000..dc89776 --- /dev/null +++ b/CatherineLynwood/Services/AccessCodeService.cs @@ -0,0 +1,53 @@ +using CatherineLynwood.Models; + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CatherineLynwood.Services +{ + public interface IAccessCodeService + { + Task<(int pageNumber, int wordIndex)> GetCurrentChallengeAsync(); + Task<(int accessLevel, int highestBook)> ValidateWordAsync(string userWord); + } + + + public class AccessCodeService : IAccessCodeService + { + private readonly List _accessCodes; + + public AccessCodeService() + { + _accessCodes = new List + { + // 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() + { + var challenge = _accessCodes.First(); // current prompt + return Task.FromResult((challenge.PageNumber, challenge.WordIndex)); + } + + public Task<(int accessLevel, int highestBook)> ValidateWordAsync(string userWord) + { + var match = _accessCodes.FirstOrDefault(c => + c.ExpectedWord.Equals(userWord, StringComparison.OrdinalIgnoreCase)); + + if (match != null) + return Task.FromResult((match.AccessLevel, match.BookNumber)); + + return Task.FromResult((0, 0)); // invalid + } + } + +} diff --git a/CatherineLynwood/Services/DataAccess.cs b/CatherineLynwood/Services/DataAccess.cs index 255b01a..c73121b 100644 --- a/CatherineLynwood/Services/DataAccess.cs +++ b/CatherineLynwood/Services/DataAccess.cs @@ -42,7 +42,7 @@ namespace CatherineLynwood.Services { questions.AskedQuestions.Add(new Question { - Age = GetDataInt(rdr, "Age"), + Age = GetDataString(rdr, "Age"), EmailAddress = GetDataString(rdr, "EmailAddress"), Name = GetDataString(rdr, "Name"), Text = GetDataString(rdr, "Question"), @@ -275,6 +275,40 @@ namespace CatherineLynwood.Services return visible; } + public async Task AddMarketingAsync(Marketing marketing) + { + 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 = "SaveMarketingOptions"; + cmd.Parameters.AddWithValue("@Name", marketing.Name); + cmd.Parameters.AddWithValue("@Email", marketing.Email); + cmd.Parameters.AddWithValue("@OptExtras", marketing.optExtras); + cmd.Parameters.AddWithValue("@OptFutureBooks", marketing.optFutureBooks); + cmd.Parameters.AddWithValue("@OptNews", marketing.optNews); + cmd.Parameters.AddWithValue("@Age", marketing.Age); + cmd.Parameters.AddWithValue("@Sex", marketing.Sex); + + await cmd.ExecuteNonQueryAsync(); + } + catch (Exception ex) + { + success = false; + } + } + } + + return success; + } + public async Task AddQuestionAsync(Question question) { bool visible = false; diff --git a/CatherineLynwood/TagHelpers/ResponsiveImageTagHelper.cs b/CatherineLynwood/TagHelpers/ResponsiveImageTagHelper.cs index c8ab25f..7796b44 100644 --- a/CatherineLynwood/TagHelpers/ResponsiveImageTagHelper.cs +++ b/CatherineLynwood/TagHelpers/ResponsiveImageTagHelper.cs @@ -46,10 +46,11 @@ namespace CatherineLynwood.TagHelpers string fileName = Path.GetFileNameWithoutExtension(rootPath); string extension = Path.GetExtension(rootPath); + string year = DateTime.Now.Year.ToString(); // Define paths for "webp" and "jpg" subfolders string webpDirectory = Path.Combine(directory, "webp"); string jpgDirectory = Path.Combine(directory, "jpg"); - string watermarkText = "© Catherine Lynwood 2024"; + string watermarkText = $"© Catherine Lynwood {year}"; // Ensure the subdirectories exist Directory.CreateDirectory(webpDirectory); diff --git a/CatherineLynwood/TagHelpers/SocialMediaShareTagHelper.cs b/CatherineLynwood/TagHelpers/SocialMediaShareTagHelper.cs index 665fb71..bc22c5f 100644 --- a/CatherineLynwood/TagHelpers/SocialMediaShareTagHelper.cs +++ b/CatherineLynwood/TagHelpers/SocialMediaShareTagHelper.cs @@ -2,48 +2,47 @@ namespace CatherineLynwood.TagHelpers { - [HtmlTargetElement("social-media-share")] - public class SocialMediaShareTagHelper : TagHelper - { - // The URL of the page to share - public string Url { get; set; } + [HtmlTargetElement("social-media-share")] + public class SocialMediaShareTagHelper : TagHelper + { + public string Url { get; set; } + public string Title { get; set; } + public string Class { get; set; } - // Optional title for the shared content - public string Title { get; set; } + public override void Process(TagHelperContext context, TagHelperOutput output) + { + var encodedUrl = $"https://www.catherinelynwood.com{Url}"; + var encodedTitle = Title ?? "Check this out!"; - // Additional CSS classes for the div - public string Class { get; set; } + var facebookUrl = $"https://www.facebook.com/sharer/sharer.php?u={encodedUrl}"; + var twitterUrl = $"https://twitter.com/intent/tweet?url={encodedUrl}&text={encodedTitle}"; + var linkedinUrl = $"https://www.linkedin.com/sharing/share-offsite/?url={encodedUrl}"; + var pinterestUrl = $"https://pinterest.com/pin/create/button/?url={encodedUrl}&description={encodedTitle}"; - public override void Process(TagHelperContext context, TagHelperOutput output) - { - // Ensure Url is encoded - var encodedUrl = $"https://www.catherinelynwood.com{Url}"; // Replace with a default if URL is not provided - var encodedTitle = Title ?? "Check this out!"; + var shareHtml = $@" + "; - // Define the social media sharing URLs - var facebookUrl = $"https://www.facebook.com/sharer/sharer.php?u={encodedUrl}"; - var twitterUrl = $"https://twitter.com/intent/tweet?url={encodedUrl}&text={encodedTitle}"; - var linkedinUrl = $"https://www.linkedin.com/sharing/share-offsite/?url={encodedUrl}"; - var pinterestUrl = $"https://pinterest.com/pin/create/button/?url={encodedUrl}&description={encodedTitle}"; + var followHtml = @" + "; - // Set the tag output - output.TagName = "p"; // container for the social media buttons - output.TagMode = TagMode.StartTagAndEndTag; + output.TagName = "div"; + output.TagMode = TagMode.StartTagAndEndTag; - // Apply the passed CSS classes along with "social-media-share" default class - var cssClass = string.IsNullOrEmpty(Class) ? "social-media-share" : $"social-media-share {Class}"; - output.Attributes.SetAttribute("class", cssClass); + var cssClass = string.IsNullOrEmpty(Class) ? "social-media-share" : $"social-media-share {Class}"; + output.Attributes.SetAttribute("class", cssClass); - // Construct HTML for each button - var content = $@" - - - - - "; - - // Set the inner HTML for the output - output.Content.SetHtmlContent(content); - } - } + output.Content.SetHtmlContent(shareHtml + followHtml); + } + } } diff --git a/CatherineLynwood/Views/Access/MailingList.cshtml b/CatherineLynwood/Views/Access/MailingList.cshtml new file mode 100644 index 0000000..118c829 --- /dev/null +++ b/CatherineLynwood/Views/Access/MailingList.cshtml @@ -0,0 +1,112 @@ +@model CatherineLynwood.Models.Marketing + +@{ + ViewData["Title"] = "Join the Mailing List"; +} + +
+
+
+

Would you like to stay in touch?

+ +

We’d love to keep you updated, but only if you want to be.

+

As a thank you, you will be granted access to even more great exclusive content. Don't miss out!

+ +
+
+
+ + + +
+
+
+
+ + + +
+
+
+

You don't have to tell me your age or sex, but it would really help me understand my readers if you do.

+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +

+ We respect your privacy. You can unsubscribe at any time. View our privacy policy. +

+ + +
+ +
+
+ +
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +@section Meta{ + + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/Access/Prompt.cshtml b/CatherineLynwood/Views/Access/Prompt.cshtml new file mode 100644 index 0000000..4003123 --- /dev/null +++ b/CatherineLynwood/Views/Access/Prompt.cshtml @@ -0,0 +1,56 @@ +@{ + ViewData["Title"] = "Verify Book Access"; + int pageNumber = ViewBag.PageNumber; + int wordIndex = ViewBag.WordIndex; + string error = ViewBag.Error as string; +} + +
+
+
+ + +
+ +
+

Unlock Your Bonus Content

+ +

+ Thank you for purchasing The Alpha Flame: Discovery. + To access the exclusive extras section, including behind-the-scenes notes, artwork, and more, please verify that you own a physical copy of the book. +

+ +
+ This check only works with paperback and hardback editions. Unfortunately, Kindle editions may not show consistent page numbers or word positions, so access is limited to physical copies for now. +
+ +
+ + +

+ Please enter the word found on page @pageNumber, word @wordIndex in your copy. +

+ +
+ +
+ + @if (!string.IsNullOrEmpty(error)) + { +
@error
+ } + + +
+ +

+ Your privacy is important. This verification is a one-time check and no personal data is stored. +

+
+
+
+ +@section Meta { + + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/AskAQuestion/Index.cshtml b/CatherineLynwood/Views/AskAQuestion/Index.cshtml index 04e3b3d..005c0b0 100644 --- a/CatherineLynwood/Views/AskAQuestion/Index.cshtml +++ b/CatherineLynwood/Views/AskAQuestion/Index.cshtml @@ -95,10 +95,13 @@
diff --git a/CatherineLynwood/Views/Discovery/Epilogue.cshtml b/CatherineLynwood/Views/Discovery/Epilogue.cshtml new file mode 100644 index 0000000..b461331 --- /dev/null +++ b/CatherineLynwood/Views/Discovery/Epilogue.cshtml @@ -0,0 +1,160 @@ +@{ + ViewData["Title"] = "The Alpha Flame | Chapter 1 Excerpt"; +} + +
+
+ +
+
+ + +
+

The Alpha Flame: Discovery

+
+ + +
+ +
+
+ + + + +
+ +
+ +
+

Epilogue

+

Narrated by Maggie – Late May 1983

+
+ +
+

Beth and I pulled into the car park of the Barnt Green Inn with the roof down, the late afternoon sun warming our faces. Everything looked more vivid lately, the colours brighter, the air lighter. It was like the whole world had released a breath.

+

I locked the car, and we wandered round to the beer garden. Rob and Zoe were already there, sat close, chatting like old friends. Even now, after everything, it still surprised me to see them so relaxed together.

+

Rob spotted us and raised a hand. “Hey!”

+

I leaned down and kissed him on the cheek. “Hiya. Can you get us a drink?”

+

“Of course. What do you fancy?”

+

“Coke for me. Beth?”

+

She gave a small smile. “Cider, please.”

+

Rob nodded and headed for the bar.

+

Beth and I took the seats opposite Zoe.

+

“How’ve you both been?” Zoe asked, giving us a once-over.

+

I glanced at Beth. “Good… I think. Still getting used to it all.”

+

Beth nodded. “Yeah. I’m alright. Put some weight on. I’m nearly as fat as Maggie now,” she grinned.

+

I laughed, nudging her. “Nearly? That ship has sailed, love.”

+

“Mum’s fault. Too many sausage sandwiches.”

+

“You both look good,” Zoe said, eyes lingering just a little longer on Beth. “Bruises gone?”

+

We nodded.

+

“So, what have you two been doing with yourselves?”

+

Beth perked up. “Helping Maggie with her designs. Turns out I’m not bad with a needle.”

+

“And she’s not a bad model either,” I added. “Definitely helps having someone try things on.”

+

Zoe smirked. “Do you make her twirl like they do on those fashion shows?”

+

Beth put on a mock pout. “She makes me pose like I’m in Vogue. Arms here, head there.”

+

“Only when you’re being annoying,” I said, laughing. “Besides, you love it.”

+

“True,” Beth admitted. “It’s actually fun. I never thought I’d enjoy something like that.”

+

Laughter echoed behind us as Rosie and Rebecca came round the corner.

+

“She’s deadly,” Rebecca giggled. “I had my eyes closed the whole way here.”

+

“It wasn’t that bad!” Rosie huffed, trying to look offended. “Not my fault people kept jumping out in front of me.”

+

“You might try braking instead of shouting. It’s far more effective,” Rebecca teased.

+

“Where’s Rob?” Rosie asked.

+

“He’s at the bar. If you’re quick, you might get a free drink,” I said.

+

Right on cue, Rob returned with a tray.

+

He clocked the new arrivals and sighed. “I’m going back to the bar, aren’t I?”

+

He placed the drinks down, then turned with theatrical weariness. “The usual, girls?”

+

“Yes please,” said Rebecca sweetly.

+

Once he was back and settled, we all relaxed into the rhythm of easy chatter.

+

“So, who’s got summer plans then?” Rosie asked. “Please tell me someone’s going somewhere glamorous.”

+

“Barnt Green counts as glamorous, right?” I said.

+

“Only if you squint,” said Zoe. “And ignore the smell of wet dog that always seems to hang around the canal.”

+

“I might take Beth to London,” I said. “Show her the big city.”

+

Beth raised an eyebrow. “What for?”

+

“So, you can be horrified at the price of everything and then come home saying how much nicer Birmingham is.”

+

“Sold,” she laughed.

+

Zoe leaned forward, lowering her voice slightly. “I heard from Graham. The case against Rick’s progressing.”

+

Beth stiffened slightly but nodded.

+

“Are you two going to be alright when it comes to court?”

+

Beth and I exchanged a look. We’d talked about it endlessly in private.

+

“We think so,” Beth said. “It’s black and white for us. We just have to tell the truth.”

+

Rob had gone quiet, his brow furrowed.

+

“You alright?” I asked.

+

He hesitated, then said, “It’s just… I don’t believe in coincidences. Not ones like that.”

+

Rebecca cocked her head. “Is he always this cryptic?”

+

“Most of the time,” I said. “This one’s new, though. Go on, Rob. Spit it out.”

+

“Rick,” he said. “The night Beth ended up under the flyover. Him just being there… it never sat right with me.”

+

Beth’s face fell still. “You think he was following me?”

+

Rob gave a half-shrug. “Feels too neat to be chance.”

+

Beth looked down. “He did have the flat, though. Cindy lived there too, remember. Maybe he was nearby anyway.”

+

“Maybe,” Rob said, but not like he believed it.

+

Rosie clapped her hands lightly. “Well, on a brighter note, Greg’s birthday is next week. He’s throwing a party. You’re all invited.”

+

Beth’s eyes lit up. “I’ve never been to a grown-up party. Not really. I’m in.”

+

“You’ll need something to wear,” I said. “And no, you’re not stealing that red skirt again.”

+

“I only borrowed it.”

+

“For three weeks.”

+

Rosie smirked. “Are you two dressing the same again?”

+

“Obviously,” we said in unison.

+

Zoe groaned. “Have you noticed they do that constantly now?” She turned to Rob. “Seriously, get out while you still can.”

+

Beth and I grinned at each other.

+

“I really don’t know what they’re…”

+

“…on about. Do you?” we said, still in sync.

+

Rebecca had been quiet, but now her voice was cautious. “Are you going to look for your dad?”

+

We both paused.

+

“We would like to,” I replied. “We haven’t really got too much to go on. There are a few things we’ve got to follow up in Beth’s memory tin. There’s a bank book for one. It’s only got one pound seventy-nine in it, but it might give us a clue.”

+

Beth added. “We’ve also got the wedding photos… and a date. Oh, and even the name of the church. So, we might be able to find something there, if we can find the right church.”

+

The table fell quiet for a moment.

+

“Did your mum ever talk about him?” Rebecca asked.

+

“Not really,” Beth said. “She used to say ‘He’s nobody worth knowing.’ But I’m not sure she meant it.”

+

Rosie glanced up. “It’s such a lovely day. We should go to the beach one weekend.”

+

Beth’s eyes went wide. “Yes! All of us. It’d be amazing.”

+

“I’ll bring sandwiches,” said Rob. “Beth, you’re banned from cooking anything though.”

+

“Hey! That cheese toastie was only slightly burnt.”

+

“It was charcoal.”

+

“I quite liked it,” I added. “Adds crunch.”

+

General agreement followed.

+

“I need the loo,” said Rebecca.

+

“Me too. I’ll grab drinks on the way back. Same again?”

+

“Perfect,” said Zoe.

+

Once they were out of earshot, Zoe leaned in. “She really doesn’t know, does she? About Sophie.”

+

We shook our heads.

+

“They’re nothing alike,” I said. “Different planets.”

+

“Sophie still avoiding you?” Zoe asked.

+

I nodded. “Mostly. I saw her once. She didn’t stop.”

+

Beth’s face darkened. “I can still see her face. That night. Just after she gave the order.”

+

Zoe blinked. “You think she did?”

+

Beth didn’t hesitate. “She knew what Rick was going to do. That club… there’s more to it. You think that, don’t you?”

+

Zoe nodded slowly. “Graham thinks so too. Says something stinks, but he hasn’t nailed it yet.”

+

Beth’s voice dropped to a whisper. “Mum wasn’t killed for nothing. Adam either. Rick even said so.”

+

“Has Graham got anything else out of Rick?” I asked.

+

“Nothing solid,” Zoe replied. “He’s clammed up. He’s gone ‘No comment’ on everything.”

+

“And our aunt? Still scared?” Beth asked.

+

“He’s working on her. She’s terrified. He’s got to go gently.”

+

Beth’s voice hardened. “What about Baker?”

+

Zoe’s face tightened. “He’s not in the frame. Yet. Graham’s gathering evidence, but if he pushes too soon, Baker will cover his tracks.”

+

Rebecca and Rosie returned, laughing.

+

“What have you two done now?” I asked.

+

“She dropped a tray of drinks on some poor guy,” Rosie grinned. “She’s worse than Rob.”

+

“Oi!” Rob protested. “That was once.”

+

“Twice,” I said, grinning, and leaned in to kiss him.

+

Beth rolled her eyes. “They’re going to be unbearable if they stay this happy.”

+

“Jealous?” I teased.

+

“A bit,” she admitted, then smiled. “But in the good way.”

+

The sun dipped lower, the sky glowing amber. For now, we had peace. But we hadn’t finished. Not yet. The flame had only just started to burn.

+ + +
+
+
+
diff --git a/CatherineLynwood/Views/Discovery/MaggiesDesigns.cshtml b/CatherineLynwood/Views/Discovery/MaggiesDesigns.cshtml new file mode 100644 index 0000000..8166993 --- /dev/null +++ b/CatherineLynwood/Views/Discovery/MaggiesDesigns.cshtml @@ -0,0 +1,373 @@ + +
+
+ +
+
+ +
+

Maggie's Designs

+

+ I love fashion and I trued to weave that into Maggie's charactger. Helped by AI I really enjoyed coming up with outfits + for Maggie to wear in the various scenes of the book. Lots were so far out there that they didn't make it to the final edit, + or the descriptions were so detailed that you've had nodded off. +

+

+ That said, no matter what the outfit was I found working from a visual prompt enable me to write more vividly about it. +

+ + +
+
+ +
+ “She didn’t dress to impress. She dressed to become, a force wrapped in colour, stitched in self-belief.” +
+ +
+
+
“The Elle Dress” – Fully Formed
+ +

This is it, the dress that stopped hearts and turned pages. The one Maggie wore for *Elle*, unapologetic and unforgettable. There’s nothing shy about this piece. It’s all precision and provocation; a sculpted plunge, a defiant cut-out, a hemline that dances between lingerie and high fashion. Every detail speaks Maggie’s language, fire without fuss, beauty without permission. She didn’t just wear this dress… she claimed it. And in doing so, she claimed herself.

+ +

The deep teal shimmered like danger in low light, somewhere between mermaid and menace. I remember writing the scene and thinking, *this isn’t about being sexy, it’s about being seen*. This dress is armour. Soft in texture, sharp in purpose. The fishnet tights? That was Maggie’s touch. A reminder that no matter how glossy the set, she brought her own edge with her. Always.

+ +

There may be another version of this dress later, refined, reimagined. But this one? This is the original. The raw truth. The moment the world turned to look… and Maggie didn’t flinch.

+ +
+
+ + +
+
+ +
+ “She didn’t rise from ashes. She bloomed from the soil, raw, rooted, and wild beyond taming.” +
+ +
+
+
“Forest Siren” – The Evolution of Elle
+ +

This is what happens when a woman finds her voice, when the flame that once flickered is now fully ablaze, controlled, focused, and utterly arresting. This dress is the next chapter after the *Elle* shoot, not just an outfit, but a statement. A transformation. A whispered prophecy realised. The original was power through seduction… but this? This is power through presence.

+ +

I imagined Maggie walking barefoot across stone in this. Not for a crowd. Not even for the camera. Just for herself. The soft, trailing green, almost moss-like in motion, conjures wild things and whispered rebellions. The floral lace still clings, but it no longer begs to be noticed. It simply exists, unafraid, untamed. The high slit and fishnets remain, a signature. A nod to the girl who fought to survive. But the gown? That belongs to the woman she’s become.

+ +

There’s a reason this version was never photographed for the magazine. It wasn’t fashion anymore. It was folklore. A garment you glimpse once and never forget. And like Maggie, it doesn’t ask you to understand it. It only asks that you remember.

+ +
+
+ + +
+
+ +
+ “She didn’t wear it to be wanted. She wore it to be undeniable.” +
+ +
+
+
“Ivory Fire” – The One That Smouldered Off-Page
+ +

This dress never appeared in the book, but it haunted the edges of it. I imagined Maggie in it once, just once, and the image never left. It was lace, yes, but not gentle. The kind of lace that clung like memory and cut like truth. It wasn’t designed to cover; it was designed to challenge. Petals traced over her chest like secrets too dangerous to speak aloud, their edges dipping into skin with a kind of deliberate precision that made it impossible to ignore her.

+ +

She didn’t wear this to seduce. She wore it to reclaim. I pictured her standing still in it while the world moved around her, daring it to catch up. The neckline plunged, but it was her gaze that undressed the room. In the end, it was too much for the scene I was writing, too sharp, too strong, too unforgettable. So I left it behind. But like so much of Maggie, it lived on in the shadows between pages. Not forgotten. Just waiting.

+ +
+
+ + +
+
+ +
+ “It burned beneath the fabric, not just colour, but something molten and unspoken. She was the match and the flame.” +
+ +
+
+
“Ember Veins” – The Prototype
+ +

This was the dress that nearly made it, an early vision of what would eventually evolve into Maggie’s infamous jumpsuit in Chapter 7. I called it *Ember Veins* because the pattern reminded me of fire trapped under silk, alive just beneath the surface. The fabric moves like it’s breathing. Every flick of orange, red, and teal threads through the design like molten emotion stitched into form. It’s bold, unapologetic… and yet, it never quite felt like the right fit for the scene. Too regal. Too statuesque. Not enough of Maggie’s street-born swagger.

+ +

But the essence is here. The deep plunge that dares the room to judge her. The sculpted waist that declares power, not permission. And the colours, oh, the colours. They felt like Maggie’s moods during that chapter: blazing, unpredictable, and impossible to ignore. This wasn’t something she would wear to blend in; it was what she’d wear to set a room on fire.

+ +

Ultimately, the jumpsuit won, it had grit, mobility, and a whisper of rebellion. But *Ember Veins* still has a place in Maggie’s story. Not on the page, perhaps… but in the margins, smouldering quietly, waiting to be remembered.

+ +
+
+ + +
+
+ +
+ “It wasn’t about seduction. It was about control, about saying, ‘You can look… but you don’t get to touch.’” +
+ +
+
+
“Midnight Teal” – The Dress Before Elle
+ +

Before Maggie stunned the world in the pages of *Elle*, there was this. A raw, electric concept that pulsed with possibility. I called it *Midnight Teal*, a piece that sat somewhere between lingerie and defiance, stitched not for comfort but for confrontation. This was Maggie untamed, unfiltered, unapologetically herself. It wasn’t designed for the high street or a Paris runway… it was born for shadows and stares, for flickering candlelight and whispered thoughts.

+ +

The lace, tangled like secrets, reveals more than it hides. The fishnets ground her in the kind of grit only Maggie could carry. And that choker? A black ribbon that says “you can look, but you don’t get to own.” I always imagined her wearing this not to seduce, but to reclaim. Not to tease, but to dare. This wasn’t about being pretty. It was about being powerful.

+ +

Ultimately, it was too much for the magazine shoot. Elle needed elegance. This was rebellion. But I keep it here, because it mattered. Because somewhere in Maggie’s soul, this dress still lives, wild, sensual, fearless. A dress not worn for an audience, but for herself.

+ +
+
+ + +
+
+ +
+ “I can be soft. But don’t mistake me for breakable.” +
+ +
+
+
“Sleek Intentions” – The Outfit That Almost Was
+ +

Before the white two-piece took its place in Chapter 15, this was the look. A vision in midnight black, bold, sculpted, unforgiving. I imagined Maggie in this as a weapon disguised as elegance. The high neck and sheer sleeves gave it structure, control… but the body-hugging lines spoke of something else entirely. Power. Restraint. And maybe a little hunger too. She wasn’t dressing for flirtation; she was dressing for impact.

+ +

This was meant to be her first appearance at Ricardo’s, a table full of family, wine, and a quiet undercurrent of testing the waters. But the outfit changed because the tone did. White softened the edges. A two-piece gave her room to move, to breathe, to step into that moment with grace rather than dominance. And yet I still love this version. It shows the side of Maggie that doesn’t compromise, the girl who grew up armoured in silence and attitude.

+ +

*Sleek Intentions* never made it to the page, but it belonged to the story all the same. The decision not to wear it says as much as if she had. Sometimes, power is in the pivot, in choosing softness when the world expects sharp.

+ +
+
+ + +
+
+ +
+ “She didn’t escape the fire. She walked through it, and the flowers grew behind her.” +
+ +
+
+
“Where the Poppies Burn” – A Dream of Freedom
+ +

This one was never meant for the story itself, not directly. It was more of a whisper behind the writing. A vision I carried with me in quiet moments: Maggie, walking barefoot through a field of fire-tipped poppies, the world golden and glowing around her. She’s not looking back. She doesn’t need to. Whatever held her is gone. Whatever comes next is hers to decide.

+ +

The dress is barely there, a gauze of lace and suggestion, soft as breath, flowing like memory. It’s not about seduction, not here. It’s about shedding. About choosing vulnerability in a world that demanded armour. Her hair is wild, her steps silent, and the light clings to her like it knows she’s survived something most never would.

+ +

I once considered using this for the cover. It would have been unconventional, maybe too symbolic, but it captured a truth. Not about what Maggie wears, or where she walks, but who she is when no one is watching. This image was never part of the story on the page… but it’s part of the soul underneath it.

+ +
+
+ + +
+
+ +
+ “You don’t rise from fire without learning how to burn.” +
+ +
+
+
“Verdant Fury” – The Goddess Unleashed
+ +

This was never meant to be subtle. This was me asking, *what if Maggie didn’t just survive… what if she ruled?* What if all the hurt, all the hunger, all the fire she'd kept bottled up was no longer something she hid, but something she wore? The result was this: *Verdant Fury*. A vision in deep emerald and gold, clinging to her like ivy laced with flame.

+ +

There’s a mythic quality to this look, part forest queen, part fallen angel, all defiance. The sculpted bodice doesn’t just highlight her form, it *armours* it. The gloves, shredded and clinging, feel like echoes of a battle already won. She stands here not as a girl escaping the past, but as a woman who’s scorched the path behind her. And those eyes, they’re not asking for permission. They’re issuing a challenge.

+ +

This outfit never had a scene. It was too much to contain. Too electric, too dangerous. But it lives in the spirit of Maggie all the same. In the moments where she turns, chin lifted, and dares the world to tell her she can’t. It’s not fashion. It’s a reckoning draped in green.

+ +
+
+ + +
+
+ +
+ “She wore it like a dare, and Zoe answered with a kiss.” +
+ +
+
+
“Unveiling Desires” – The Painted Flame Jumpsuit
+ +

This was never a maybe. This jumpsuit was destined to be worn. From the moment I imagined Maggie walking into that nightclub on New Year’s Eve, I saw her in this, a riot of colour, molten silk clinging to her with intent. Gold, vermilion, violet, turquoise… each hue brushed like fire across fabric, alive with movement, bold without apology. She didn’t just wear it, she ignited it.

+ +

Everything about it was deliberate. The plunging neckline, the fitted waist, the shimmer that caught the light every time she turned, it was a siren song, yes, but also a declaration. She made it herself, of course. Maggie’s talent always came from that raw place inside her, where fire met finesse. And in this look, her artistry wasn’t just visible, it was undeniable.

+ +

The jumpsuit became more than fashion. It was foreplay. Power. The spark that lit the fuse between her and Zoe, making their chemistry explosive and immediate. This outfit had presence. It was the flame before the kiss, the stroke before the sigh. And it belongs in this scrapbook because it didn’t just make it into the book, it helped define it.

+ +
+
+ + +
+
+ +
+ “She didn’t wear it… but for a moment, she almost did.” +
+ +
+
+
“Whispers in Lace” – The Dress That Was Too Much
+ +

This gown was a daydream. An experiment in elegance. I imagined Maggie twirling through Ricardo’s grand hallway, all lace and light, every step sweeping the floor like she was born to haunt ballrooms. But as soon as I saw it fully realised, I knew, this wasn’t her moment for that. This dress belonged to a different story. One where Maggie danced, yes, but not in a world as grounded as hers. It was too refined, too ethereal, too… not quite right.

+ +

Still, there’s something about it that I loved. The off-shoulder cut, the illusion of fragility, the way it billowed with every motion. It captured the romantic part of Maggie that often hides behind her fire, the dreamer, the artist, the girl who still, despite everything, believes in beauty. But I needed her to walk into Ricardo’s with strength, not softness. Confidence, not fantasy. This was grace when what I needed was poise with a bit of punch.

+ +

So the dress stayed in the wings. It never made it onto the page. But like many of Maggie’s almost-moments, it still deserves to be seen. Because sometimes, even the wrong outfit tells us something honest about who she is underneath it all.

+ +
+
+ + +
+
+ +
+ “She wore hope in the shape of a dress. And for a moment, she almost believed it would be enough.” +
+ +
+
+
“Lace & Lager” – The First Date Dress
+ +

This was the one. The dress Maggie wore the night she finally let herself hope for something real, and got two pints of beer tipped over her for the trouble. I designed it around contradiction: soft lace sleeves clinging like whispered promises, paired with a defiant red skirt that billowed like a dare. It wasn’t subtle. It wasn’t supposed to be. It was Maggie stepping into the world not as someone surviving, but as someone choosing to be seen.

+ +

The top was reworked from a more elegant concept, too much for Ricardo’s, but perfect once grounded by the rough texture and boldness of that crumpled scarlet skirt. I loved that about her. How she blended grace with grit. The result was vulnerable and fearless all at once, which is probably why the moment hurt so much when it all went wrong.

+ +

She looked stunning that night. I remember writing that scene with a tightness in my chest, knowing exactly how much that outfit meant to her, not just as a creation, but as a risk. And seeing it ruined, soaked in lager and shame, broke my heart. But that was the point. This dress, like Maggie, deserved better. And eventually… she gets it.

+ +
+
+ + +
+
+ +
+ “It made her feel powerful… but not like herself.” +
+ +
+
+
“Velvet Resolve” – The One That Stayed Behind
+ +

This was a contender, a serious one. There was a moment when I imagined Maggie standing at the top of the stairs in this, every line of the dress perfectly composed, every eye in the restaurant turning to look. The plunging black velvet bodice, the way it folded into that crimson skirt… it was elegance incarnate. Mature. Commanding. And, in the end, just a little too much.

+ +

Because Maggie, for all her power, wasn’t trying to impress that night, not with poise. She wanted to feel beautiful, yes, but she also wanted to feel *real*. To be herself, raw edges and all. This dress was breathtaking, but it was armour. And what she needed then was something that breathed with her, not something that held her still.

+ +

But I still keep it here, in the scrapbook. Because this was the version of Maggie who might have walked into that meal pretending she wasn’t scared. The one who hid every bruise behind glamour. It didn’t make it to the page, but it came very close.

+ +
+
+ + +
+
+ +
+ “She didn’t need a scene to wear this. Just a window, and a reason to breathe.” +
+ +
+
+
“Threadbare Ghosts” – The Dress Without a Scene
+ +

This one never had a chapter. No nightclub. No first date. No dramatic spill or kiss behind a curtain. It wasn’t made for anything, and maybe that’s why I love it. Because sometimes, Maggie just exists… not as a character in motion, but as a feeling. A breath. A girl wrapped in sunlight and silence, not trying to fight or impress or survive, just being. And this is what that moment looked like in my head.

+ +

The bodice is intricate, almost antique, like something stolen from a forgotten theatre. Lace, delicate and curling like memory. Faint threads of rust red and soft bone hues bleeding into the fabric, as if it once knew passion and never quite let go. She looks like something out of time. Something haunting and utterly alive. And that’s the magic of it, she doesn’t need to move to hold you. She just needs to look up, like this, and you’re caught.

+ +

I never found the right place to write this dress in. But I never let it go, either. It stayed on my desk, on a scrap of paper, next to notes that never became dialogue. Because some images don’t need stories. They *are* the story… just quietly, beautifully, waiting.

+ +
+
+ + +
+
+ +
+ “She wore it first. Beth made it hers. But what stitched them together was never fabric.” +
+
+
+
“Summer Soft” – The Outfit They Shared
+ +

This outfit was never meant to be a showstopper. It wasn’t fire or lace or velvet. It was light, deliberately so. The white cotton skirt, simple and sun-washed, the top just delicate enough to feel like a whisper. This was the first outfit Maggie wore to Ricardo’s, when she needed to feel both presentable and herself. It wasn’t designed to turn heads… and yet it did, quietly, effortlessly. She wore it with that rare kind of grace that doesn’t try, and so becomes unforgettable.

+ +

Later, she lent it to Beth, and that’s when it truly earned its place in the story. Because clothes carry energy. They hold memory. And in that moment, Maggie wasn’t just lending an outfit. She was offering safety, trust, sisterhood before either of them even knew the word for it. Beth, wrapped in Maggie’s confidence, stepping into her own space, her own choices, it made me cry when I wrote it. Still does.

+ +

It’s not the most elaborate design in the scrapbook, not by a long shot. But maybe that’s what makes it so important. Because sometimes, what matters most isn’t how it looks… but who it becomes part of.

+ +
+
+ +
+ + +@section Meta { + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/Discovery/ScrapBook.cshtml b/CatherineLynwood/Views/Discovery/ScrapBook.cshtml new file mode 100644 index 0000000..168fd7c --- /dev/null +++ b/CatherineLynwood/Views/Discovery/ScrapBook.cshtml @@ -0,0 +1,217 @@ + +
+
+ +
+
+ +
+

Discover Scrapbook

+

+ On this page I've included some of the images that helped inspire me to write The Alpha Flame: Discovery. +

+

+ Some of them are fictional, generated by AI, others are real, both recent and archive photos. +

+

+ I find that when I'm writing I like to imagine the scene. So having a visual guide helps me tremendously. + So I might, for example, ask AI to generate an image of a luxurious restaraunt. The I would look at the result + and tweak it, until what I was looking at matches what was in my imagination. I also find it useful to do the reverse. + I might write a description of a particular location, Beth's flat was one of them, and then feed that into AI to see + if it generated what I'd described. This was really useful because it helped me work out whether there was enough detail. + My thoughts were that if AI can draw what I've described, then I'm sure you as a reader will be able to imagine something + similar. Hopefully it's worked. +

+ + +
+
+ +
+
+
The Rubery Flyover
+

+ A number of scenes in The Alpha Flame: Discovery are set, or at least start here. The Rubery flyover carries the A38 Bristol Road + down to meet the M5. It's the main road in and out of the city from the South West. Quite why the floyover exists is something of + a mystery to me. Apart from allowing traffic to pass underneath it, past "Beth's Bench", it seems to serve no purpose. It doesn't + bridge any sort of gap in the landscape. Neither does it provide access to a higher ground further along. +

+

+ Many years ago I used to live in this area and travelling underneath the flyover really gave me the creeps. As I describe in the book + there were often many unsavoury characters seated on the benches. And thre genuinely were women offering their bodies to whoever + happened to drive past. +

+
+
+ + +
+
+ +
+
+
Beth and Her Flat
+

+ In the beginning Beth's flat was even more depressing that it is described in the book. The idea of a sterotypical + early 1980s council flat was too hard to resist. However once I had developed her personality a little further it + became obvious that she would have a lot more pride in where she lived, even if she had no money. +

+

+ In reality the block of flats that I put Beth in are only two storeys on top of a row of shops. But for the + purpose of the book I made them into one of the taller blocks that can be found all over the area. +

+
+
+ + +
+
+ +
+
+
Rubery Hill Hospital
+

+ Now this place used to genuinely give me the creeps. It was built way back in the 1800s and as I say in the book, + was origonally known as "The City of Birmingham Lunatic Asylum". It was renamed many times over it's long life + but always had links to what we would call "mental health" these days. From what I have found out the only deviation + from this was during the war, when it was a hospital for injured soldiers. +

+
+
+ + +
+
+ +
+
+
Maggie in Her Jumpsuit
+

+ So, the scene where Maggie goes to Limelight and walks across the dance floor to go and say hello to Zoe and Graham. Is this what you imagined? + I doubt it, but it was what was in my mind. The original description of this outfit went on for over a page, and I think you can see why. + Unfortuantely it got severaly cut in the edit. You're probably quite thankful for that! +

+

+ But wouldn't you just love to wear it! +

+
+
+ + +
+
+ +
+
+
Ricardo's
+

+ The extremely lavish Riscrod's restaraunt went through many changes, and evloved into something more luxurious every + single time. I'm not sure this image does it justice, but I hope by my descriptions you got the feeling of the sheer + opulance within it. +

+

+ In reality Northfield never had any such restaraunt, it's simply not that sort of place. But it's nice to think that + it could have. +

+
+
+ + +
+
+ +
+
+
Beth and Her Flat
+

+ In the beginning Beth's flat was even more depressing that it is described in the book. The idea of a sterotypical + early 1980s council flat was too hard to resist. However once I had developed her personality a little further it + became obvious that she would have a lot more pride in where she lived, even if she had no money. +

+

+ In reality the block of flats that I put Beth in are only two storeys on top of a row of shops. But for the + purpose of the book I made them into one of the taller blocks that can be found all over the area. +

+
+
+ + +
+
+ +
+
+
Rubery Hill Hospital
+

+ Now this place used to genuinely give me the creeps. It was built way back in the 1800s and as I say in the book, + was origonally known as "The City of Birmingham Lunatic Asylum". It was renamed many times over it's long life + but always had links to what we would call "mental health" these days. From what I have found out the only deviation + from this was during the war, when it was a hospital for injured soldiers. +

+
+
+ +
+ + +@section Meta { + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/Home/AboutCatherineLynwood.cshtml b/CatherineLynwood/Views/Home/AboutCatherineLynwood.cshtml index 22007a8..faa3d01 100644 --- a/CatherineLynwood/Views/Home/AboutCatherineLynwood.cshtml +++ b/CatherineLynwood/Views/Home/AboutCatherineLynwood.cshtml @@ -16,7 +16,7 @@
- +
Catherin Lynwood
@@ -61,10 +61,10 @@ "@@context": "https://schema.org", "@@type": "Person", "name": "Catherine Lynwood", - "url": "https://www.catherinelynwood.com/about-catherine-lynwood", - "description": "Learn more about Catherine Lynwood, author of *The Alpha Flame*, a novel featuring romance, mystery, and family secrets.", + "url": "https://www.catherinelynwood.com", "jobTitle": "Author", - "knowsAbout": ["fiction writing", "mystery novels", "family drama"] + "knowsAbout": ["women’s fiction", "family secrets novels", "mystery"], + "knowsLanguage": "English" } } \ No newline at end of file diff --git a/CatherineLynwood/Views/Home/Index.cshtml b/CatherineLynwood/Views/Home/Index.cshtml index 92d76d6..d32db00 100644 --- a/CatherineLynwood/Views/Home/Index.cshtml +++ b/CatherineLynwood/Views/Home/Index.cshtml @@ -1,5 +1,5 @@ @{ - ViewData["Title"] = "Catherine Lynwood"; + ViewData["Title"] = "The Alpha Flame"; }
@@ -11,38 +11,33 @@
-
-
- + + +
+
+
- -
-
-

Welcome to Catherine Lynwood's World

-
- -
-

Step into the pages of The Alpha Flame, where emotions burn brightly, secrets twist through each chapter, and powerful women shape their own destinies. As a debut novelist, Catherine Lynwood invites you to experience a story crafted with depth, grit, and heart—a journey that pulls you into the lives of characters who refuse to live within anyone else’s lines.

-
- -
-

In The Alpha Flame, readers will meet Maggie Grant, a woman whose fierce intelligence and subtle dominance lead her on a thrilling path through 1980s Britain. Set against a backdrop of mystery and romance, Maggie’s story delves into the complexities of family, the weight of secrets, and the power of self-discovery. From the streets of Birmingham to quiet English countrysides, Catherine weaves a narrative that is as provocative as it is poignant.

-
- -
- Read The Alpha Flame Blog +
+

The Alpha Flame: Discovery

+

Some girls survive. Others set the world on fire.

+

+ 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, The Alpha Flame: Discovery is a story of sisterhood, survival, and the power of fire to both destroy and redeem. +

+ +

+ The Alpha Flame: Discovery, writen by Catherine Lynwood, 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 Reckoning (Spring 2026) and concludes with Redemption (Autumn 2026). + Learn more about the full trilogy on the Alpha Flame series page. +

-
-

Catherine writes with a keen sensitivity to the struggles and triumphs of women who navigate love, loyalty, and identity on their own terms. The Alpha Flame is not simply a romance or a thriller; it’s an exploration of strength, vulnerability, and the desire to be fully seen and heard. Each chapter unfolds with rich detail, bringing the 1980s to life in a way that feels both timeless and deeply personal.

-
- -
-

Whether you’re here to discover more about Catherine's debut or to explore the upcoming projects she’s hinted at, welcome. This is a space for stories that challenge convention and celebrate resilience. Follow along as Catherine Lynwood shares updates, reflections, and glimpses into the worlds and characters she is passionate about bringing to life.

-
+ + @section Meta { @@ -75,4 +70,53 @@ "knowsLanguage": "English" } + + } \ No newline at end of file diff --git a/CatherineLynwood/Views/Home/Privacy.cshtml b/CatherineLynwood/Views/Home/Privacy.cshtml new file mode 100644 index 0000000..e63dbfd --- /dev/null +++ b/CatherineLynwood/Views/Home/Privacy.cshtml @@ -0,0 +1,55 @@ +
+

Mailing List and Reader Access Data

+ +

+ We respect your privacy and are committed to protecting your personal data. This section explains how we handle the information you may provide when accessing bonus content on this site. +

+ +

What We Collect

+

+ When you enter a word from your physical copy of a Catherine Lynwood book to unlock extras, we store a small amount of session data to determine what content you can access. This includes: +

+
    +
  • Your access level (based on the edition of the book)
  • +
  • The book(s) you are entitled to access
  • +
+

+ When you choose to join our mailing list, we may also collect the following: +

+
    +
  • Your email address (optional)
  • +
  • + Your selected communication preferences: +
      +
    • Updates about The Alpha Flame trilogy
    • +
    • Access to bonus material and digital extras
    • +
    • News about future books by Catherine Lynwood
    • +
    +
  • +
+

+ A single cookie (MailingListPrompted=true) is set to ensure we only ask once. +

+ +

How We Use Your Information

+
    +
  • To give you access to content appropriate for your book and edition
  • +
  • To email you with the types of updates you selected, and nothing else
  • +
  • To avoid re-prompting you unnecessarily for mailing list opt-in
  • +
+

+ We do not use your data for advertising, do not sell your data, and do not share your email address with third parties. +

+ +

Your Rights

+
    +
  • You can unsubscribe from emails at any time using the link provided in each message.
  • +
  • You can request to view or delete the information we hold about you by contacting us directly.
  • +
  • We retain minimal data only as necessary to manage access and communications.
  • +
+ +

+ For more information about your rights under the General Data Protection Regulation (GDPR), please visit + www.gov.uk/data-protection. +

+
diff --git a/CatherineLynwood/Views/Publishing/Index.cshtml b/CatherineLynwood/Views/Publishing/Index.cshtml new file mode 100644 index 0000000..a8f1047 --- /dev/null +++ b/CatherineLynwood/Views/Publishing/Index.cshtml @@ -0,0 +1,163 @@ +@{ + ViewData["Title"] = "Catherine Lynwood Publishing"; +} + +
+
+ +
+
+ +
+
+

Catherine Lynwood Publishing

+

The official imprint of author Catherine Lynwood

+
+
+ +
+
+
+

About the Imprint

+

Catherine Lynwood Publishing is the registered trading name under which Catherine Lynwood independently publishes her written works. Established in the United Kingdom as a sole trader business, this imprint allows full control over every aspect of the creative and publishing process.

+

From editing and layout to cover design and distribution, each book released under this imprint is crafted with care, passion, and an unwavering focus on quality storytelling.

+
+ +
+

What We Do

+
    +
  • Publish and manage the Alpha Flame Trilogy and future titles
  • +
  • Oversee all design, layout, and editorial decisions
  • +
  • Register and manage ISBNs and metadata
  • +
  • Coordinate print and eBook distribution via IngramSpark, Amazon, and other platforms
  • +
  • Offer exclusive editions and extras via this website
  • +
+
+ +
+

Current Titles

+

The Alpha Flame: Discovery (Book One of the Alpha Flame Trilogy)

+
    +
  • Available in hardback, paperback, eBook, and Amazon-exclusive editions
  • +
  • More titles coming soon
  • +
+
+ +
+

Publishing Philosophy

+

At Catherine Lynwood Publishing, we believe that independent publishing can offer the same exceptional quality as traditional houses, with greater creative freedom. Every detail matters: from the emotional weight of the story to the typography, layout, and binding.

+

Our goal is to deliver books that not only tell powerful stories but look and feel beautiful in your hands.

+
+ +
+

For Retailers & Libraries

+

All titles under this imprint are registered with ISBNs and distributed through reputable global networks. If you are a bookshop, library, or distributor and would like to stock our titles or learn more about upcoming releases, please get in touch.

+

Contact: catherine@catherinelynwood.com

+
+ +
+

Legal Information

+
    +
  • Trading Name: Catherine Lynwood Publishing
  • +
  • Business Type: Sole Trader
  • +
  • Established: 2025
  • +
  • Country: United Kingdom
  • +
+
+
+
+ +@section Meta{ + + + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/Shared/AccessDenied.cshtml b/CatherineLynwood/Views/Shared/AccessDenied.cshtml new file mode 100644 index 0000000..21704f5 --- /dev/null +++ b/CatherineLynwood/Views/Shared/AccessDenied.cshtml @@ -0,0 +1,17 @@ +@{ + ViewData["Title"] = "Access Denied"; +} + +
+

Access Denied

+

Sorry, you don’t have permission to view this content.

+ +

+ If you believe this is an error, please verify your book again.
+ Or return to the Extras home page. +

+ +
+ Access Denied +
+
diff --git a/CatherineLynwood/Views/Shared/Components/BlogCommentComponent/Default.cshtml b/CatherineLynwood/Views/Shared/Components/BlogCommentComponent/Default.cshtml index 9f85a43..5153d9d 100644 --- a/CatherineLynwood/Views/Shared/Components/BlogCommentComponent/Default.cshtml +++ b/CatherineLynwood/Views/Shared/Components/BlogCommentComponent/Default.cshtml @@ -48,7 +48,7 @@

Leave a Comment

In invite you to leave comments regarding this blog post. As you can see I ask that you give me your name and email address, as well as your age and sex. This is so I can better understand my audience and tailor my content to suit your needs. I will never share your information with anyone else. I look forward to hearing from you. - Please note that I may email you and ask for a reply before publishng your comment. This is to ensure that I am not publishing spam comments. + Please note that I may email you and ask for a reply before publishing your comment. This is to ensure that I am not publishing spam comments.
@@ -71,10 +71,13 @@
@@ -105,7 +108,7 @@

Please Note

- By posting a comment, you agree to allow us to contact you regarding your comment. Additionally, you consent to receive occasional updates, blog posts, and news about our latest content and book releases. You may opt out of these communications at any time. + By posting a comment, you agree to allow us to contact you regarding your comment.

diff --git a/CatherineLynwood/Views/Shared/_Layout.cshtml b/CatherineLynwood/Views/Shared/_Layout.cshtml index dd54837..b73bef9 100644 --- a/CatherineLynwood/Views/Shared/_Layout.cshtml +++ b/CatherineLynwood/Views/Shared/_Layout.cshtml @@ -9,6 +9,20 @@ + + + @@ -66,7 +80,7 @@ The Alpha Flame @@ -87,27 +101,34 @@
- + + @RenderSection("Scripts", required: false) diff --git a/CatherineLynwood/Views/TheAlphaFlame/Beth.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Beth.cshtml index 7ae5871..f50bd3c 100644 --- a/CatherineLynwood/Views/TheAlphaFlame/Beth.cshtml +++ b/CatherineLynwood/Views/TheAlphaFlame/Beth.cshtml @@ -25,6 +25,15 @@
+
+
+ +
+
Watch Beth tell you about her story.
+
+
+ + +

Beth Fletcher

I love the character of Beth. To me she's the most interesting of them all. Her harrowing back story and life of poverty and squaller shapes her character, yet through it all she still manages to maintain her personal standards.'

Overview

@@ -123,6 +135,19 @@ + + + + + + + + + + + + + } \ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/Chapter2.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Chapter2.cshtml index ed670f3..ebca7b5 100644 --- a/CatherineLynwood/Views/TheAlphaFlame/Chapter2.cshtml +++ b/CatherineLynwood/Views/TheAlphaFlame/Chapter2.cshtml @@ -8,6 +8,7 @@ @@ -37,9 +38,12 @@
+

+ Listen to Maggie narrating Chapter 2 - The Last Lesson, +

@@ -96,5 +100,56 @@ twitter-player-width="480" twitter-player-height="80" /> + } \ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/Discovery.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Discovery.cshtml new file mode 100644 index 0000000..07dcb95 --- /dev/null +++ b/CatherineLynwood/Views/TheAlphaFlame/Discovery.cshtml @@ -0,0 +1,230 @@ +@{ + ViewData["Title"] = "The Alpha Flame: Discovery"; +} + +
+
+ +
+
+ + +
+ +
+
+
+ +
+

The Front Cover

+

This is the final front cover of The Alpha Flame: Discovery. It features Maggie stood outside the derelict Rubery Hill Hospital.

+
+
+
+
+ + +
+
+
+
+

The Alpha Flame

+
+
+
+
+ +
+
+ +
+ +
+

+ Listen to Catherine telling you about The Alpha Flame: Discovery +

+
+
+
+
+
+ + Buy on Amazon + +

Also available on your local Amazon store.

+
+
+
+ + + +

Synopsis

+

The Alpha Flame is an unflinching and deeply emotional story of resilience, love, and survival, set against the vibrant yet tumultuous backdrop of 1983. Through the intersecting lives of two heroines, it delves into the extremes of human suffering and the boundless power of the human spirit to endure, adapt, and rise.

+

For Beth, the world is a cold and unforgiving place. Devastation strikes in a single moment, leaving her isolated, shattered, and vulnerable. Alone in the bleak shadows of a city that offers neither refuge nor redemption, she is forced to navigate a relentless cycle of desperation and despair. Every step of her journey tests the limits of her endurance, pushing her into harrowing situations where survival feels like a hollow victory. Beth’s existence is marked by loss, betrayal, and an almost suffocating loneliness that threatens to consume her entirely. Yet, even in the darkest corners of her ordeal, a fragile ember of defiance smoulders within her, a quiet, stubborn refusal to let the world destroy her completely.

+

Maggie, by contrast, is a force of nature, a woman who thrives on her unshakable drive and an unrelenting belief in her own power. Behind her fiery red hair and disarming charm lies a storm of determination and ferocity. Maggie doesn’t just live; she races through life, fuelled by a need for speed and the thrill of freedom. Her Triumph TR6 isn’t just a car; it’s an extension of her spirit, sleek, powerful, and unapologetically bold. On the open road, with the engine roaring and the world blurring past her, she feels invincible. But Maggie’s intensity doesn’t stop at the wheel. Her relationships burn just as brightly. As a lover, she is dominant, passionate, and unafraid to embrace her darker desires. While fiercely loving and loyal, Maggie is also formidable; crossing her isn’t a mistake anyone makes twice.

+

When fate brings Beth and Maggie together, their connection is explosive, a union of two polar opposites that burns with both tenderness and raw power. For Beth, Maggie represents a lifeline, a reminder that love and trust still exist, even in a world that has betrayed her at every turn. For Maggie, Beth awakens a fierce protectiveness and vulnerability she’s rarely allowed herself to feel. Together, they ignite a flame that challenges them to confront their own fears, desires, and limitations.

+

Set against the kaleidoscope of 1983, where synthesised anthems provide a pulsing soundtrack and the streets are alive with the bold styles and rebellious energy of the decade, their story unfolds in a city teeming with danger and intrigue. From high-speed chases along winding roads to dimly lit clubs and desolate alleyways, the heroines’ journey is a visceral exploration of survival and freedom. The neon haze of the era contrasts sharply with the stark realities they face, painting a vivid picture of a world where strength and vulnerability coexist.

+

As secrets surface and danger tightens its grip, Beth and Maggie must confront not only the challenges around them but the truths within themselves. Their bond is tested by betrayal, desire, and the shadows of their pasts, but through it all, their flame burns brighter, illuminating their courage and the unbreakable spirit of two heroines determined to rewrite their fates.

+

At its heart, The Alpha Flame is a story of survival, passion, and empowerment. It explores the devastating lows and triumphant highs of life with unflinching honesty, capturing the raw power of human connection against the gritty, vibrant backdrop of an unforgettable era. With its blend of drama, intensity, and unapologetic emotion, this is a story that will leave its mark long after the final frame.

+ + +
+
+
+
+
+ + +
+

Chapter Previews

+
+
+
+ + + +
+

Chapter 1: Drowning in Silence - Beth

+

Beth returns home to find her mother lifeless in the bath...

+ +
+
+
+
+
+ + + +
+

Chapter 2: The Last Lesson - Maggie

+

On Christmas Eve, Maggie nervously heads out for her driving test...

+ +
+
+
+
+
+ + + +
+

Meet the Characters

+

Dive into the vibrant world of The Alpha Flame and discover the unforgettable cast of characters that bring this story to life.

+

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.

+

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.

+ + +
+
+
+
+
+ + +@section Scripts { + + +} + + +@section Meta{ + + + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/Extras.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Extras.cshtml new file mode 100644 index 0000000..501d9f4 --- /dev/null +++ b/CatherineLynwood/Views/TheAlphaFlame/Extras.cshtml @@ -0,0 +1,180 @@ +@{ + ViewData["Title"] = "Extras"; + + int? accessLevel = Context.Session.GetInt32("BookAccessLevel"); + int? accessBook = Context.Session.GetInt32("BookAccessMax"); +} + +
+
+ +
+
+ +
+

Your Exclusive Extras

+ + @if (accessLevel >= 1) + { +
+
+
+
Epilogue
+

Immerse yourself in the Eplilogue to The Alpha Flame: Discovery. Join the team as they relax for a quite drink at the Barnt Green Inn

+ Read or Listen +
+
+ +
+
+
Discovery Scrap Book
+

Take a look at my image scrapbook for The Alpha Flame: Discovery. View the images I used for inspiration when writing the various scenes within the book.

+ View Scrapbook +
+
+ +
+
+
Rubery Hill Photo Archive
+

Explore historical photos and floor plans of the real Rubery Hill Hospital, the eerie inspiration behind key scenes.

+ Explore +
+
+ +
+
+
Scrapbook: Maggie’s Designs
+

Flip through Maggie’s sketches, fashion notes, and photos from her original designs – including the infamous red skirt.

+ View Scrapbook +
+
+ +
+ } + else if (accessLevel >= 2) + { +
+
+
+
Epilogue
+

Immerse yourself in the Eplilogue to The Alpha Flame: Discovery. Join the team as they relax for a quite drink at the Barnt Green Inn

+ Read or Listen +
+
+ +
+
+
Discovery Scrap Book
+

Take a look at my image scrapbook for The Alpha Flame: Discovery. View the images I used for inspiration when writing the various scenes within the book.

+ View Scrapbook +
+
+ +
+
+
Rubery Hill Photo Archive
+

Explore historical photos and floor plans of the real Rubery Hill Hospital, the eerie inspiration behind key scenes.

+ Explore +
+
+ +
+
+
Scrapbook: Maggie’s Designs
+

Flip through Maggie’s sketches, fashion notes, and photos from her original designs – including the infamous red skirt.

+ View Scrapbook +
+
+ +
+ } + else if (accessLevel >= 3) + { +
+
+
+
Epilogue
+

Immerse yourself in the Eplilogue to The Alpha Flame: Discovery. Join the team as they relax for a quite drink at the Barnt Green Inn

+ Read or Listen +
+
+ +
+
+
Discovery Scrap Book
+

Take a look at my image scrapbook for The Alpha Flame: Discovery. View the images I used for inspiration when writing the various scenes within the book.

+ View Scrapbook +
+
+ +
+
+
Rubery Hill Photo Archive
+

Explore historical photos and floor plans of the real Rubery Hill Hospital, the eerie inspiration behind key scenes.

+ Explore +
+
+ +
+
+
Scrapbook: Maggie’s Designs
+

Flip through Maggie’s sketches, fashion notes, and photos from her original designs – including the infamous red skirt.

+ View Scrapbook +
+
+ +
+ } + + + + +
+ +@section Meta{ + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/FrontCover.cshtml b/CatherineLynwood/Views/TheAlphaFlame/FrontCover.cshtml deleted file mode 100644 index da72293..0000000 --- a/CatherineLynwood/Views/TheAlphaFlame/FrontCover.cshtml +++ /dev/null @@ -1,37 +0,0 @@ -@{ - ViewData["Title"] = "The Alpha Flame | Front Cover"; -} - -
-
- -
-
- -
-
-
-
- -
-

Front Cover Draft

-

- I've had a few different versions of my front cover, and I'm a little undecided, however I'm now favouring the more dramatic version. -

-

- The girl in the image is a representation of the main character, Maggie, and the flames are a metaphor for the fire that consumes her life, and also a more literal reference to her hair. -

-

- There is also a hint towards one of the more dramatic scenes I'm proposing nearer to the end of my book. I don't want to give too much away, but even though Maggie looks kind of delicate and dainty, she's a force to be reckoned with, and woe betide anyone who crosses her on her quest. -

-
-
-
-
-
\ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/Index.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Index.cshtml index ae4b044..98d2237 100644 --- a/CatherineLynwood/Views/TheAlphaFlame/Index.cshtml +++ b/CatherineLynwood/Views/TheAlphaFlame/Index.cshtml @@ -12,114 +12,124 @@
-
-
+
+
+

The Alpha Flame Trilogy

+

+ A powerful series of love, trauma, discovery and transformation. + Follow Maggie and Beth as they navigate a world full of secrets, shadows, and the flicker of hope that refuses to die. + Across three unforgettable books, the Alpha Flame burns ever brighter. +

+
- -
-

Book Previews

-
- -
-
- - + +
+
+
+
+
+ + -
-

The Front Cover

-

In the quieter moments when I'm not writing I've been spending some time working on the cover of my book. It's definitely early days at the moment, but you can take a look at a draft version of the front cover if you wish.'

- -
-
- -
-
- - - -
-

Chapter 1: Drowning in Silence - Beth

-

Beth returns home to find her mother lifeless in the bath, an empty bottle beside her. Overwhelmed by grief and disbelief, she wrestles with feelings of abandonment and anger as her world shatters around her. Left alone at just sixteen, Beth faces the bleak realities of life without her mother, including navigating the cold and impersonal system of social services. When her estranged aunt briefly steps in before leaving her completely alone, Beth is forced to make a desperate decision—to run away and forge her own path, no matter the cost.

- -
-
-
- -
-
- - - -
-

Chapter 2: The Last Lesson - Maggie

-

On Christmas Eve, Maggie nervously heads out for her driving test, determined to succeed. Dressed to impress and brimming with playful confidence, she charms her instructor Colin and even turns heads at the test center. However, an unexpected incident involving a child running into the road tests her composure and skill. Maggie’s quick thinking earns her a perfect pass, and she celebrates with her family and best friend, Rosie. Driving her newly restored Triumph TR6 for the first time, Maggie revels in her freedom but can’t shake the haunting image of a lonely girl she spots under a flyover, sparking a lingering sense of unease.

- -
-
-
-
-
-
- - - -
-
-

Meet the Characters

-
-

Dive into the vibrant world of The Alpha Flame and discover the unforgettable cast of characters that bring this story to life.

- -

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.

- -

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.

- -

Not everyone is a friend, though—Sophie brings tension and drama with her prickly demeanor, and Rick, the dark and dangerous antagonist, keeps the stakes high and the tension palpable.

- -

Find out what makes them tick, what drives their actions, and what secrets they’re hiding. Who will you root for, and who will you love to hate? Discover it all in The Alpha Flame.

+
+
+

The Alpha Flame: Discovery

+

Some girls survive. Others set the world on fire.

+

+ Maggie didn’t go looking for trouble. But when she found Beth—bruised, broken, and terrified—she couldn’t walk away. +

+

+ What begins as a rescue becomes something far more dangerous. Drawn into Beth’s world, Maggie is forced to confront a hidden undercurrent of control, abuse, and corruption that runs deeper than she ever imagined. A seedy underworld of silence and survival where nothing is as it seems, and walking away is no longer an option. +

+

+ As truths unravel and pasts collide, Maggie must decide who she is, who she trusts, and how far she's willing to go for someone she barely knows… yet feels inexplicably bound to. +

+

+ The Alpha Flame: Discovery is a gritty, emotionally charged thriller about trauma, loyalty, and fire—forged in pain, and burning with truth. +

+ - +
+ +
+
+
+
+
+ +
+
+
+ Coming Spring 2026 +
+
+ +
+
+
+
The Alpha Flame: Reckoning
+

+ As truths begin to unravel, *The Alpha Flame: Reckoning* plunges deeper into the aftermath of choices made and sins buried. + The cost of survival is rising, and the ghosts of the past demand payment in full. +

+

+ With loyalties tested and new threats circling, the flame that once brought light now threatens to consume. Darker, more daring, and laced with tension, the second book refuses to flinch from the consequences of truth. +

+ +
-
+
+
+ +
+
+
+ Coming Autumn 2026 +
+
+ +
+
+
+
The Alpha Flame: Redemption
+

+ Every fire must either burn out or forge something stronger. *The Alpha Flame: Redemption* is a story of confronting what’s been lost, what’s been taken, and what might still be saved. +

+

+ As the final pieces fall into place, the women at the heart of the flame must decide if healing is possible—or if some wounds are meant to stay open. Fierce, emotional, and defiantly human, this final chapter brings the trilogy to a powerful close. +

+ + +
+
+
+
+
- @section Meta { - - - - - - - + .placeholder-blur:hover { + filter: blur(2px); + opacity: 0.9; + } + } \ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/Index2.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Index2.cshtml new file mode 100644 index 0000000..c5fa980 --- /dev/null +++ b/CatherineLynwood/Views/TheAlphaFlame/Index2.cshtml @@ -0,0 +1,167 @@ +@{ + ViewData["Title"] = "The Alpha Flame"; +} + +
+
+ +
+
+
+
+
+
+
+
+
+

The Alpha Flame

+
+
+
+ +
+
+
+

Synopsis

+

The Alpha Flame is an unflinching and deeply emotional story of resilience, love, and survival, set against the vibrant yet tumultuous backdrop of 1983. Through the intersecting lives of two heroines, it delves into the extremes of human suffering and the boundless power of the human spirit to endure, adapt, and rise.

+

For Beth, the world is a cold and unforgiving place. Devastation strikes in a single moment, leaving her isolated, shattered, and vulnerable. Alone in the bleak shadows of a city that offers neither refuge nor redemption, she is forced to navigate a relentless cycle of desperation and despair. Every step of her journey tests the limits of her endurance, pushing her into harrowing situations where survival feels like a hollow victory. Beth’s existence is marked by loss, betrayal, and an almost suffocating loneliness that threatens to consume her entirely. Yet, even in the darkest corners of her ordeal, a fragile ember of defiance smoulders within her—a quiet, stubborn refusal to let the world destroy her completely.

+

Maggie, by contrast, is a force of nature—a woman who thrives on her unshakable drive and an unrelenting belief in her own power. Behind her fiery red hair and disarming charm lies a storm of determination and ferocity. Maggie doesn’t just live; she races through life, fuelled by a need for speed and the thrill of freedom. Her Triumph TR6 isn’t just a car; it’s an extension of her spirit—sleek, powerful, and unapologetically bold. On the open road, with the engine roaring and the world blurring past her, she feels invincible. But Maggie’s intensity doesn’t stop at the wheel. Her relationships burn just as brightly. As a lover, she is dominant, passionate, and unafraid to embrace her darker desires. While fiercely loving and loyal, Maggie is also formidable; crossing her isn’t a mistake anyone makes twice.

+

When fate brings Beth and Maggie together, their connection is explosive—a union of two polar opposites that burns with both tenderness and raw power. For Beth, Maggie represents a lifeline, a reminder that love and trust still exist, even in a world that has betrayed her at every turn. For Maggie, Beth awakens a fierce protectiveness and vulnerability she’s rarely allowed herself to feel. Together, they ignite a flame that challenges them to confront their own fears, desires, and limitations.

+

Set against the kaleidoscope of 1983—where synthesised anthems provide a pulsing soundtrack and the streets are alive with the bold styles and rebellious energy of the decade—their story unfolds in a city teeming with danger and intrigue. From high-speed chases along winding roads to dimly lit clubs and desolate alleyways, the heroines’ journey is a visceral exploration of survival and freedom. The neon haze of the era contrasts sharply with the stark realities they face, painting a vivid picture of a world where strength and vulnerability coexist.

+

As secrets surface and danger tightens its grip, Beth and Maggie must confront not only the challenges around them but the truths within themselves. Their bond is tested by betrayal, desire, and the shadows of their pasts, but through it all, their flame burns brighter, illuminating their courage and the unbreakable spirit of two heroines determined to rewrite their fates.

+

At its heart, The Alpha Flame is a story of survival, passion, and empowerment. It explores the devastating lows and triumphant highs of life with unflinching honesty, capturing the raw power of human connection against the gritty, vibrant backdrop of an unforgettable era. With its blend of drama, intensity, and unapologetic emotion, this is a story that will leave its mark long after the final frame.

+ + +
+
+ +
+
+
+ + +
+

Book Previews

+
+ +
+
+ + + +
+

The Front Cover

+

In the quieter moments when I'm not writing I've been spending some time working on the cover of my book. It's definitely early days at the moment, but you can take a look at a draft version of the front cover if you wish.'

+ +
+
+
+ +
+
+ + + +
+

Chapter 1: Drowning in Silence - Beth

+

Beth returns home to find her mother lifeless in the bath, an empty bottle beside her. Overwhelmed by grief and disbelief, she wrestles with feelings of abandonment and anger as her world shatters around her. Left alone at just sixteen, Beth faces the bleak realities of life without her mother, including navigating the cold and impersonal system of social services. When her estranged aunt briefly steps in before leaving her completely alone, Beth is forced to make a desperate decision—to run away and forge her own path, no matter the cost.

+ +
+
+
+ +
+
+ + + +
+

Chapter 2: The Last Lesson - Maggie

+

On Christmas Eve, Maggie nervously heads out for her driving test, determined to succeed. Dressed to impress and brimming with playful confidence, she charms her instructor Colin and even turns heads at the test center. However, an unexpected incident involving a child running into the road tests her composure and skill. Maggie’s quick thinking earns her a perfect pass, and she celebrates with her family and best friend, Rosie. Driving her newly restored Triumph TR6 for the first time, Maggie revels in her freedom but can’t shake the haunting image of a lonely girl she spots under a flyover, sparking a lingering sense of unease.

+ +
+
+
+
+
+
+ + + +
+
+

Meet the Characters

+
+

Dive into the vibrant world of The Alpha Flame and discover the unforgettable cast of characters that bring this story to life.

+ +

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.

+ +

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.

+ +

Not everyone is a friend, though—Sophie brings tension and drama with her prickly demeanor, and Rick, the dark and dangerous antagonist, keeps the stakes high and the tension palpable.

+ +

Find out what makes them tick, what drives their actions, and what secrets they’re hiding. Who will you root for, and who will you love to hate? Discover it all in The Alpha Flame.

+
+ +
+
+
+
+
+
+
+ + +@section Meta { + + + + + + + + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/CatherineLynwood/Views/TheAlphaFlame/Maggie.cshtml b/CatherineLynwood/Views/TheAlphaFlame/Maggie.cshtml index 9eece9e..fe00075 100644 --- a/CatherineLynwood/Views/TheAlphaFlame/Maggie.cshtml +++ b/CatherineLynwood/Views/TheAlphaFlame/Maggie.cshtml @@ -24,6 +24,15 @@
+
+
+ +
+
Watch Maggie tell you about her story.
+
+
-

Overview

+ + + +

Maggie Grant is the fiery and complex heroine of The Alpha Flame:. With her striking red hair, sharp wit, and magnetic personality, she is a force to be reckoned with. Maggie’s journey is one of self-discovery, resilience, and dominance, as she navigates a world full of challenges, betrayal, and passion.

Born and raised in a modest town, Maggie’s life takes unexpected turns that shape her into the strong woman she becomes. Her natural charisma and keen intelligence make her a leader in any room, but it’s her unwavering determination that sets her apart. Maggie doesn’t just survive—she thrives, finding ways to take control of situations that would leave others defeated.

@@ -162,6 +174,18 @@ + + + + + + + + + + + +