[{"data":1,"prerenderedAt":4106},["ShallowReactive",2],{"blog-paginated-count":3,"blog-paginated-20":4,"blog-paginated-cats":3460},640,[5,248,374,569,710,838,929,1042,2212,2326,2528,2717,3046,3151,3261],{"id":6,"title":7,"author":8,"body":11,"category":224,"date":225,"description":226,"extension":227,"featured":228,"image":229,"keywords":230,"meta":236,"navigation":237,"path":238,"readTime":239,"seo":240,"stem":241,"tags":242,"__hash__":247},"blog/blog/military-records-genealogy.md","Military Records in Genealogy: Service, Pension, and Muster Rolls",{"name":9,"bio":10},"James Ross Jr.","Strategic Systems Architect & Enterprise Software Developer",{"type":12,"value":13,"toc":212},"minimark",[14,19,23,26,29,33,36,44,50,57,63,67,70,73,79,85,91,103,109,112,116,119,122,125,129,140,143,146,154,158,164,170,181,184,187,191],[15,16,18],"h2",{"id":17},"why-military-records-matter","Why Military Records Matter",[20,21,22],"p",{},"Military records are some of the most detailed and personal documents any genealogist will encounter. A parish register gives you a name and a date. A census gives you a household snapshot. But a military pension file can give you a life story: where a man was born, when he enlisted, where he served, what wounds he suffered, who his wife was, when and where his children were born, what his health was like in old age, and how he died.",[20,24,25],{},"The reason is simple. Military bureaucracies need information to manage personnel, and pension systems need information to verify claims. The result is a paper trail that can span decades and contain dozens of documents -- enlistment papers, muster rolls, hospital records, discharge papers, pension applications, supporting affidavits, and correspondence.",[20,27,28],{},"For American genealogy especially, military records are indispensable. From the Revolutionary War through the twentieth century, military service generated records that are often the richest source of family information available for a particular ancestor.",[15,30,32],{"id":31},"service-records","Service Records",[20,34,35],{},"Service records -- also called compiled military service records (CMSRs) for US conflicts before World War I -- document an individual's military career: enlistment date, unit assignments, promotions, hospitalizations, disciplinary actions, and discharge.",[20,37,38,39,43],{},"For the ",[40,41,42],"strong",{},"Revolutionary War"," (1775-1783), service records are fragmentary but significant. Continental Army records, state militia records, and bounty land warrants survive for many soldiers. The National Archives holds compiled service records and pension files.",[20,45,38,46,49],{},[40,47,48],{},"Civil War"," (1861-1865), service records exist for approximately 6.3 million Union and Confederate soldiers. The compiled military service records include muster rolls, casualty sheets, prisoner of war records, and hospital records. Union records are held at NARA; Confederate records are split between NARA and state archives.",[20,51,52,53,56],{},"For ",[40,54,55],{},"World War I",", most US Army service records were destroyed in the 1973 fire at the National Personnel Records Center in St. Louis. Approximately 80 percent of Army records for personnel discharged between 1912 and 1964 were lost. This is one of the great archival disasters of American history. Draft registration cards, however, survive for virtually all men aged 18-45 in 1917-1918, providing name, birth date, birthplace, physical description, occupation, and next of kin.",[20,58,52,59,62],{},[40,60,61],{},"World War II",", service records are available through NARA (for deceased veterans) and through a request process (for living veterans or their next of kin). The WWII Army Enlistment Records database, available through NARA, provides a searchable index of approximately 9 million enlistment records.",[15,64,66],{"id":65},"pension-records","Pension Records",[20,68,69],{},"Pension files are the genealogist's treasure. They contain far more information than service records because the pension application process required the veteran (or his widow) to prove identity, service, disability, and family relationships.",[20,71,72],{},"A typical Civil War pension file contains:",[20,74,75,78],{},[40,76,77],{},"The application",": Name, age, residence, unit, dates of service, nature of disability or grounds for pension.",[20,80,81,84],{},[40,82,83],{},"Supporting affidavits",": Statements from fellow soldiers, neighbors, and physicians confirming the veteran's identity and claims. These affidavits often contain detailed narratives of wartime experiences.",[20,86,87,90],{},[40,88,89],{},"Surgeon's certificates",": Medical examinations documenting the veteran's health, wounds, and physical condition -- sometimes in extraordinary detail.",[20,92,93,96,97,102],{},[40,94,95],{},"Marriage and family documentation",": When a widow applied for a pension, she had to prove her marriage and her husband's death. The file often contains ",[98,99,101],"a",{"href":100},"/blog/parish-registers-family-history","marriage certificates",", family Bible pages, birth records of children, and statements from witnesses to the marriage.",[20,104,105,108],{},[40,106,107],{},"Correspondence",": Letters between the veteran, the Pension Bureau, attorneys, and others. These letters sometimes contain personal details that appear in no other record.",[20,110,111],{},"Revolutionary War pension files, available through Fold3 and FamilySearch, are similarly rich. The pension applications submitted in the early nineteenth century often contain detailed narratives of service, recorded decades after the events, providing firsthand accounts of the war.",[15,113,115],{"id":114},"muster-rolls-and-unit-records","Muster Rolls and Unit Records",[20,117,118],{},"Muster rolls -- the periodic counts of a unit's personnel -- document who was present for duty, who was absent, and why. They are particularly valuable for tracking an ancestor's movements during wartime.",[20,120,121],{},"For the Civil War, muster rolls were typically compiled every two months. Combined with regimental histories (many of which have been published), they allow you to follow a soldier through his unit's campaigns, knowing where he was at specific dates and what battles his unit fought.",[20,123,124],{},"Unit records -- order books, morning reports, after-action reports -- are held at NARA and some have been digitized. Regimental histories, published by veteran organizations in the decades after the war, often include rosters of personnel with biographical details gathered from surviving members.",[15,126,128],{"id":127},"british-and-scottish-military-records","British and Scottish Military Records",[20,130,131,132,135,136,139],{},"For researchers with British or Scottish ancestry, military records are held primarily at ",[40,133,134],{},"The National Archives"," (Kew) and the ",[40,137,138],{},"National Records of Scotland",".",[20,141,142],{},"British Army service records for World War I (the \"burnt documents\" and \"unburnt documents\" in series WO 363 and WO 364) survive for approximately 40 percent of soldiers who served. The rest were destroyed by German bombing in 1940. The surviving records have been digitized and are available through Ancestry and Findmypast.",[20,144,145],{},"For earlier periods, the records are more scattered. Muster rolls and pay lists for the British Army survive from the eighteenth century. Chelsea Hospital pension records (for army pensioners) and Greenwich Hospital records (for naval pensioners) contain detailed personal information.",[20,147,148,149,153],{},"Scottish regimental records -- the Black Watch, the Seaforth Highlanders, the Gordon Highlanders, and others -- are held at the National Records of Scotland and regimental museums. For ",[98,150,152],{"href":151},"/blog/highland-clearances-clan-ross-diaspora","Highland Scots"," who served in the British Army (and many did, particularly after the Clearances removed other options), these records can provide detailed biographical information.",[15,155,157],{"id":156},"getting-started","Getting Started",[20,159,160,163],{},[40,161,162],{},"NARA"," (archives.gov) is the starting point for US military records. Many records are available online through Fold3, Ancestry, and FamilySearch. Physical records can be requested by mail or in person at NARA facilities.",[20,165,166,169],{},[40,167,168],{},"The National Personnel Records Center"," (NPRC) in St. Louis handles requests for twentieth-century service records using Standard Form 180.",[20,171,172,175,176,180],{},[40,173,174],{},"Fold3.com"," (a subsidiary of Ancestry) specializes in military records and has extensive digitized collections of service records, ",[98,177,179],{"href":178},"/blog/census-records-genealogy","pension files",", and unit records.",[20,182,183],{},"Military records require patience -- pension files can run to hundreds of pages, and the handwriting ranges from legible to illegible. But the reward is a depth of detail that no other genealogical source can match. In a pension file, you do not just find your ancestor. You meet him.",[185,186],"hr",{},[15,188,190],{"id":189},"related-articles","Related Articles",[192,193,194,200,206],"ul",{},[195,196,197],"li",{},[98,198,199],{"href":178},"Census Records: Snapshots of Your Ancestors' Lives",[195,201,202],{},[98,203,205],{"href":204},"/blog/immigration-records-research","Immigration Records: Tracing Ancestors Across the Atlantic",[195,207,208],{},[98,209,211],{"href":210},"/blog/family-history-documentary-research","Documentary Research: Building a Family History from Primary Sources",{"title":213,"searchDepth":214,"depth":214,"links":215},"",3,[216,218,219,220,221,222,223],{"id":17,"depth":217,"text":18},2,{"id":31,"depth":217,"text":32},{"id":65,"depth":217,"text":66},{"id":114,"depth":217,"text":115},{"id":127,"depth":217,"text":128},{"id":156,"depth":217,"text":157},{"id":189,"depth":217,"text":190},"Heritage","2026-01-25","Military records are among the richest genealogical sources available. Service records, pension files, muster rolls, and draft registrations can reveal an ancestor's physical description, family relationships, places of residence, and life story in extraordinary detail.","md",false,null,[231,232,233,234,235],"military records genealogy","civil war pension records","muster rolls genealogy","military service records","veteran records family history",{},true,"/blog/military-records-genealogy",7,{"title":7,"description":226},"blog/military-records-genealogy",[243,244,245,246,66],"Military Records","Genealogy Research","Family History","War Records","2zwBsOK3GuCLkUT3gLkVFIwYOgYkCi5vX_FdcpUVRmE",{"id":249,"title":250,"author":251,"body":252,"category":224,"date":225,"description":354,"extension":227,"featured":228,"image":229,"keywords":355,"meta":362,"navigation":237,"path":363,"readTime":364,"seo":365,"stem":366,"tags":367,"__hash__":373},"blog/blog/newgrange-ancient-monument.md","Newgrange: Older Than the Pyramids, Built by Our Ancestors",{"name":9,"bio":10},{"type":12,"value":253,"toc":347},[254,258,261,269,273,276,279,282,286,298,301,304,308,320,332,336,339],[15,255,257],{"id":256},"older-than-memory","Older Than Memory",[20,259,260],{},"Newgrange was already ancient when the pyramids of Giza were built. Constructed around 3200 BC, the great passage tomb in the Boyne Valley of County Meath predates the Egyptian pyramids by roughly five centuries and Stonehenge by a thousand years. It is one of the oldest deliberately engineered structures on Earth, and it still works. Every winter solstice, a shaft of sunlight enters a specially constructed opening above the entrance and travels down the 19-meter passage to illuminate the inner chamber for approximately 17 minutes. Five thousand years after its builders aligned it with the sun, the mechanism functions with precision.",[20,262,263,264,268],{},"Newgrange is not just old. It is a monument to the sophistication of the ",[98,265,267],{"href":266},"/blog/anatolian-farmer-migration","Neolithic farming communities"," who built it -- people who are often dismissed as primitive but who possessed engineering knowledge, astronomical understanding, and organizational capacity that challenges comfortable assumptions about the deep past.",[15,270,272],{"id":271},"the-structure","The Structure",[20,274,275],{},"The monument is a large circular mound approximately 85 meters in diameter and 13 meters tall, covering roughly an acre. The mound is retained by a wall of 97 kerbstones, many of which are decorated with elaborate carved designs -- spirals, lozenges, concentric circles, and chevrons. The entrance stone, with its famous triple spiral motif, is one of the most recognized works of prehistoric art in the world.",[20,277,278],{},"The passage extends 19 meters from the entrance on the southeast side to a cruciform chamber at the center. The chamber is roofed with a corbelled vault -- layers of stone overlapping inward to create a self-supporting dome -- that has remained waterproof for over five millennia without any mortar. The engineering required to construct a corbelled roof that does not leak after 5,000 years of Irish rain is not trivial. It demonstrates an understanding of structural loads, water drainage, and material properties that is genuinely impressive.",[20,280,281],{},"Above the entrance, a specially constructed \"roof box\" allows the rising sun on the winter solstice to enter the passage. The box is angled precisely to admit light only during a narrow window of days around December 21st. Modern surveys have confirmed that the alignment accounts for changes in the Earth's axial tilt over the intervening millennia -- the original alignment was even more precise than what we observe today.",[15,283,285],{"id":284},"who-built-it","Who Built It",[20,287,288,289,292,293,297],{},"The builders of Newgrange were the descendants of ",[98,290,291],{"href":266},"Anatolian farmers"," who had arrived in Ireland sometime around 3800 BC, part of the great Neolithic expansion that transformed Europe over the preceding millennia. Genetic analysis of remains found at Newgrange and other Boyne Valley tombs has confirmed this: the individuals buried in these monuments carry ancestry profiles consistent with Neolithic farming populations, with high proportions of early European farmer DNA and relatively little ",[98,294,296],{"href":295},"/blog/western-hunter-gatherer-dna","hunter-gatherer"," contribution.",[20,299,300],{},"One remarkable finding from ancient DNA analysis of Newgrange burials was evidence of elite social structure. A male individual buried in the central chamber showed signs of close parental consanguinity -- his parents were first-degree relatives. This pattern of elite inbreeding is known from other stratified ancient societies, including the Egyptian pharaohs and Hawaiian royalty. It suggests that the Boyne Valley communities were not egalitarian farming villages but hierarchical societies with a ruling class that used marriage practices to consolidate power.",[20,302,303],{},"The labor required to build Newgrange was enormous. Estimates suggest that the construction required hundreds of workers over a period of years, transporting thousands of tons of stone, many from sources kilometers away. The decorated kerbstones were carved before placement, meaning that the artistic program was planned in advance, not added as an afterthought. This level of coordination implies centralized authority, surplus food production to support non-agricultural labor, and a shared cosmological vision that motivated the investment.",[15,305,307],{"id":306},"newgrange-in-mythology","Newgrange in Mythology",[20,309,310,311,315,316,319],{},"The builders of Newgrange left no written records, but the monument was never forgotten. When Celtic-speaking peoples arrived in Ireland, probably during the Bronze Age, they incorporated Newgrange into their mythology. In Irish tradition, Newgrange is ",[312,313,314],"em",{},"Si an Bhrui"," or ",[312,317,318],{},"Bru na Boinne",", the dwelling of the Dagda, chief of the Tuatha De Danann -- the mythological race of gods or supernatural beings who inhabited Ireland before the arrival of the Gaels.",[20,321,322,323,327,328,331],{},"The ",[98,324,326],{"href":325},"/blog/book-of-invasions-mythology","Book of Invasions"," describes the Tuatha De Danann retreating into the ",[312,329,330],{},"sid"," -- the fairy mounds -- after their defeat by the Milesians, and Newgrange is identified as one of the most important of these otherworldly dwellings. The association of megalithic monuments with the supernatural world is common in Irish tradition and reflects a genuine cultural memory: these structures were already impossibly ancient when the Celts encountered them, and the only explanation available was that they had been built by beings who were more than human.",[15,333,335],{"id":334},"what-newgrange-means","What Newgrange Means",[20,337,338],{},"Newgrange challenges the narrative of linear progress that assumes the deep past was simpler and less capable than the present. The people who built it were farmers who had been in Ireland for only a few centuries, working with stone tools and no metal technology. Yet they produced a structure of monumental scale, precise astronomical alignment, and enduring engineering quality that has outlasted virtually everything built in the five thousand years since.",[20,340,341,342,346],{},"For those exploring ",[98,343,345],{"href":344},"/blog/celtic-languages-family-tree","Irish heritage",", Newgrange is a reminder that the story begins long before the Celts. The island's sacred landscape was established by Neolithic communities whose genetic and cultural contributions, though overlaid by later arrivals, were never entirely erased. The passage tomb at Newgrange stands as the oldest chapter in a story that continues through the Bronze Age, the Celtic period, early Christianity, and into the modern world.",{"title":213,"searchDepth":214,"depth":214,"links":348},[349,350,351,352,353],{"id":256,"depth":217,"text":257},{"id":271,"depth":217,"text":272},{"id":284,"depth":217,"text":285},{"id":306,"depth":217,"text":307},{"id":334,"depth":217,"text":335},"Newgrange, the great passage tomb in Ireland's Boyne Valley, was built around 3200 BC by Neolithic farming communities. Its precise solar alignment and monumental scale reveal a civilization far more sophisticated than popular imagination suggests.",[356,357,358,359,360,361],"newgrange ireland","newgrange passage tomb","boyne valley monuments","newgrange winter solstice","neolithic ireland","newgrange history",{},"/blog/newgrange-ancient-monument",9,{"title":250,"description":354},"blog/newgrange-ancient-monument",[368,369,370,371,372],"Newgrange","Boyne Valley","Neolithic Ireland","Passage Tomb","Ancient Monument","RvOZLi_LwoRWnl1vTnUpfrBYzERajWghi69ygNRde_s",{"id":375,"title":376,"author":377,"body":378,"category":224,"date":549,"description":550,"extension":227,"featured":228,"image":229,"keywords":551,"meta":557,"navigation":237,"path":558,"readTime":559,"seo":560,"stem":561,"tags":562,"__hash__":568},"blog/blog/highland-clearances-detailed-history.md","The Highland Clearances: A Deeper Look at Forced Displacement",{"name":9,"bio":10},{"type":12,"value":379,"toc":541},[380,384,387,395,398,402,405,411,417,423,429,433,436,442,453,459,465,469,472,478,484,490,501,505,511,514,517,520,522,524],[15,381,383],{"id":382},"a-century-of-displacement","A Century of Displacement",[20,385,386],{},"The Highland Clearances were not a single event but a sustained process of forced displacement that unfolded across the Scottish Highlands and Islands from the 1760s through the 1880s. During this period, tens of thousands of Gaelic-speaking Highlanders were removed from the inland glens and straths they had farmed for generations, pushed to marginal coastal land or onto emigrant ships bound for Canada, Australia, and the United States.",[20,388,389,390,394],{},"The Clearances transformed the Highland landscape from a populated agricultural territory into a depopulated expanse of sheep runs and sporting estates. The social world of the ",[98,391,393],{"href":392},"/blog/scottish-clan-system-explained","Highland clan system"," -- already weakened by the post-Culloden legislation -- was effectively destroyed. The Gaelic language, deprived of its community base, began its long decline toward endangered status.",[20,396,397],{},"No account of Scottish ancestry is complete without understanding the Clearances, because for the majority of Highland families, the Clearances are the reason their descendants are scattered across the English-speaking world.",[15,399,401],{"id":400},"the-structural-causes","The Structural Causes",[20,403,404],{},"The Clearances were driven by a convergence of economic, legal, and ideological forces that made the displacement of Highland populations appear rational -- even beneficial -- to the landlords who carried them out.",[20,406,407,410],{},[40,408,409],{},"The transformation of chiefs into landlords."," The post-Culloden legislation of the 1740s and 1750s stripped clan chiefs of their hereditary jurisdictions and military authority. What remained was their legal title to land. Chiefs who had once derived their power from the number of armed men they could field now derived their income from the rental value of their estates. The incentive shifted from maintaining a large tenantry to maximizing land revenue.",[20,412,413,416],{},[40,414,415],{},"The sheep economy."," Cheviot and Blackface sheep could graze Highland pastures more profitably than small-scale mixed farming could use them. A cleared glen converted to a single sheep run generated rental income far exceeding what the same land produced under traditional crofting. The arithmetic was brutal but clear.",[20,418,419,422],{},[40,420,421],{},"The ideology of improvement."," The Scottish Enlightenment's emphasis on rational land management provided intellectual justification for the Clearances. Improving landlords framed the displacement of Highland communities as a modernizing project -- replacing backward subsistence farming with productive commercial agriculture. The language of improvement masked the reality of mass eviction.",[20,424,425,428],{},[40,426,427],{},"Kelp industry collapse."," On the western and northern coasts, the kelp industry had employed thousands of Highlanders in the early nineteenth century. When cheaper synthetic alternatives appeared in the 1820s, the industry collapsed almost overnight, removing the economic rationale that some landlords had used for maintaining large coastal populations.",[15,430,432],{"id":431},"key-episodes","Key Episodes",[20,434,435],{},"The Clearances were geographically widespread, but several episodes became notorious enough to enter the historical record in detail.",[20,437,438,441],{},[40,439,440],{},"Sutherland Clearances (1811-1820)."," The most infamous of the Clearances, carried out on the vast Sutherland estate by factors acting for the Countess of Sutherland and her husband, the Marquess of Stafford. Entire communities -- Strathnaver, Kildonan, and other straths -- were emptied to make way for sheep. The factor Patrick Sellar was tried (and acquitted) for culpable homicide after the death of elderly residents during the evictions at Strathnaver in 1814.",[20,443,444,447,448,452],{},[40,445,446],{},"Ross-shire Clearances."," The glens of ",[98,449,451],{"href":450},"/blog/ross-shire-geography-history","Ross-shire"," -- Strathconon, Strathcarron, and the interior valleys -- were cleared through the first half of the nineteenth century. The Greenyards incident of 1854, in which police assaulted women who resisted eviction notices in Strathcarron, became a cause celebre in the anti-Clearance press.",[20,454,455,458],{},[40,456,457],{},"Skye and the Crofters' War (1882)."," The Battle of the Braes on Skye, in which crofters resisted police sent to enforce an eviction, marked a turning point in public sympathy. The subsequent Napier Commission (1883) heard testimony from crofters across the Highlands and led to the Crofters' Holdings (Scotland) Act of 1886.",[20,460,461,464],{},[40,462,463],{},"The Outer Hebrides."," Lewis, Harris, and the Uists experienced clearances and forced relocations through the nineteenth century, with some of the most acute suffering occurring during the potato famine of the late 1840s, when destitution compounded the effects of landlord policies.",[15,466,468],{"id":467},"resistance","Resistance",[20,470,471],{},"The Highland population did not submit passively to eviction. Resistance took multiple forms, though it was constrained by the legal system, which overwhelmingly favored landlords.",[20,473,474,477],{},[40,475,476],{},"Physical resistance."," Women were often at the forefront of physical resistance to evictions, confronting sheriff officers and police. The gendering of resistance was partly strategic -- authorities were less willing to use violence against women -- and partly reflected the social structure of Highland communities where women managed the domestic and agricultural space.",[20,479,480,483],{},[40,481,482],{},"Legal challenge."," Some communities attempted to challenge evictions through the courts, though the legal system provided little protection to tenants before the 1886 Act.",[20,485,486,489],{},[40,487,488],{},"Press campaigns."," From the 1840s onward, journalists and reformers publicized the Clearances in the Scottish and British press. The coverage of events like Greenyards and the Crofters' War shifted public opinion and created political pressure for reform.",[20,491,492,495,496,500],{},[40,493,494],{},"Emigration as resistance."," For some communities, organized emigration was a form of agency -- choosing to leave on their own terms rather than waiting for forced eviction. The emigration of entire communities to ",[98,497,499],{"href":498},"/blog/scottish-diaspora-world","Canada and the United States"," sometimes preserved social bonds and cultural practices that would have been destroyed by piecemeal displacement.",[15,502,504],{"id":503},"the-aftermath","The Aftermath",[20,506,322,507,510],{},[98,508,509],{"href":151},"Crofters' Holdings Act of 1886"," ended the era of arbitrary eviction by granting crofters security of tenure, fair rent, and the right to pass their holdings to family members. But it could not reverse the demographic damage already done.",[20,512,513],{},"The population of the Scottish Highlands, which had peaked in the early nineteenth century, declined steadily through the Clearance era and continued to decline through the twentieth century. Gaelic, which had been the community language of the entire Highlands and Islands, retreated to the western fringes. The social structure of the clan system -- already legally dismantled after Culloden -- lost its demographic base.",[20,515,516],{},"What replaced the cleared communities was sheep farms, deer forests, and eventually sporting estates catering to Victorian and Edwardian hunting tourism. The glens that had supported hundreds of families became private playgrounds for absentee landlords.",[20,518,519],{},"The Highland Clearances remain a defining trauma in Scottish national memory -- a wound that informs Scottish attitudes toward land ownership, class, and authority to this day. For the descendants of the cleared communities, now scattered across the global diaspora, the Clearances are the hinge point of family history: the event that separated their ancestors from the land and sent them into the world.",[185,521],{},[15,523,190],{"id":189},[192,525,526,531,536],{},[195,527,528],{},[98,529,530],{"href":151},"The Highland Clearances and Clan Ross: How a People Were Scattered",[195,532,533],{},[98,534,535],{"href":392},"The Scottish Clan System Explained",[195,537,538],{},[98,539,540],{"href":498},"The Scottish Diaspora: How Scotland Seeded the World",{"title":213,"searchDepth":214,"depth":214,"links":542},[543,544,545,546,547,548],{"id":382,"depth":217,"text":383},{"id":400,"depth":217,"text":401},{"id":431,"depth":217,"text":432},{"id":467,"depth":217,"text":468},{"id":503,"depth":217,"text":504},{"id":189,"depth":217,"text":190},"2026-01-22","The Highland Clearances displaced tens of thousands of Gaelic-speaking Scots from their ancestral lands over more than a century. Here is a detailed account of the economic forces, the key events, the resistance, and the lasting consequences of one of Scotland's greatest traumas.",[552,553,554,555,556],"highland clearances history","highland clearances detailed","scottish clearances events","highland clearances causes","clearances resistance scotland",{},"/blog/highland-clearances-detailed-history",8,{"title":376,"description":550},"blog/highland-clearances-detailed-history",[563,564,565,566,567],"Highland Clearances","Scottish History","Forced Displacement","Crofting","Scottish Diaspora","SEZ6O6KXpCuwQSvQU4IpLiPPkneMttVrgDTQUK79FpY",{"id":570,"title":571,"author":572,"body":573,"category":693,"date":549,"description":694,"extension":227,"featured":228,"image":229,"keywords":695,"meta":699,"navigation":237,"path":700,"readTime":559,"seo":701,"stem":702,"tags":703,"__hash__":709},"blog/blog/niche-saas-market-entry.md","Entering a Niche SaaS Market: Lessons From the Auto Glass Industry",{"name":9,"bio":10},{"type":12,"value":574,"toc":686},[575,579,582,585,594,598,601,609,617,621,624,627,639,642,646,649,652,655,658,662,665,671,679],[15,576,578],{"id":577},"why-niche-markets","Why Niche Markets",[20,580,581],{},"The SaaS market is enormous, but the opportunity for independent developers and small teams is not in building the next Salesforce or the next Slack. Those markets are dominated by companies with hundreds of millions in venture capital and thousands of employees. Competing on their terms is not a viable strategy for a small team.",[20,583,584],{},"Niche markets — also called vertical SaaS — are where small teams can win. A vertical SaaS product serves a specific industry with software built for that industry's specific workflows, terminology, and regulatory requirements. The market size for any individual vertical is smaller than the horizontal market, but the competition is proportionally smaller too, and the willingness to pay is often higher because the software solves specific, high-value problems.",[20,586,587,593],{},[98,588,592],{"href":589,"rel":590},"https://bastionglass.com",[591],"nofollow","BastionGlass"," is a vertical SaaS for the auto glass industry. The lessons from entering this market apply broadly to anyone considering a niche SaaS product.",[15,595,597],{"id":596},"finding-the-right-niche","Finding the Right Niche",[20,599,600],{},"Not every niche is worth pursuing. The ideal niche for a SaaS product has several characteristics: enough businesses to support a sustainable software company, enough industry-specific workflow complexity to justify purpose-built software, enough dissatisfaction with existing solutions to create demand, and enough willingness to pay for software to support a viable business model.",[20,602,603,604,608],{},"The auto glass industry checked all of these. There are thousands of auto glass shops in the US — enough market size for a vertical SaaS. The workflow is genuinely complex, involving vehicle-specific quoting, insurance claim management, ",[98,605,607],{"href":606},"/blog/bastionglass-dispatch-scheduling","mobile dispatch",", ADAS recalibration tracking, and compliance requirements. The existing software options are either legacy systems with dated interfaces or generic field service platforms that require extensive customization. And auto glass shops are accustomed to paying for software — most already use some kind of point-of-sale or invoicing system.",[20,610,611,612,616],{},"I did not find this niche through market research in the traditional sense. I found it through Chris S., who runs ",[98,613,615],{"href":614},"/blog/building-myautoglassrehab-brand-strategy","AutoGlass Rehab"," in DFW. He was the first user, the domain expert, and eventually the co-founder. This is a pattern worth highlighting — the most reliable path to a niche SaaS is having a deep relationship with someone who works in the industry every day. Market research reports cannot tell you what keeps a shop owner up at night. A co-founder who is also a customer can.",[15,618,620],{"id":619},"the-first-customer-advantage","The First Customer Advantage",[20,622,623],{},"BastionGlass launched with one customer: AutoGlass Rehab. This is not a limitation — it is a strategic advantage. Building for one customer before building for a market provides several benefits that are difficult to replicate at scale.",[20,625,626],{},"First, the feedback loop is immediate and honest. Chris used BastionGlass every day in his actual business. When something did not work, he told me within hours. When a feature was missing, he described the exact scenario where he needed it. This is infinitely more valuable than survey responses or user interviews because it comes from genuine daily use, not hypothetical usage.",[20,628,629,630,634,635,638],{},"Second, building for one customer forces you to solve real problems rather than imagined ones. The ",[98,631,633],{"href":632},"/blog/bastionglass-quoting-engine","quoting engine"," was built because Chris spent 15 minutes per quote on the phone, looking up part numbers and calculating prices manually. The ",[98,636,637],{"href":606},"dispatch system"," was built because he missed a job due to a scheduling conflict that text-message dispatch did not catch. Every feature exists because of a real problem in a real business, not because a product roadmap said it should.",[20,640,641],{},"Third, one satisfied customer is the best marketing for the next ten customers. When BastionGlass is ready for broader distribution, Chris's shop is the case study, the demo environment, and the reference customer. A prospective customer can see exactly how BastionGlass runs in a real shop, talk to a real shop owner who uses it, and evaluate whether it would work for their operation.",[15,643,645],{"id":644},"pricing-for-niche-markets","Pricing for Niche Markets",[20,647,648],{},"Pricing niche SaaS is different from pricing horizontal SaaS. Horizontal products compete on features and price against dozens of alternatives, which pushes prices down. Vertical products compete on fit and depth against a handful of alternatives, which allows for higher pricing.",[20,650,651],{},"The pricing strategy for BastionGlass is value-based rather than cost-based. The question is not \"how much does it cost us to serve one customer\" — it is \"how much value does this software create for the customer.\" When BastionGlass reduces quoting time from 15 minutes to 2 minutes, reduces scheduling conflicts from weekly to never, and automates insurance claim filing, the value to a busy shop is significant. Pricing captures a fraction of that value, which gives the customer a clear ROI and the product a sustainable margin.",[20,653,654],{},"We are still iterating on the specific pricing model — per-shop monthly fee, per-user pricing, or tiered plans based on job volume. Each model has trade-offs. Per-shop pricing is simple but does not scale revenue as the shop grows. Per-user pricing scales but can discourage adoption by making shops reluctant to add users. Tiered plans align pricing with value but add complexity to the buying decision.",[20,656,657],{},"The approach I would recommend to anyone entering a niche market: start simple, measure usage, and evolve the pricing model based on data. The first price you set is almost certainly wrong. The goal is to get it close enough that customers say yes, and then refine it as you learn more about how different types of customers derive value from the product.",[15,659,661],{"id":660},"building-industry-credibility","Building Industry Credibility",[20,663,664],{},"The challenge for a software company entering a niche market is credibility. Auto glass shop owners want software built by people who understand auto glass, not by generic software developers who discovered the industry last month.",[20,666,322,667,670],{},[98,668,669],{"href":614},"brand strategy for AutoGlass Rehab"," established credibility by demonstrating that we understand the industry's workflows, terminology, and challenges. The marketing for BastionGlass leans heavily on this — the case study shows a real shop using the real product, with the real shop owner explaining the impact in his own words.",[20,672,673,674,678],{},"Technical credibility matters too. The articles I write about ",[98,675,677],{"href":676},"/blog/auto-glass-industry-software","auto glass industry software",", the auto glass quoting process, and insurance claim management demonstrate domain knowledge that potential customers can verify. If a shop owner reads my article about insurance claim workflows and it matches their experience, they trust that the software was built by someone who understands their business.",[20,680,681,682,139],{},"Entering a niche market is not just a product decision — it is a commitment to becoming a domain expert. The software is only as good as the team's understanding of the domain, and that understanding deepens over time. The longer you work in a niche, the better your product becomes, and the harder it is for a competitor to replicate your depth. That compounding domain expertise is the real moat for a ",[98,683,685],{"href":684},"/blog/saas-architecture-patterns","vertical SaaS product",{"title":213,"searchDepth":214,"depth":214,"links":687},[688,689,690,691,692],{"id":577,"depth":217,"text":578},{"id":596,"depth":217,"text":597},{"id":619,"depth":217,"text":620},{"id":644,"depth":217,"text":645},{"id":660,"depth":217,"text":661},"Business","What I learned entering the auto glass industry with BastionGlass — market research, first customer strategy, pricing, and why niche markets reward depth over breadth.",[696,697,698],"niche saas market entry","vertical saas strategy","industry specific software",{},"/blog/niche-saas-market-entry",{"title":571,"description":694},"blog/niche-saas-market-entry",[704,705,706,707,708],"SaaS","Business Strategy","Niche Markets","Auto Glass","Entrepreneurship","9m6sRPIMFloNoJQv8ZqVQtC9ximwCStn7FC6ZpdWMTQ",{"id":711,"title":712,"author":713,"body":714,"category":224,"date":822,"description":823,"extension":227,"featured":228,"image":229,"keywords":824,"meta":828,"navigation":237,"path":787,"readTime":829,"seo":830,"stem":831,"tags":832,"__hash__":837},"blog/blog/brehon-law-ancient-ireland.md","Brehon Law: How Ancient Ireland Governed Itself",{"name":9,"bio":10},{"type":12,"value":715,"toc":816},[716,720,727,734,737,741,748,756,772,776,779,782,790,794,802,809],[15,717,719],{"id":718},"a-legal-system-without-prisons","A Legal System Without Prisons",[20,721,722,723,726],{},"Brehon law — ",[312,724,725],{},"Fenechas"," in Irish, meaning \"the law of the freemen\" — was the indigenous legal system of Ireland from at least the 7th century AD (when it was first written down) until the 17th century, when English common law finally displaced it. Its roots are almost certainly much older, extending deep into the pre-Christian Iron Age.",[20,728,729,730,733],{},"The most striking feature of Brehon law, from a modern perspective, is the absence of punishment as we understand it. There were no prisons, no police force, and no death penalty for most offenses. Instead, the system was built on compensation. If you injured someone, you paid a fine — the ",[312,731,732],{},"eric"," fine — calculated according to the severity of the injury and the social status of the victim. If you killed someone, you paid the victim's family a blood price. If you could not pay, your kin group was liable.",[20,735,736],{},"This was not a primitive system. It was a sophisticated framework for maintaining social order in a decentralized society without a strong central state. The underlying logic was restorative rather than punitive: the goal was to restore the injured party to their prior position, not to punish the offender for the satisfaction of the state. Since there was no state in the modern sense, punitive justice had no institutional home.",[15,738,740],{"id":739},"the-brehons-and-their-training","The Brehons and Their Training",[20,742,743,744,747],{},"The law was administered by ",[312,745,746],{},"brehons"," — professional jurists who underwent extensive training. According to the legal texts, a fully qualified brehon studied for up to twenty years, memorizing vast bodies of precedent, procedural rules, and legal commentary. The brehons were not judges in the modern sense — they did not have enforcement power. They were arbitrators whose authority rested on their knowledge and their reputation.",[20,749,750,751,755],{},"The brehon tradition was hereditary. Certain families specialized in law, passing their knowledge and their position from generation to generation. This created a professional class of legal scholars who served a similar function to the ",[98,752,754],{"href":753},"/blog/druid-tradition-history","druids"," in pre-Christian society — indeed, the legal and druidic traditions may have been historically linked, with the brehons emerging as a secular successor to the druids' legal functions after Christianization.",[20,757,758,759,762,763,766,767,771],{},"The legal texts themselves — the ",[312,760,761],{},"Senchus Mor",", the ",[312,764,765],{},"Book of Aicill",", and others — are among the most important documents in Irish literary history. Written in Old and Middle Irish, they preserve vocabulary, concepts, and social arrangements that predate their written form by centuries. For linguists studying the evolution of ",[98,768,770],{"href":769},"/blog/scottish-gaelic-language-history","Scottish Gaelic"," and Irish, the legal texts are invaluable primary sources.",[15,773,775],{"id":774},"women-status-and-complexity","Women, Status, and Complexity",[20,777,778],{},"Brehon law's treatment of women was remarkably progressive by the standards of its time — and, in some respects, by modern standards. Women could own property independently of their husbands. They could initiate divorce on multiple grounds, including the husband's failure to provide, his infidelity, or his physical violence. In cases of divorce, the woman retained her property and received a share of the marital assets proportional to her contribution.",[20,780,781],{},"There were multiple forms of marriage recognized under Brehon law, ranging from unions of equal property (where both partners brought equivalent wealth) to unions where one partner was clearly dominant. The legal status of children born outside marriage was also carefully regulated — they had defined rights to inheritance, though these varied by the circumstances of their birth.",[20,783,784,785,789],{},"Status in Brehon law was not simply a matter of birth. It was calculated through a complex system that took into account property, skill, reputation, and lineage. A king had the highest honor price, but a skilled craftsman or a learned ",[98,786,788],{"href":787},"/blog/brehon-law-ancient-ireland","brehon"," could have a higher honor price than a minor lord. This created a society where social mobility, while constrained, was possible through the acquisition of skill, property, or reputation.",[15,791,793],{"id":792},"the-end-and-the-echo","The End and the Echo",[20,795,796,797,801],{},"Brehon law survived the ",[98,798,800],{"href":799},"/blog/viking-age-scotland","Viking Age",", the Norman invasion, and centuries of English encroachment. It was finally and deliberately destroyed during the Tudor and Stuart conquests of the 16th and 17th centuries, when English common law was imposed across Ireland as part of a broader campaign to eradicate Gaelic culture and political autonomy.",[20,803,804,805,808],{},"The destruction was thorough. By the 18th century, Brehon law existed only in manuscripts that were largely unread until scholars began recovering them in the 19th century. The six-volume publication of the ",[312,806,807],{},"Ancient Laws of Ireland"," (1865-1901) brought the texts back into academic circulation, and they have been studied intensively ever since.",[20,810,811,812,815],{},"The relevance of Brehon law today lies not in any practical legal application but in what it reveals about the Gaelic world that produced it. This was a society that, long before the ",[98,813,814],{"href":392},"Scottish clan system"," formalized Highland social structures, had developed a legal framework based on kinship obligation, restorative justice, and graduated social status. The principles underlying Brehon law — that justice means restoring balance, that status carries obligation, that the community bears collective responsibility — echo across the centuries, even in societies that have never heard of a brehon.",{"title":213,"searchDepth":214,"depth":214,"links":817},[818,819,820,821],{"id":718,"depth":217,"text":719},{"id":739,"depth":217,"text":740},{"id":774,"depth":217,"text":775},{"id":792,"depth":217,"text":793},"2026-01-20","Brehon law governed Ireland for over a thousand years. It was restorative, sophisticated, and radically different from the systems that replaced it.",[825,826,827],"brehon law ancient ireland","ancient irish law","celtic legal system",{},6,{"title":712,"description":823},"blog/brehon-law-ancient-ireland",[833,834,835,836],"Brehon Law","Ancient Ireland","Celtic Law","Irish History","hd9ro1hx5Zjhe3sHq4ZtOh07kXjyFaRLH-SIT2-BGO8",{"id":839,"title":840,"author":841,"body":842,"category":224,"date":822,"description":911,"extension":227,"featured":228,"image":229,"keywords":912,"meta":918,"navigation":237,"path":919,"readTime":239,"seo":920,"stem":921,"tags":922,"__hash__":928},"blog/blog/selkie-kelpie-water-mythology.md","Selkies and Kelpies: Scotland's Water Mythology",{"name":9,"bio":10},{"type":12,"value":843,"toc":905},[844,848,851,854,862,866,869,872,875,879,882,885,892,896,899,902],[15,845,847],{"id":846},"water-in-scottish-life","Water in Scottish Life",[20,849,850],{},"Water defines Scotland. The country is shaped by lochs, rivers, firths, and the sea that surrounds it on three sides. For the people who have lived there across millennia, water was provider and destroyer in equal measure: it gave fish, powered mills, transported goods, and irrigated fields, but it also drowned fishermen, flooded homes, and claimed children who strayed too close to its edge. Scottish mythology invested water with consciousness, agency, and an ambiguous relationship with humanity.",[20,852,853],{},"The water beings of Scottish folklore are numerous and diverse, but they share certain characteristics. They are powerful. They are shape-shifters. They are beautiful, often dangerously so. And their interactions with humans are marked by desire, deception, and loss. These are not the sanitized water sprites of children's literature. They are reflections of a genuine and well-founded anxiety about the waters that sustained and threatened the communities that told their stories.",[20,855,856,857,861],{},"The two most famous Scottish water beings, the selkie and the kelpie, represent contrasting aspects of the human relationship with water. The selkie embodies the sea's allure and the grief of separation. The kelpie embodies the freshwater dangers of rivers and lochs. Together with the ",[98,858,860],{"href":859},"/blog/fairy-folklore-celtic-nations","fairy folk",", they constitute a supernatural landscape among the richest in any European tradition.",[15,863,865],{"id":864},"the-selkie","The Selkie",[20,867,868],{},"Selkies are seal-folk, beings who live as seals in the sea but can shed their skins to take human form on land. The selkie mythology is most strongly associated with Orkney and Shetland, where the Norse influence is strongest, though similar stories are found along the entire Scottish coast and in Ireland and the Faroe Islands. The stories almost always follow one of two patterns.",[20,870,871],{},"In the first pattern, a man finds a female selkie in human form on the shore, steals her sealskin, and hides it. Unable to return to the sea without her skin, the selkie becomes his wife. She is beautiful, gentle, and a good mother to their children, but she is always melancholy, always gazing at the sea. Eventually, often after years or decades, she or one of her children discovers the hidden skin. She puts it on, returns to the sea, and is never seen in human form again. She may be glimpsed as a seal, watching her human family from the water, but she cannot come back.",[20,873,874],{},"The selkie stories are, at their core, stories about the impossibility of possessing another being completely. The stolen sealskin is a metaphor for any relationship maintained by constraint rather than choice. When the selkie finds her skin, she chooses her true nature over the life that was imposed on her. The stories are heartbreaking because they do not resolve: the husband loses his wife, the children lose their mother, and the selkie returns to a sea that is her home but is also a kind of exile from the family she loved.",[15,876,878],{"id":877},"the-kelpie","The Kelpie",[20,880,881],{},"The kelpie is an altogether more dangerous creature. A water horse that inhabits rivers and lochs, the kelpie typically appears as a beautiful horse standing by the water's edge, inviting passersby to mount. Those who do find that they cannot dismount: the kelpie's hide becomes adhesive, and the creature plunges into the water, dragging its rider to their death.",[20,883,884],{},"In nearly all versions, the kelpie is associated with specific locations: a particular pool, a bend in a river, a stretch of loch shore. This specificity suggests that kelpie stories served a practical function, marking dangerous water features in a culture where fencing and warning signs did not exist.",[20,886,322,887,891],{},[98,888,890],{"href":889},"/blog/scottish-superstitions-folklore","highland folklore"," tradition includes numerous accounts of individuals who encountered kelpies and survived, usually through wit or the protection of iron, which water spirits were said to fear. One common motif involves a traveler who begins to stroke a kelpie's mane and finds their hand stuck. They cut off their own finger or hand to escape, a gruesome detail that underscores the message: the kelpie's beauty is a trap, and the cost of survival is high.",[15,893,895],{"id":894},"the-deeper-meanings","The Deeper Meanings",[20,897,898],{},"Water mythology encodes genuine ecological knowledge: which waters are dangerous, where currents are treacherous, where banks are unstable. It also encodes social anxieties about the sea that took fishermen and the rivers that drowned children.",[20,900,901],{},"The selkie stories may reflect the experience of women in communities where marriage was often arranged and escape was difficult. The selkie wife who gazes at the sea is a figure of contained desire, and her return to the water is an assertion of autonomy that social structures rarely permitted. The kelpie stories teach caution, distrust of the too-perfect, and the understanding that the natural world is fundamentally indifferent to human desire.",[20,903,904],{},"These stories have survived the transition from belief to entertainment, but they have not lost their power. The image of the selkie finding her hidden skin and walking into the sea still resonates. The beautiful horse by the water, waiting, still disturbs. The waters of Scotland are still beautiful, still dangerous, and still haunted by the stories that the people who lived beside them told to make sense of their power.",{"title":213,"searchDepth":214,"depth":214,"links":906},[907,908,909,910],{"id":846,"depth":217,"text":847},{"id":864,"depth":217,"text":865},{"id":877,"depth":217,"text":878},{"id":894,"depth":217,"text":895},"Scotland's lochs, rivers, and coasts are haunted by creatures of extraordinary power and beauty. Selkies, kelpies, and other water beings reflect a deep and ancient relationship between the Scottish people and their waters.",[913,914,915,916,917],"selkie mythology scotland","kelpie water horse","scottish water mythology","selkie stories","kelpie folklore",{},"/blog/selkie-kelpie-water-mythology",{"title":840,"description":911},"blog/selkie-kelpie-water-mythology",[923,924,925,926,927],"Scottish Mythology","Selkies","Kelpies","Water Spirits","Scottish Folklore","h8RxKOnxhhuOD0UXX1RGtHN4rpH7lqhAkWyZXd3kWTg",{"id":930,"title":931,"author":932,"body":933,"category":224,"date":822,"description":1025,"extension":227,"featured":228,"image":229,"keywords":1026,"meta":1033,"navigation":237,"path":1034,"readTime":364,"seo":1035,"stem":1036,"tags":1037,"__hash__":1041},"blog/blog/tara-hill-seat-of-kings.md","The Hill of Tara: Ireland's Sacred Seat of Power",{"name":9,"bio":10},{"type":12,"value":934,"toc":1019},[935,939,942,945,949,959,966,973,977,988,991,998,1002,1005,1008,1011],[15,936,938],{"id":937},"the-hill-that-ruled-ireland","The Hill That Ruled Ireland",[20,940,941],{},"The Hill of Tara does not look like much. It rises only 154 meters above sea level in the rolling farmland of County Meath, an unremarkable bump in the central Irish midlands. There are no dramatic cliffs, no towering stone walls, no ruins of great halls. What remains are grass-covered earthworks -- ring forts, passage tombs, enclosures, and ditches -- that trace the outlines of structures built and rebuilt over more than five thousand years.",[20,943,944],{},"But Tara's power was never physical. It was symbolic, political, and sacred. For the ancient Irish, Tara was the center of the world, the axis around which kingship, sovereignty, and the relationship between ruler and land revolved. To be inaugurated at Tara was to claim authority over all Ireland. To hold Tara was to hold the most potent symbol of legitimacy in the Irish political imagination.",[15,946,948],{"id":947},"layers-of-history","Layers of History",[20,950,951,952,955,956,958],{},"Tara's significance long predates the Celtic period. The oldest monument on the hill is the Mound of the Hostages (",[312,953,954],{},"Dumha na nGiall","), a Neolithic passage tomb dated to approximately 3200 BC -- making it roughly contemporary with ",[98,957,368],{"href":363},", just 30 kilometers to the northeast in the Boyne Valley. The passage tomb contained cremated remains and grave goods spanning a thousand years of use, from the Neolithic through the Early Bronze Age. The site was sacred long before anyone spoke a Celtic language in Ireland.",[20,960,961,962,139],{},"Later monuments include the Rath of the Synods, a multi-vallate ring fort with evidence of occupation from the Iron Age through the early medieval period. Roman artifacts found here -- including glass, pottery, and metalwork -- suggest that even though Rome never invaded Ireland, Roman goods reached Tara through trade or diplomatic exchange. The Rath na Ri (Fort of the Kings) is the largest enclosure on the hill, within which sits the Forrad and Tech Cormaic, the area traditionally associated with the seat of the ",[98,963,965],{"href":964},"/blog/irish-high-kings-history","High Kings",[20,967,968,969,972],{},"The Lia Fail, the Stone of Destiny, stands on the summit. Tradition holds that the stone would cry out when the rightful king of Ireland touched it. The stone visible today is a standing stone that may or may not be the original Lia Fail -- other traditions claim the true stone was taken to Scotland, where it became the Stone of Scone used in Scottish and later British coronation ceremonies. The connection between Tara's stone and Scotland's stone reflects the deep genealogical and mythological links between Ireland and Scotland through the ",[98,970,971],{"href":344},"Dal Riata kingdom"," and earlier migrations.",[15,974,976],{"id":975},"tara-in-the-literary-tradition","Tara in the Literary Tradition",[20,978,979,980,983,984,987],{},"The medieval Irish literary tradition lavishes attention on Tara. The ",[312,981,982],{},"Dindshenchas",", a collection of place-name lore, devotes extensive entries to the hill and its features. The ",[312,985,986],{},"Feis Temro"," (Feast of Tara) was a great assembly that, according to tradition, occurred at intervals when a new king was inaugurated or major decisions affecting all Ireland were made. During the feast, laws were proclaimed, disputes settled, and the political order of the island reaffirmed.",[20,989,990],{},"Cormac mac Airt, the legendary third-century High King, is particularly associated with Tara in the literary tradition. The texts describe his reign as a golden age of justice, prosperity, and learning, with Tara as a flourishing royal seat with grand halls and a sophisticated court. Archaeological evidence does not support the existence of monumental buildings at Tara during this period, but the literary tradition reveals how the Irish imagined their political center -- as a place where righteous kingship produced material abundance.",[20,992,993,994,997],{},"The association between Tara and sovereignty was not merely political but cosmological. In Irish mythological geography, Tara occupied the center of the island, with the four provinces -- Ulster, Connacht, Munster, and Leinster -- radiating outward. The fifth province, Meath (",[312,995,996],{},"Mide",", meaning \"middle\"), was Tara's own territory, the sacred center from which the rest of Ireland was conceptually organized.",[15,999,1001],{"id":1000},"decline-and-memory","Decline and Memory",[20,1003,1004],{},"Tara's political importance faded gradually during the early medieval period. The last king recorded as being inaugurated at Tara was Mael Sechnaill II in the late tenth century. By that time, the High Kingship itself was contested by dynasties from Munster and elsewhere who did not hold Tara, and the symbolic link between the hill and supreme authority was weakening.",[20,1006,1007],{},"The arrival of Christianity also transformed Tara's significance. According to tradition, Saint Patrick confronted the druids at Tara and challenged the pagan religious establishment that underpinned the site's sacred authority. The story may be more legend than history, but it captures a genuine transition: as Christianity became the dominant religion, the specifically pagan associations of Tara -- the sacred marriage of king and land, the druidic rituals, the cosmological centrality -- lost their institutional support.",[20,1009,1010],{},"But Tara never lost its hold on Irish identity. During the 1798 Rebellion, insurgents gathered at Tara. Daniel O'Connell held one of his massive \"Monster Meetings\" there in 1843, drawing an estimated 750,000 people to demand the repeal of the Act of Union. In each case, Tara was chosen because of what it symbolized: the ancient sovereignty of Ireland, the legitimacy that came from deep roots in the land.",[20,1012,1013,1014,1018],{},"For anyone exploring Irish or broader ",[98,1015,1017],{"href":1016},"/blog/proto-celtic-origins","Celtic heritage",", Tara is the point where archaeology, mythology, and political history converge. The hill contains physical remains spanning five millennia, literary traditions that connect it to the mythological origins of Ireland, and a political symbolism that persists into the modern era. It is, in every meaningful sense, the sacred center of the Irish world.",{"title":213,"searchDepth":214,"depth":214,"links":1020},[1021,1022,1023,1024],{"id":937,"depth":217,"text":938},{"id":947,"depth":217,"text":948},{"id":975,"depth":217,"text":976},{"id":1000,"depth":217,"text":1001},"The Hill of Tara in County Meath was the symbolic and political center of Irish kingship for millennia. From Neolithic ritual site to seat of the High Kings, Tara embodies the layered history of Ireland's relationship between land, power, and the sacred.",[1027,1028,1029,1030,1031,1032],"hill of tara ireland","tara seat of kings","tara hill history","irish sacred sites","tara county meath","celtic sacred landscape",{},"/blog/tara-hill-seat-of-kings",{"title":931,"description":1025},"blog/tara-hill-seat-of-kings",[1038,1039,965,1040,836],"Tara","Ireland","Sacred Sites","P7x5t7kz23dghhrGnNELD5uVwn3LWaiqZJbvcJQMLyM",{"id":1043,"title":1044,"author":1045,"body":1046,"category":2197,"date":2198,"description":2199,"extension":227,"featured":228,"image":229,"keywords":2200,"meta":2203,"navigation":237,"path":2204,"readTime":239,"seo":2205,"stem":2206,"tags":2207,"__hash__":2211},"blog/blog/drag-and-drop-interfaces.md","Building Drag-and-Drop Interfaces in Vue",{"name":9,"bio":10},{"type":12,"value":1047,"toc":2191},[1048,1051,1054,1058,1061,1086,1102,1108,1111,1477,1487,1491,1498,1854,1864,1872,1876,1879,1949,1954,1957,1961,1968,1971,2181,2184,2187],[20,1049,1050],{},"Drag-and-drop is one of the most satisfying interactions to use and one of the most frustrating to implement well. The browser's native drag-and-drop API is powerful but inconsistent across browsers and devices. Touch support requires additional handling. Accessibility requires a completely parallel interaction model. And the visual feedback during a drag operation — drop indicators, placeholder positioning, scroll behavior — determines whether the interaction feels polished or broken.",[20,1052,1053],{},"I have built drag-and-drop interfaces for project management boards, content editors, and file upload systems. Here is what actually works.",[15,1055,1057],{"id":1056},"choosing-your-approach","Choosing Your Approach",[20,1059,1060],{},"You have three options for drag-and-drop in Vue, and the choice matters.",[20,1062,1063,1066,1067,1071,1072,1071,1075,1071,1078,1081,1082,1085],{},[40,1064,1065],{},"Native HTML Drag and Drop API"," — works for simple cases like file drops onto a target zone. The API uses ",[1068,1069,1070],"code",{},"dragstart",", ",[1068,1073,1074],{},"dragover",[1068,1076,1077],{},"dragenter",[1068,1079,1080],{},"dragleave",", and ",[1068,1083,1084],{},"drop"," events. It is adequate for drag-from-desktop-to-browser scenarios but awkward for in-page reordering because it provides minimal visual feedback and no touch support.",[20,1087,1088,1091,1092,1071,1095,1081,1098,1101],{},[40,1089,1090],{},"Pointer events with manual positioning"," — you handle ",[1068,1093,1094],{},"pointerdown",[1068,1096,1097],{},"pointermove",[1068,1099,1100],{},"pointerup"," yourself, calculating positions and moving elements via CSS transforms. This gives you complete control over the visual experience but requires implementing hit detection, scroll behavior, and list reordering from scratch.",[20,1103,1104,1107],{},[40,1105,1106],{},"Libraries"," — VueDraggable (wrapping SortableJS), dnd-kit, or pragmatic-drag-and-drop. These handle the interaction mechanics and provide Vue-friendly APIs. For most applications, this is the right choice.",[20,1109,1110],{},"VueDraggable is the most established option in the Vue ecosystem. It wraps SortableJS with a Vue component interface:",[1112,1113,1117],"pre",{"className":1114,"code":1115,"language":1116,"meta":213,"style":213},"language-vue shiki shiki-themes github-dark","\u003Cscript setup lang=\"ts\">\nimport draggable from 'vuedraggable'\n\nInterface Task {\n id: string\n title: string\n status: string\n}\n\nConst tasks = ref\u003CTask[]>([\n { id: '1', title: 'Design mockups', status: 'todo' },\n { id: '2', title: 'API endpoints', status: 'todo' },\n { id: '3', title: 'Database schema', status: 'in-progress' },\n])\n\u003C/script>\n\n\u003Ctemplate>\n \u003Cdraggable\n v-model=\"tasks\"\n item-key=\"id\"\n ghost-class=\"opacity-50\"\n animation=\"200\"\n @end=\"onDragEnd\"\n >\n \u003Ctemplate #item=\"{ element }\">\n \u003Cdiv class=\"rounded border bg-white p-4 shadow-sm cursor-grab active:cursor-grabbing\">\n {{ element.title }}\n \u003C/div>\n \u003C/template>\n \u003C/draggable>\n\u003C/template>\n","vue",[1068,1118,1119,1149,1164,1169,1175,1184,1191,1198,1203,1207,1226,1250,1269,1289,1295,1305,1310,1320,1329,1340,1351,1362,1373,1384,1390,1415,1433,1439,1449,1458,1468],{"__ignoreMap":213},[1120,1121,1124,1128,1132,1136,1139,1142,1146],"span",{"class":1122,"line":1123},"line",1,[1120,1125,1127],{"class":1126},"s95oV","\u003C",[1120,1129,1131],{"class":1130},"s4JwU","script",[1120,1133,1135],{"class":1134},"svObZ"," setup",[1120,1137,1138],{"class":1134}," lang",[1120,1140,1141],{"class":1126},"=",[1120,1143,1145],{"class":1144},"sU2Wk","\"ts\"",[1120,1147,1148],{"class":1126},">\n",[1120,1150,1151,1155,1158,1161],{"class":1122,"line":217},[1120,1152,1154],{"class":1153},"snl16","import",[1120,1156,1157],{"class":1126}," draggable ",[1120,1159,1160],{"class":1153},"from",[1120,1162,1163],{"class":1144}," 'vuedraggable'\n",[1120,1165,1166],{"class":1122,"line":214},[1120,1167,1168],{"emptyLinePlaceholder":237},"\n",[1120,1170,1172],{"class":1122,"line":1171},4,[1120,1173,1174],{"class":1126},"Interface Task {\n",[1120,1176,1178,1181],{"class":1122,"line":1177},5,[1120,1179,1180],{"class":1134}," id",[1120,1182,1183],{"class":1126},": string\n",[1120,1185,1186,1189],{"class":1122,"line":829},[1120,1187,1188],{"class":1134}," title",[1120,1190,1183],{"class":1126},[1120,1192,1193,1196],{"class":1122,"line":239},[1120,1194,1195],{"class":1134}," status",[1120,1197,1183],{"class":1126},[1120,1199,1200],{"class":1122,"line":559},[1120,1201,1202],{"class":1126},"}\n",[1120,1204,1205],{"class":1122,"line":364},[1120,1206,1168],{"emptyLinePlaceholder":237},[1120,1208,1210,1213,1215,1218,1220,1223],{"class":1122,"line":1209},10,[1120,1211,1212],{"class":1126},"Const tasks ",[1120,1214,1141],{"class":1153},[1120,1216,1217],{"class":1134}," ref",[1120,1219,1127],{"class":1126},[1120,1221,1222],{"class":1134},"Task",[1120,1224,1225],{"class":1126},"[]>([\n",[1120,1227,1229,1232,1235,1238,1241,1244,1247],{"class":1122,"line":1228},11,[1120,1230,1231],{"class":1126}," { id: ",[1120,1233,1234],{"class":1144},"'1'",[1120,1236,1237],{"class":1126},", title: ",[1120,1239,1240],{"class":1144},"'Design mockups'",[1120,1242,1243],{"class":1126},", status: ",[1120,1245,1246],{"class":1144},"'todo'",[1120,1248,1249],{"class":1126}," },\n",[1120,1251,1253,1255,1258,1260,1263,1265,1267],{"class":1122,"line":1252},12,[1120,1254,1231],{"class":1126},[1120,1256,1257],{"class":1144},"'2'",[1120,1259,1237],{"class":1126},[1120,1261,1262],{"class":1144},"'API endpoints'",[1120,1264,1243],{"class":1126},[1120,1266,1246],{"class":1144},[1120,1268,1249],{"class":1126},[1120,1270,1272,1274,1277,1279,1282,1284,1287],{"class":1122,"line":1271},13,[1120,1273,1231],{"class":1126},[1120,1275,1276],{"class":1144},"'3'",[1120,1278,1237],{"class":1126},[1120,1280,1281],{"class":1144},"'Database schema'",[1120,1283,1243],{"class":1126},[1120,1285,1286],{"class":1144},"'in-progress'",[1120,1288,1249],{"class":1126},[1120,1290,1292],{"class":1122,"line":1291},14,[1120,1293,1294],{"class":1126},"])\n",[1120,1296,1298,1301,1303],{"class":1122,"line":1297},15,[1120,1299,1300],{"class":1126},"\u003C/",[1120,1302,1131],{"class":1130},[1120,1304,1148],{"class":1126},[1120,1306,1308],{"class":1122,"line":1307},16,[1120,1309,1168],{"emptyLinePlaceholder":237},[1120,1311,1313,1315,1318],{"class":1122,"line":1312},17,[1120,1314,1127],{"class":1126},[1120,1316,1317],{"class":1130},"template",[1120,1319,1148],{"class":1126},[1120,1321,1323,1326],{"class":1122,"line":1322},18,[1120,1324,1325],{"class":1126}," \u003C",[1120,1327,1328],{"class":1130},"draggable\n",[1120,1330,1332,1335,1337],{"class":1122,"line":1331},19,[1120,1333,1334],{"class":1134}," v-model",[1120,1336,1141],{"class":1126},[1120,1338,1339],{"class":1144},"\"tasks\"\n",[1120,1341,1343,1346,1348],{"class":1122,"line":1342},20,[1120,1344,1345],{"class":1134}," item-key",[1120,1347,1141],{"class":1126},[1120,1349,1350],{"class":1144},"\"id\"\n",[1120,1352,1354,1357,1359],{"class":1122,"line":1353},21,[1120,1355,1356],{"class":1134}," ghost-class",[1120,1358,1141],{"class":1126},[1120,1360,1361],{"class":1144},"\"opacity-50\"\n",[1120,1363,1365,1368,1370],{"class":1122,"line":1364},22,[1120,1366,1367],{"class":1134}," animation",[1120,1369,1141],{"class":1126},[1120,1371,1372],{"class":1144},"\"200\"\n",[1120,1374,1376,1379,1381],{"class":1122,"line":1375},23,[1120,1377,1378],{"class":1134}," @end",[1120,1380,1141],{"class":1126},[1120,1382,1383],{"class":1144},"\"onDragEnd\"\n",[1120,1385,1387],{"class":1122,"line":1386},24,[1120,1388,1389],{"class":1126}," >\n",[1120,1391,1393,1395,1397,1400,1403,1405,1408,1411,1413],{"class":1122,"line":1392},25,[1120,1394,1325],{"class":1126},[1120,1396,1317],{"class":1130},[1120,1398,1399],{"class":1126}," #",[1120,1401,1402],{"class":1134},"item",[1120,1404,1141],{"class":1126},[1120,1406,1407],{"class":1144},"\"",[1120,1409,1410],{"class":1126},"{ element }",[1120,1412,1407],{"class":1144},[1120,1414,1148],{"class":1126},[1120,1416,1418,1420,1423,1426,1428,1431],{"class":1122,"line":1417},26,[1120,1419,1325],{"class":1126},[1120,1421,1422],{"class":1130},"div",[1120,1424,1425],{"class":1134}," class",[1120,1427,1141],{"class":1126},[1120,1429,1430],{"class":1144},"\"rounded border bg-white p-4 shadow-sm cursor-grab active:cursor-grabbing\"",[1120,1432,1148],{"class":1126},[1120,1434,1436],{"class":1122,"line":1435},27,[1120,1437,1438],{"class":1126}," {{ element.title }}\n",[1120,1440,1442,1445,1447],{"class":1122,"line":1441},28,[1120,1443,1444],{"class":1126}," \u003C/",[1120,1446,1422],{"class":1130},[1120,1448,1148],{"class":1126},[1120,1450,1452,1454,1456],{"class":1122,"line":1451},29,[1120,1453,1444],{"class":1126},[1120,1455,1317],{"class":1130},[1120,1457,1148],{"class":1126},[1120,1459,1461,1463,1466],{"class":1122,"line":1460},30,[1120,1462,1444],{"class":1126},[1120,1464,1465],{"class":1130},"draggable",[1120,1467,1148],{"class":1126},[1120,1469,1471,1473,1475],{"class":1122,"line":1470},31,[1120,1472,1300],{"class":1126},[1120,1474,1317],{"class":1130},[1120,1476,1148],{"class":1126},[20,1478,322,1479,1482,1483,1486],{},[1068,1480,1481],{},"ghost-class"," applies styles to the element being dragged. The ",[1068,1484,1485],{},"animation"," prop adds smooth transitions when items reorder. These details make the difference between \"it works\" and \"it feels right.\"",[15,1488,1490],{"id":1489},"kanban-board-implementation","Kanban Board Implementation",[20,1492,1493,1494,1497],{},"Multi-column drag-and-drop — moving items between lists — is the most common complex case. Each column is its own draggable container, and items can move between them. The key is sharing a ",[1068,1495,1496],{},"group"," name across columns:",[1112,1499,1501],{"className":1114,"code":1500,"language":1116,"meta":213,"style":213},"\u003Cscript setup lang=\"ts\">\nconst columns = ref([\n { id: 'todo', title: 'To Do', tasks: [...] },\n { id: 'in-progress', title: 'In Progress', tasks: [...] },\n { id: 'done', title: 'Done', tasks: [...] },\n])\n\nFunction onMoveTask(event: { added?: unknown; removed?: unknown }) {\n // Persist the new order to the backend\n syncTaskOrder()\n}\n\u003C/script>\n\n\u003Ctemplate>\n \u003Cdiv class=\"grid grid-cols-3 gap-6\">\n \u003Cdiv v-for=\"column in columns\" :key=\"column.id\" class=\"rounded-lg bg-neutral-50 p-4\">\n \u003Ch2 class=\"mb-4 text-lg font-semibold\">{{ column.title }}\u003C/h2>\n \u003Cdraggable\n v-model=\"column.tasks\"\n group=\"kanban\"\n item-key=\"id\"\n class=\"min-h-[100px] space-y-2\"\n @change=\"onMoveTask\"\n >\n \u003Ctemplate #item=\"{ element }\">\n \u003CTaskCard :task=\"element\" />\n \u003C/template>\n \u003C/draggable>\n \u003C/div>\n \u003C/div>\n\u003C/template>\n",[1068,1502,1503,1519,1536,1556,1573,1591,1595,1599,1616,1622,1630,1634,1642,1646,1654,1669,1700,1720,1726,1735,1745,1753,1762,1772,1776,1796,1814,1822,1830,1838,1846],{"__ignoreMap":213},[1120,1504,1505,1507,1509,1511,1513,1515,1517],{"class":1122,"line":1123},[1120,1506,1127],{"class":1126},[1120,1508,1131],{"class":1130},[1120,1510,1135],{"class":1134},[1120,1512,1138],{"class":1134},[1120,1514,1141],{"class":1126},[1120,1516,1145],{"class":1144},[1120,1518,1148],{"class":1126},[1120,1520,1521,1524,1528,1531,1533],{"class":1122,"line":217},[1120,1522,1523],{"class":1153},"const",[1120,1525,1527],{"class":1526},"sDLfK"," columns",[1120,1529,1530],{"class":1153}," =",[1120,1532,1217],{"class":1134},[1120,1534,1535],{"class":1126},"([\n",[1120,1537,1538,1540,1542,1544,1547,1550,1553],{"class":1122,"line":214},[1120,1539,1231],{"class":1126},[1120,1541,1246],{"class":1144},[1120,1543,1237],{"class":1126},[1120,1545,1546],{"class":1144},"'To Do'",[1120,1548,1549],{"class":1126},", tasks: [",[1120,1551,1552],{"class":1153},"...",[1120,1554,1555],{"class":1126},"] },\n",[1120,1557,1558,1560,1562,1564,1567,1569,1571],{"class":1122,"line":1171},[1120,1559,1231],{"class":1126},[1120,1561,1286],{"class":1144},[1120,1563,1237],{"class":1126},[1120,1565,1566],{"class":1144},"'In Progress'",[1120,1568,1549],{"class":1126},[1120,1570,1552],{"class":1153},[1120,1572,1555],{"class":1126},[1120,1574,1575,1577,1580,1582,1585,1587,1589],{"class":1122,"line":1177},[1120,1576,1231],{"class":1126},[1120,1578,1579],{"class":1144},"'done'",[1120,1581,1237],{"class":1126},[1120,1583,1584],{"class":1144},"'Done'",[1120,1586,1549],{"class":1126},[1120,1588,1552],{"class":1153},[1120,1590,1555],{"class":1126},[1120,1592,1593],{"class":1122,"line":829},[1120,1594,1294],{"class":1126},[1120,1596,1597],{"class":1122,"line":239},[1120,1598,1168],{"emptyLinePlaceholder":237},[1120,1600,1601,1604,1607,1610,1613],{"class":1122,"line":559},[1120,1602,1603],{"class":1126},"Function ",[1120,1605,1606],{"class":1134},"onMoveTask",[1120,1608,1609],{"class":1126},"(event: { added?: unknown; removed",[1120,1611,1612],{"class":1153},"?:",[1120,1614,1615],{"class":1126}," unknown }) {\n",[1120,1617,1618],{"class":1122,"line":364},[1120,1619,1621],{"class":1620},"sAwPA"," // Persist the new order to the backend\n",[1120,1623,1624,1627],{"class":1122,"line":1209},[1120,1625,1626],{"class":1134}," syncTaskOrder",[1120,1628,1629],{"class":1126},"()\n",[1120,1631,1632],{"class":1122,"line":1228},[1120,1633,1202],{"class":1126},[1120,1635,1636,1638,1640],{"class":1122,"line":1252},[1120,1637,1300],{"class":1126},[1120,1639,1131],{"class":1130},[1120,1641,1148],{"class":1126},[1120,1643,1644],{"class":1122,"line":1271},[1120,1645,1168],{"emptyLinePlaceholder":237},[1120,1647,1648,1650,1652],{"class":1122,"line":1291},[1120,1649,1127],{"class":1126},[1120,1651,1317],{"class":1130},[1120,1653,1148],{"class":1126},[1120,1655,1656,1658,1660,1662,1664,1667],{"class":1122,"line":1297},[1120,1657,1325],{"class":1126},[1120,1659,1422],{"class":1130},[1120,1661,1425],{"class":1134},[1120,1663,1141],{"class":1126},[1120,1665,1666],{"class":1144},"\"grid grid-cols-3 gap-6\"",[1120,1668,1148],{"class":1126},[1120,1670,1671,1673,1675,1678,1680,1683,1686,1688,1691,1693,1695,1698],{"class":1122,"line":1307},[1120,1672,1325],{"class":1126},[1120,1674,1422],{"class":1130},[1120,1676,1677],{"class":1134}," v-for",[1120,1679,1141],{"class":1126},[1120,1681,1682],{"class":1144},"\"column in columns\"",[1120,1684,1685],{"class":1134}," :key",[1120,1687,1141],{"class":1126},[1120,1689,1690],{"class":1144},"\"column.id\"",[1120,1692,1425],{"class":1134},[1120,1694,1141],{"class":1126},[1120,1696,1697],{"class":1144},"\"rounded-lg bg-neutral-50 p-4\"",[1120,1699,1148],{"class":1126},[1120,1701,1702,1704,1706,1708,1710,1713,1716,1718],{"class":1122,"line":1312},[1120,1703,1325],{"class":1126},[1120,1705,15],{"class":1130},[1120,1707,1425],{"class":1134},[1120,1709,1141],{"class":1126},[1120,1711,1712],{"class":1144},"\"mb-4 text-lg font-semibold\"",[1120,1714,1715],{"class":1126},">{{ column.title }}\u003C/",[1120,1717,15],{"class":1130},[1120,1719,1148],{"class":1126},[1120,1721,1722,1724],{"class":1122,"line":1322},[1120,1723,1325],{"class":1126},[1120,1725,1328],{"class":1130},[1120,1727,1728,1730,1732],{"class":1122,"line":1331},[1120,1729,1334],{"class":1134},[1120,1731,1141],{"class":1126},[1120,1733,1734],{"class":1144},"\"column.tasks\"\n",[1120,1736,1737,1740,1742],{"class":1122,"line":1342},[1120,1738,1739],{"class":1134}," group",[1120,1741,1141],{"class":1126},[1120,1743,1744],{"class":1144},"\"kanban\"\n",[1120,1746,1747,1749,1751],{"class":1122,"line":1353},[1120,1748,1345],{"class":1134},[1120,1750,1141],{"class":1126},[1120,1752,1350],{"class":1144},[1120,1754,1755,1757,1759],{"class":1122,"line":1364},[1120,1756,1425],{"class":1134},[1120,1758,1141],{"class":1126},[1120,1760,1761],{"class":1144},"\"min-h-[100px] space-y-2\"\n",[1120,1763,1764,1767,1769],{"class":1122,"line":1375},[1120,1765,1766],{"class":1134}," @change",[1120,1768,1141],{"class":1126},[1120,1770,1771],{"class":1144},"\"onMoveTask\"\n",[1120,1773,1774],{"class":1122,"line":1386},[1120,1775,1389],{"class":1126},[1120,1777,1778,1780,1782,1784,1786,1788,1790,1792,1794],{"class":1122,"line":1392},[1120,1779,1325],{"class":1126},[1120,1781,1317],{"class":1130},[1120,1783,1399],{"class":1126},[1120,1785,1402],{"class":1134},[1120,1787,1141],{"class":1126},[1120,1789,1407],{"class":1144},[1120,1791,1410],{"class":1126},[1120,1793,1407],{"class":1144},[1120,1795,1148],{"class":1126},[1120,1797,1798,1800,1803,1806,1808,1811],{"class":1122,"line":1417},[1120,1799,1325],{"class":1126},[1120,1801,1802],{"class":1130},"TaskCard",[1120,1804,1805],{"class":1134}," :task",[1120,1807,1141],{"class":1126},[1120,1809,1810],{"class":1144},"\"element\"",[1120,1812,1813],{"class":1126}," />\n",[1120,1815,1816,1818,1820],{"class":1122,"line":1435},[1120,1817,1444],{"class":1126},[1120,1819,1317],{"class":1130},[1120,1821,1148],{"class":1126},[1120,1823,1824,1826,1828],{"class":1122,"line":1441},[1120,1825,1444],{"class":1126},[1120,1827,1465],{"class":1130},[1120,1829,1148],{"class":1126},[1120,1831,1832,1834,1836],{"class":1122,"line":1451},[1120,1833,1444],{"class":1126},[1120,1835,1422],{"class":1130},[1120,1837,1148],{"class":1126},[1120,1839,1840,1842,1844],{"class":1122,"line":1460},[1120,1841,1444],{"class":1126},[1120,1843,1422],{"class":1130},[1120,1845,1148],{"class":1126},[1120,1847,1848,1850,1852],{"class":1122,"line":1470},[1120,1849,1300],{"class":1126},[1120,1851,1317],{"class":1130},[1120,1853,1148],{"class":1126},[20,1855,322,1856,1859,1860,1863],{},[1068,1857,1858],{},"group=\"kanban\""," setting allows items to be dragged between any column that shares the group name. The ",[1068,1861,1862],{},"min-h-[100px]"," on each column ensures there is a visible drop target even when a column is empty — without it, users cannot drop items into an empty column because there is no area to drop onto.",[20,1865,1866,1867,1871],{},"Persistence is critical. When a user moves a task from \"To Do\" to \"Done,\" that change must be saved immediately. Optimistic updates — updating the UI first, then sending the API request — provide the best user experience. If the API call fails, revert the UI and show an error notification. This pattern aligns with the ",[98,1868,1870],{"href":1869},"/blog/pinia-state-management-guide","state management approaches"," used for other optimistic UI updates.",[15,1873,1875],{"id":1874},"touch-support-and-mobile-considerations","Touch Support and Mobile Considerations",[20,1877,1878],{},"Touch devices add complexity because touch events conflict with scrolling. When a user puts their finger on a draggable item, the browser does not know whether they intend to drag the item or scroll the page. SortableJS handles this with a delay — the user must press and hold for a moment before the drag activates.",[1112,1880,1882],{"className":1114,"code":1881,"language":1116,"meta":213,"style":213},"\u003Cdraggable\n v-model=\"items\"\n item-key=\"id\"\n :delay=\"150\"\n :delay-on-touch-only=\"true\"\n>\n",[1068,1883,1884,1890,1904,1912,1929,1945],{"__ignoreMap":213},[1120,1885,1886,1888],{"class":1122,"line":1123},[1120,1887,1127],{"class":1126},[1120,1889,1328],{"class":1130},[1120,1891,1892,1894,1896,1898,1901],{"class":1122,"line":217},[1120,1893,1334],{"class":1134},[1120,1895,1141],{"class":1126},[1120,1897,1407],{"class":1144},[1120,1899,1900],{"class":1126},"items",[1120,1902,1903],{"class":1144},"\"\n",[1120,1905,1906,1908,1910],{"class":1122,"line":214},[1120,1907,1345],{"class":1134},[1120,1909,1141],{"class":1126},[1120,1911,1350],{"class":1144},[1120,1913,1914,1917,1920,1922,1924,1927],{"class":1122,"line":1171},[1120,1915,1916],{"class":1126}," :",[1120,1918,1919],{"class":1134},"delay",[1120,1921,1141],{"class":1126},[1120,1923,1407],{"class":1144},[1120,1925,1926],{"class":1526},"150",[1120,1928,1903],{"class":1144},[1120,1930,1931,1933,1936,1938,1940,1943],{"class":1122,"line":1177},[1120,1932,1916],{"class":1126},[1120,1934,1935],{"class":1134},"delay-on-touch-only",[1120,1937,1141],{"class":1126},[1120,1939,1407],{"class":1144},[1120,1941,1942],{"class":1526},"true",[1120,1944,1903],{"class":1144},[1120,1946,1947],{"class":1122,"line":829},[1120,1948,1148],{"class":1126},[20,1950,322,1951,1953],{},[1068,1952,1935],{}," setting applies the delay exclusively on touch devices, keeping desktop drag instant. 150 milliseconds is enough to distinguish a drag intention from a scroll without feeling sluggish.",[20,1955,1956],{},"On narrow viewports, horizontal kanban boards need a different approach. A common pattern is converting the horizontal board to a vertical accordion where each column expands on tap. Dragging between columns still works, but the spatial arrangement changes to match the viewport. Do not force horizontal scrolling on a kanban board at mobile widths — the interaction is frustrating and the content is nearly unreadable.",[15,1958,1960],{"id":1959},"accessibility-the-keyboard-alternative","Accessibility: The Keyboard Alternative",[20,1962,1963,1964,139],{},"Drag-and-drop is inherently a pointer-based interaction. Keyboard users and screen reader users need a parallel mechanism that achieves the same result. This is not optional — it is a ",[98,1965,1967],{"href":1966},"/blog/accessible-form-design","core accessibility requirement",[20,1969,1970],{},"The most effective pattern is providing action buttons on each draggable item that appear on focus:",[1112,1972,1974],{"className":1114,"code":1973,"language":1116,"meta":213,"style":213},"\u003Ctemplate>\n \u003Cdiv\n role=\"listitem\"\n :aria-label=\"`${task.title}, position ${index + 1} of ${total}`\"\n class=\"group\"\n >\n \u003Cspan>{{ task.title }}\u003C/span>\n \u003Cdiv class=\"opacity-0 group-focus-within:opacity-100\">\n \u003Cbutton\n aria-label=\"Move up\"\n @click=\"moveItem(index, index - 1)\"\n :disabled=\"index === 0\"\n >\n &uarr;\n \u003C/button>\n \u003Cbutton\n aria-label=\"Move down\"\n @click=\"moveItem(index, index + 1)\"\n :disabled=\"index === total - 1\"\n >\n &darr;\n \u003C/button>\n \u003C/div>\n \u003C/div>\n\u003C/template>\n",[1068,1975,1976,1984,1991,2001,2011,2020,2024,2037,2052,2059,2069,2079,2089,2093,2098,2107,2113,2122,2131,2140,2144,2149,2157,2165,2173],{"__ignoreMap":213},[1120,1977,1978,1980,1982],{"class":1122,"line":1123},[1120,1979,1127],{"class":1126},[1120,1981,1317],{"class":1130},[1120,1983,1148],{"class":1126},[1120,1985,1986,1988],{"class":1122,"line":217},[1120,1987,1325],{"class":1126},[1120,1989,1990],{"class":1130},"div\n",[1120,1992,1993,1996,1998],{"class":1122,"line":214},[1120,1994,1995],{"class":1134}," role",[1120,1997,1141],{"class":1126},[1120,1999,2000],{"class":1144},"\"listitem\"\n",[1120,2002,2003,2006,2008],{"class":1122,"line":1171},[1120,2004,2005],{"class":1134}," :aria-label",[1120,2007,1141],{"class":1126},[1120,2009,2010],{"class":1144},"\"`${task.title}, position ${index + 1} of ${total}`\"\n",[1120,2012,2013,2015,2017],{"class":1122,"line":1177},[1120,2014,1425],{"class":1134},[1120,2016,1141],{"class":1126},[1120,2018,2019],{"class":1144},"\"group\"\n",[1120,2021,2022],{"class":1122,"line":829},[1120,2023,1389],{"class":1126},[1120,2025,2026,2028,2030,2033,2035],{"class":1122,"line":239},[1120,2027,1325],{"class":1126},[1120,2029,1120],{"class":1130},[1120,2031,2032],{"class":1126},">{{ task.title }}\u003C/",[1120,2034,1120],{"class":1130},[1120,2036,1148],{"class":1126},[1120,2038,2039,2041,2043,2045,2047,2050],{"class":1122,"line":559},[1120,2040,1325],{"class":1126},[1120,2042,1422],{"class":1130},[1120,2044,1425],{"class":1134},[1120,2046,1141],{"class":1126},[1120,2048,2049],{"class":1144},"\"opacity-0 group-focus-within:opacity-100\"",[1120,2051,1148],{"class":1126},[1120,2053,2054,2056],{"class":1122,"line":364},[1120,2055,1325],{"class":1126},[1120,2057,2058],{"class":1130},"button\n",[1120,2060,2061,2064,2066],{"class":1122,"line":1209},[1120,2062,2063],{"class":1134}," aria-label",[1120,2065,1141],{"class":1126},[1120,2067,2068],{"class":1144},"\"Move up\"\n",[1120,2070,2071,2074,2076],{"class":1122,"line":1228},[1120,2072,2073],{"class":1134}," @click",[1120,2075,1141],{"class":1126},[1120,2077,2078],{"class":1144},"\"moveItem(index, index - 1)\"\n",[1120,2080,2081,2084,2086],{"class":1122,"line":1252},[1120,2082,2083],{"class":1134}," :disabled",[1120,2085,1141],{"class":1126},[1120,2087,2088],{"class":1144},"\"index === 0\"\n",[1120,2090,2091],{"class":1122,"line":1271},[1120,2092,1389],{"class":1126},[1120,2094,2095],{"class":1122,"line":1291},[1120,2096,2097],{"class":1526}," &uarr;\n",[1120,2099,2100,2102,2105],{"class":1122,"line":1297},[1120,2101,1444],{"class":1126},[1120,2103,2104],{"class":1130},"button",[1120,2106,1148],{"class":1126},[1120,2108,2109,2111],{"class":1122,"line":1307},[1120,2110,1325],{"class":1126},[1120,2112,2058],{"class":1130},[1120,2114,2115,2117,2119],{"class":1122,"line":1312},[1120,2116,2063],{"class":1134},[1120,2118,1141],{"class":1126},[1120,2120,2121],{"class":1144},"\"Move down\"\n",[1120,2123,2124,2126,2128],{"class":1122,"line":1322},[1120,2125,2073],{"class":1134},[1120,2127,1141],{"class":1126},[1120,2129,2130],{"class":1144},"\"moveItem(index, index + 1)\"\n",[1120,2132,2133,2135,2137],{"class":1122,"line":1331},[1120,2134,2083],{"class":1134},[1120,2136,1141],{"class":1126},[1120,2138,2139],{"class":1144},"\"index === total - 1\"\n",[1120,2141,2142],{"class":1122,"line":1342},[1120,2143,1389],{"class":1126},[1120,2145,2146],{"class":1122,"line":1353},[1120,2147,2148],{"class":1526}," &darr;\n",[1120,2150,2151,2153,2155],{"class":1122,"line":1364},[1120,2152,1444],{"class":1126},[1120,2154,2104],{"class":1130},[1120,2156,1148],{"class":1126},[1120,2158,2159,2161,2163],{"class":1122,"line":1375},[1120,2160,1444],{"class":1126},[1120,2162,1422],{"class":1130},[1120,2164,1148],{"class":1126},[1120,2166,2167,2169,2171],{"class":1122,"line":1386},[1120,2168,1444],{"class":1126},[1120,2170,1422],{"class":1130},[1120,2172,1148],{"class":1126},[1120,2174,2175,2177,2179],{"class":1122,"line":1392},[1120,2176,1300],{"class":1126},[1120,2178,1317],{"class":1130},[1120,2180,1148],{"class":1126},[20,2182,2183],{},"For kanban boards, replace the up/down buttons with a dropdown that lets the user select the target column. Announce the result of the action using an ARIA live region so screen reader users receive confirmation.",[20,2185,2186],{},"The keyboard interface does not need to replicate the drag-and-drop animation. It needs to achieve the same outcome — reordering items or moving them between groups — through a different interaction model. Do not try to make keyboard users \"drag\" with arrow keys. Give them direct actions that are clearer than dragging anyway.",[2188,2189,2190],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":213,"searchDepth":214,"depth":214,"links":2192},[2193,2194,2195,2196],{"id":1056,"depth":217,"text":1057},{"id":1489,"depth":217,"text":1490},{"id":1874,"depth":217,"text":1875},{"id":1959,"depth":217,"text":1960},"Frontend","2026-01-19","Implement drag-and-drop in Vue applications — sortable lists, kanban boards, file uploads, and the accessibility considerations most tutorials skip.",[2201,2202],"Vue drag and drop","drag and drop interface development",{},"/blog/drag-and-drop-interfaces",{"title":1044,"description":2199},"blog/drag-and-drop-interfaces",[2208,2209,2210],"Vue","UX Patterns","Accessibility","J4GNgSc2_XCDYWCnml8paGy1BfL_7nQVtXig4ReaIyE",{"id":2213,"title":2214,"author":2215,"body":2216,"category":2309,"date":2310,"description":2311,"extension":227,"featured":228,"image":229,"keywords":2312,"meta":2316,"navigation":237,"path":2317,"readTime":239,"seo":2318,"stem":2319,"tags":2320,"__hash__":2325},"blog/blog/bastionglass-payment-processing.md","Payment Processing in BastionGlass: Stripe Integration for Field Services",{"name":9,"bio":10},{"type":12,"value":2217,"toc":2302},[2218,2222,2225,2232,2235,2239,2242,2245,2248,2251,2255,2258,2261,2264,2267,2271,2274,2277,2280,2284,2287,2295],[15,2219,2221],{"id":2220},"payment-complexity-in-auto-glass","Payment Complexity in Auto Glass",[20,2223,2224],{},"Auto glass payment is not a simple one-time charge. Jobs can be paid through insurance, out of pocket, or a combination. Insurance claims involve deductibles that the customer pays directly while the insurance company pays the remainder separately. Some customers want to pay in full upfront, others want to pay on completion. Mobile technicians need to collect payments in the field, sometimes with unreliable cell service.",[20,2226,2227,2228,2231],{},"Before ",[98,2229,592],{"href":589,"rel":2230},[591],", Chris was using a separate Square terminal and manually reconciling payments with jobs in his spreadsheet. This worked but created accounting gaps — a payment collected in the field might not get recorded against the right job until the end of the day, and matching insurance reimbursements to specific jobs was a weekly reconciliation headache.",[20,2233,2234],{},"The goal for BastionGlass's payment system was simple: every payment is automatically associated with a job, every job's payment status is visible in real time, and the technician should be able to collect payment in two taps.",[15,2236,2238],{"id":2237},"stripe-as-the-payment-foundation","Stripe as the Payment Foundation",[20,2240,2241],{},"We chose Stripe for BastionGlass's payment processing for several reasons beyond the obvious ones. Yes, Stripe has excellent APIs and documentation. But more specifically, Stripe's payment intents model aligns well with the auto glass workflow, where a payment may be authorized at one point and captured at another.",[20,2243,2244],{},"When a customer approves a quote, BastionGlass creates a Stripe payment intent for the customer's portion of the job cost. For cash-pay customers, this is the full amount. For insurance customers, this is the deductible amount. The payment intent is created but not yet confirmed — it represents an obligation to pay, not a completed transaction.",[20,2246,2247],{},"When the technician completes the job and the customer signs the digital work order, the system confirms the payment intent. If the customer is paying with a card on file (captured during the intake process), confirmation happens automatically. If the customer is paying on-site, the technician's mobile interface presents a card input screen using Stripe's mobile elements, which handles the card reading and PCI compliance.",[20,2249,2250],{},"This authorization-then-capture pattern has a practical benefit: the customer's ability to pay is verified before the technician drives to the job. If a card is declined during authorization, the office can resolve the payment issue before dispatching the technician, saving a wasted trip.",[15,2252,2254],{"id":2253},"handling-insurance-payments","Handling Insurance Payments",[20,2256,2257],{},"Insurance payments are the more complex half of auto glass billing. When a job is covered by insurance, the total cost is split between the customer's deductible and the insurance company's reimbursement. These two payments happen through completely different channels — the deductible is collected directly from the customer, while the insurance payment arrives days or weeks later via check or ACH from the insurance company.",[20,2259,2260],{},"BastionGlass models this as a split payment on the job record. The job has a total cost, a customer amount (the deductible), and an insurance amount. The Stripe integration handles the customer amount through the standard payment intent flow. The insurance amount is tracked separately as a receivable.",[20,2262,2263],{},"When the insurance reimbursement arrives, the office staff records it against the specific job. The system reconciles the total — if the insurance payment plus the customer payment equals the quoted amount, the job is marked as fully paid. If there is a discrepancy (insurance companies sometimes pay less than the quoted rate), the system flags the difference for review.",[20,2265,2266],{},"This reconciliation process replaced the manual spreadsheet matching that Chris was doing weekly. Instead of downloading bank statements and hunting for which deposit matches which job, the system presents unmatched insurance payments and suggests likely job matches based on the amount, date, and insurance company. Most matches can be confirmed with a single click.",[15,2268,2270],{"id":2269},"field-collection-challenges","Field Collection Challenges",[20,2272,2273],{},"Collecting payments in the field introduced technical challenges that do not exist in a traditional e-commerce integration. The biggest was connectivity. Mobile technicians work in parking lots, driveways, and commercial properties where cell signal is unreliable. A payment system that requires a constant connection to process a transaction would fail in exactly the situations where payment collection is needed.",[20,2275,2276],{},"We handled this with Stripe's offline-capable payment flow. The payment intent is created while the technician has connectivity — during the dispatch phase, not at the moment of collection. When the technician completes the job and collects payment, the card information is tokenized on the device using Stripe's SDK. If connectivity is available, the payment confirms immediately. If not, the tokenized payment is queued and confirmed when connectivity returns.",[20,2278,2279],{},"The risk of offline collection is that a card could be declined when the queued payment eventually processes. We mitigated this by requiring card pre-authorization during the scheduling phase. By the time the technician arrives, the customer's card has already been validated and a hold placed for the expected amount. The on-site collection is a confirmation of an already-authorized transaction, not a new charge.",[15,2281,2283],{"id":2282},"reporting-and-financial-visibility","Reporting and Financial Visibility",[20,2285,2286],{},"With payments flowing through Stripe and insurance receivables tracked in BastionGlass, the system provides financial visibility that was previously impossible. The dashboard shows daily, weekly, and monthly revenue broken down by payment type — credit card, cash, insurance. Outstanding insurance receivables are tracked separately, with aging reports that highlight claims that have not been paid within the expected timeframe.",[20,2288,2289,2290,2294],{},"This financial visibility connects to the broader ",[98,2291,2293],{"href":2292},"/blog/bastionglass-architecture-decisions","ERP architecture",". Revenue data feeds into profitability reporting per job, per technician, and per service area. Chris can see not just total revenue but which types of jobs are most profitable, which service areas generate the most business, and whether insurance-pay or cash-pay jobs contribute more to the bottom line.",[20,2296,322,2297,2301],{},[98,2298,2300],{"href":2299},"/blog/stripe-subscription-billing","Stripe billing patterns"," we used in BastionGlass informed the approach we later took with subscription billing in Routiine.io, though the two use cases are different. Transaction-based payments for field services and recurring subscription billing for SaaS share the same payment infrastructure but require different models for authorization, timing, and reconciliation.",{"title":213,"searchDepth":214,"depth":214,"links":2303},[2304,2305,2306,2307,2308],{"id":2220,"depth":217,"text":2221},{"id":2237,"depth":217,"text":2238},{"id":2253,"depth":217,"text":2254},{"id":2269,"depth":217,"text":2270},{"id":2282,"depth":217,"text":2283},"Engineering","2026-01-18","How I integrated Stripe into BastionGlass for field service payments — handling deposits, on-site card collection, insurance reconciliation, and split payment scenarios.",[2313,2314,2315],"stripe field service integration","payment processing erp","field service payment collection",{},"/blog/bastionglass-payment-processing",{"title":2214,"description":2311},"blog/bastionglass-payment-processing",[2321,2322,2323,707,2324],"Stripe","Payments","ERP","TypeScript","52K0B9QCLUr3hdNJyn8Am46ohtPgvKXo7wKiMsm4XbA",{"id":2327,"title":205,"author":2328,"body":2329,"category":224,"date":2310,"description":2513,"extension":227,"featured":228,"image":229,"keywords":2514,"meta":2520,"navigation":237,"path":204,"readTime":239,"seo":2521,"stem":2522,"tags":2523,"__hash__":2527},"blog/blog/immigration-records-research.md",{"name":9,"bio":10},{"type":12,"value":2330,"toc":2504},[2331,2335,2338,2341,2344,2348,2351,2361,2367,2373,2379,2383,2390,2396,2402,2408,2414,2420,2430,2434,2437,2440,2443,2447,2450,2454,2460,2466,2475,2481,2484,2486,2488],[15,2332,2334],{"id":2333},"the-atlantic-crossing","The Atlantic Crossing",[20,2336,2337],{},"Between the early seventeenth century and the mid-twentieth century, an estimated 60 million Europeans crossed the Atlantic to settle in the Americas. They came from every country in Europe, driven by famine, poverty, religious persecution, political upheaval, and the promise of land and opportunity.",[20,2339,2340],{},"For genealogists, the crossing is often the critical link: the point where a family in the New World connects to a family in the Old. Finding the immigration record -- the document that identifies when an ancestor arrived, on what ship, from what port, and (with luck) from what town or parish -- is frequently the breakthrough that opens an entire European lineage.",[20,2342,2343],{},"The records exist. They are extensive, increasingly digitized, and searchable. But they are also scattered, inconsistent, and sometimes misleading. Understanding what records were kept, by whom, and where they survive is essential for navigating the archival landscape.",[15,2345,2347],{"id":2346},"passenger-lists-and-ship-manifests","Passenger Lists and Ship Manifests",[20,2349,2350],{},"The core immigration record is the passenger list or ship manifest -- the document recording the names of passengers on a particular voyage.",[20,2352,2353,2356,2357,2360],{},[40,2354,2355],{},"Before 1820",", systematic passenger lists for the United States do not exist. Some colonial-era records survive -- the lists of passengers on specific ships, the records of indentured servants, the customs house records of individual ports -- but there is no comprehensive system. For the colonial period, finding an ancestor's voyage often requires working from the destination backward, using land grants, ",[98,2358,2359],{"href":178},"census records",", and local records to establish when and where the family first appeared.",[20,2362,2363,2366],{},[40,2364,2365],{},"From 1820 onward",", US customs regulations required ship captains to submit passenger lists to the port collector at the destination. These early lists (1820-1891) typically record name, age, sex, occupation, and country of origin -- but not the specific town or parish, which limits their usefulness for connecting to European records.",[20,2368,2369,2372],{},[40,2370,2371],{},"From 1893 onward",", the lists became dramatically more detailed. New immigration forms asked for last residence, final destination, who paid for the passage, whether the passenger had been in the US before, the name and address of a relative in the country of origin, and the name and address of a relative or friend in the US. These details are genealogical gold.",[20,2374,2375,2378],{},[40,2376,2377],{},"From 1906 onward",", physical descriptions were added: height, complexion, hair color, eye color, distinguishing marks. From 1907, the name of the nearest relative in the country of origin was required -- often the single most valuable piece of information on the form.",[15,2380,2382],{"id":2381},"where-to-find-passenger-lists","Where to Find Passenger Lists",[20,2384,2385,2386,2389],{},"The major collections of US passenger lists are held at the ",[40,2387,2388],{},"National Archives and Records Administration"," (NARA) and have been digitized by multiple platforms:",[20,2391,2392,2395],{},[40,2393,2394],{},"Ancestry.com"," has the most comprehensive collection, including New York (Castle Garden and Ellis Island), Boston, Philadelphia, Baltimore, New Orleans, San Francisco, and dozens of smaller ports.",[20,2397,2398,2401],{},[40,2399,2400],{},"FamilySearch.org"," provides free access to many of the same collections, though indexing may be less complete.",[20,2403,2404,2407],{},[40,2405,2406],{},"The Ellis Island website"," (libertyellisfoundation.org) provides searchable access to arrival records for New York Harbor from 1892 to 1957. Approximately 12 million immigrants passed through Ellis Island during this period.",[20,2409,2410,2413],{},[40,2411,2412],{},"Castle Garden"," (castlegarden.org) covers New York arrivals from 1820 to 1892, before Ellis Island opened.",[20,2415,52,2416,2419],{},[40,2417,2418],{},"Canadian immigration",", Library and Archives Canada provides digitized passenger lists from 1865 onward. For earlier periods, records are scattered across provincial archives.",[20,2421,52,2422,2425,2426,2429],{},[40,2423,2424],{},"departures from the UK",", the Board of Trade passenger lists (held at The National Archives, Kew) record outgoing passengers from UK ports from 1890 onward. These are especially valuable because they list the passenger's last address in the UK -- a detail that can connect directly to British ",[98,2427,2428],{"href":100},"parish registers"," and census records.",[15,2431,2433],{"id":2432},"naturalization-records","Naturalization Records",[20,2435,2436],{},"Naturalization records -- the documents created when an immigrant became a citizen -- are a separate and often overlooked source. In the United States, naturalization was a two-step process: the Declaration of Intention (\"first papers\") and the Petition for Naturalization (\"final papers\"). Both documents can contain valuable genealogical information.",[20,2438,2439],{},"Before 1906, naturalization could occur in any court -- federal, state, or local -- and the records are scattered across thousands of courthouses. After 1906, the newly created Bureau of Immigration and Naturalization standardized the forms, which then asked for date and place of birth, date and port of arrival, name of ship, and current address.",[20,2441,2442],{},"NARA holds federal naturalization records. State and local records are often held at county courthouses or state archives. Many have been digitized through Ancestry, FamilySearch, and Fold3.",[15,2444,2446],{"id":2445},"passport-applications","Passport Applications",[20,2448,2449],{},"US passport applications, from 1795 onward, can contain birth date, birthplace, physical description, and sometimes a photograph. For naturalized citizens, applications include details of immigration and naturalization. Passport applications are held at NARA and have been partially digitized through Ancestry and FamilySearch.",[15,2451,2453],{"id":2452},"tips-for-successful-searching","Tips for Successful Searching",[20,2455,2456,2459],{},[40,2457,2458],{},"Expect name changes."," Names were not systematically changed at Ellis Island -- that is a myth. But names were frequently misspelled by clerks, anglicized by the immigrants themselves, or recorded differently from one document to the next. Search for phonetic variants and consider how a name might sound to an English-speaking clerk hearing it for the first time.",[20,2461,2462,2465],{},[40,2463,2464],{},"Search by family group."," Immigrants often traveled with family members, neighbors, or people from the same village. If you cannot find your ancestor by name, search for known associates who may have traveled on the same ship.",[20,2467,2468,2471,2472,2474],{},[40,2469,2470],{},"Work backward from the destination."," If you know where an ancestor settled in the US, ",[98,2473,2359],{"href":178}," can tell you their year of immigration and country of origin. Naturalization records can tell you the port, the ship, and the date. Armed with those details, finding the passenger list becomes much easier.",[20,2476,2477,2480],{},[40,2478,2479],{},"Check departure records as well as arrival records."," British departure records (BT 27 at The National Archives) may record a last address that does not appear in any American document. Hamburg emigration lists (1850-1934) are particularly detailed for emigrants passing through that port.",[20,2482,2483],{},"The Atlantic crossing was the defining event in millions of family histories. Finding the record of that crossing -- the name on the manifest, the ship, the date, the port -- is the moment when a family's American story connects to everything that came before.",[185,2485],{},[15,2487,190],{"id":189},[192,2489,2490,2494,2499],{},[195,2491,2492],{},[98,2493,199],{"href":178},[195,2495,2496],{},[98,2497,2498],{"href":100},"Parish Registers: The Backbone of Family History Research",[195,2500,2501],{},[98,2502,2503],{"href":151},"The Highland Clearances and Clan Ross Diaspora",{"title":213,"searchDepth":214,"depth":214,"links":2505},[2506,2507,2508,2509,2510,2511,2512],{"id":2333,"depth":217,"text":2334},{"id":2346,"depth":217,"text":2347},{"id":2381,"depth":217,"text":2382},{"id":2432,"depth":217,"text":2433},{"id":2445,"depth":217,"text":2446},{"id":2452,"depth":217,"text":2453},{"id":189,"depth":217,"text":190},"Millions of people crossed the Atlantic between the seventeenth and twentieth centuries, and many of them left traces in ship manifests, passenger lists, naturalization records, and port arrival documents. Here is how to find them.",[2515,2516,2517,2518,2519],"immigration records genealogy","passenger lists ancestors","ship manifest records","ellis island records","naturalization records genealogy",{},{"title":205,"description":2513},"blog/immigration-records-research",[2524,244,245,2525,2526],"Immigration Records","Passenger Lists","Migration History","lHfusW-Y_j28EjDrCXU-tkmjTcLdjnZCDexY8ZjJlY0",{"id":2529,"title":2530,"author":2531,"body":2532,"category":2702,"date":2703,"description":2704,"extension":227,"featured":228,"image":229,"keywords":2705,"meta":2709,"navigation":237,"path":2710,"readTime":239,"seo":2711,"stem":2712,"tags":2713,"__hash__":2716},"blog/blog/ai-lead-scoring.md","AI Lead Scoring: Identifying Your Best Prospects Automatically",{"name":9,"bio":10},{"type":12,"value":2533,"toc":2695},[2534,2538,2541,2544,2547,2549,2553,2556,2562,2568,2571,2579,2581,2585,2588,2594,2600,2606,2612,2622,2624,2628,2631,2637,2643,2649,2655,2657,2665,2667,2671],[15,2535,2537],{"id":2536},"the-lead-prioritization-problem","The Lead Prioritization Problem",[20,2539,2540],{},"A B2B sales team receives 500 leads per month. Some are ready to buy. Some are vaguely curious. Some are competitors checking your pricing. Some filled out a form by accident. The sales team has the capacity to give serious attention to maybe 50 of those leads. Choosing the right 50 determines whether the quarter hits target or misses.",[20,2542,2543],{},"Traditional lead scoring assigns points based on explicit criteria: company size gets points, job title gets points, visiting the pricing page gets points. These rule-based scores are better than no scoring but have fundamental limitations. The rules are static — they reflect what the scoring designer thought mattered at the time, not what the data says matters. They treat each signal independently — a VP who visited the pricing page gets the sum of the VP score and the pricing page score, even though the combination might be more predictive than the sum suggests. And they cannot capture non-linear patterns — leads from the healthcare industry might convert at high rates for one product line but low rates for another, a nuance that a single \"industry\" score cannot represent.",[20,2545,2546],{},"AI lead scoring replaces static rules with a model trained on your actual conversion data. The model learns which combinations of attributes and behaviors predict conversion in your specific business, and it updates as your data evolves.",[185,2548],{},[15,2550,2552],{"id":2551},"what-the-model-learns","What the Model Learns",[20,2554,2555],{},"An AI lead scoring model ingests two types of signals: firmographic attributes and behavioral data.",[20,2557,2558,2561],{},[40,2559,2560],{},"Firmographic attributes"," describe the company and the contact: industry, company size, job title, department, technology stack, geographic location, funding stage. These attributes indicate whether the lead fits your ideal customer profile. The model learns which attribute combinations predict conversion — not just \"enterprise companies convert well\" but \"enterprise healthcare companies with a technical buyer convert at 3x the average rate.\"",[20,2563,2564,2567],{},[40,2565,2566],{},"Behavioral data"," captures what the lead has done: which pages they visited, how many times they returned, whether they downloaded a whitepaper, which emails they opened, whether they attended a webinar, how they interacted with your product (if you offer a trial). Behavioral signals indicate intent. A lead who visited your pricing page three times, read two case studies, and attended a product webinar is demonstrating purchase intent through actions, not just fitting a demographic profile.",[20,2569,2570],{},"The model's power comes from combining these signals. A mid-market company in financial services where the VP of Operations visited the pricing page and downloaded the ROI calculator scores differently than a mid-market fintech company where a developer visited the API documentation. Both are \"mid-market\" and both visited the site, but the conversion probability is different because the combination of attributes and behaviors tells a different story.",[20,2572,2573,2574,2578],{},"The model also captures temporal patterns. A lead that moves from awareness (blog reading) to consideration (pricing page, case studies) to intent (demo request, ROI calculator) in two weeks has different momentum than one that has been passively visiting every few months for a year. ",[98,2575,2577],{"href":2576},"/blog/ai-predictive-analytics","Predictive analytics"," captures these velocity signals that static scoring rules cannot.",[185,2580],{},[15,2582,2584],{"id":2583},"building-the-scoring-system","Building the Scoring System",[20,2586,2587],{},"The implementation connects your CRM, your website analytics, and your marketing automation platform to a scoring model.",[20,2589,2590,2593],{},[40,2591,2592],{},"Data collection."," The model needs historical data on leads that converted and leads that did not, along with the firmographic and behavioral attributes that were present before conversion. This is typically a combination of CRM records (deal outcomes), marketing automation data (email engagement, form submissions), and web analytics (page visits, session data). The data integration is usually the most time-consuming part of the implementation.",[20,2595,2596,2599],{},[40,2597,2598],{},"Feature engineering."," Raw data becomes predictive features. Website visits become recency (days since last visit), frequency (visits per week), and depth (pages per session). Email data becomes engagement rate (opens/sends), response time, and content interest (which topics did they engage with). CRM data becomes deal attributes and conversion indicators.",[20,2601,2602,2605],{},[40,2603,2604],{},"Model training."," The model trains on historical leads with known outcomes. For most B2B lead scoring, gradient-boosted trees (XGBoost, LightGBM) work well because the data is tabular and the feature interactions are important. The model outputs a probability score (0-100) for each lead, representing the estimated likelihood of conversion.",[20,2607,2608,2611],{},[40,2609,2610],{},"Calibration."," The raw model output is a probability, but sales teams need actionable categories. Calibrate the scores into tiers: \"hot\" (top 10%, likely to convert in the next 30 days), \"warm\" (next 20%, strong potential with the right engagement), \"cold\" (bottom 70%, not ready or not a fit). The tier thresholds should be validated against actual conversion data — a \"hot\" lead should convert at a meaningfully higher rate than average.",[20,2613,2614,2617,2618,139],{},[40,2615,2616],{},"Integration."," The scores must appear where the sales team works — in the CRM, in the notification system, in the lead routing rules. A lead that crosses into \"hot\" territory should trigger an immediate notification to the assigned rep. Lead routing should direct hot leads to the most experienced reps. The scoring system is only valuable if it ",[98,2619,2621],{"href":2620},"/blog/ai-for-small-business","changes how the sales team allocates attention",[185,2623],{},[15,2625,2627],{"id":2626},"maintaining-and-improving-the-model","Maintaining and Improving the Model",[20,2629,2630],{},"Lead scoring models require ongoing attention to remain accurate.",[20,2632,2633,2636],{},[40,2634,2635],{},"Monitor score distribution."," If the model starts scoring too many leads as hot (or too few), the calibration has drifted. This often happens when marketing campaigns change the mix of incoming leads — a new channel that attracts a different lead profile can shift the distribution.",[20,2638,2639,2642],{},[40,2640,2641],{},"Validate predictions against outcomes."," Monthly, compare the model's predictions against actual conversions. Are hot leads actually converting at a higher rate? If the lift (the conversion rate of hot leads relative to average) is declining, the model needs retraining.",[20,2644,2645,2648],{},[40,2646,2647],{},"Retrain periodically."," The model should be retrained quarterly or when significant changes occur — new products, new markets, changes in sales process. Each retraining incorporates the most recent conversion data, keeping the model current.",[20,2650,2651,2654],{},[40,2652,2653],{},"Incorporate feedback."," Sales reps interact with leads daily and develop intuition about what makes a lead promising. Structured feedback — reps marking leads as \"good fit\" or \"bad fit\" — provides signal that the model cannot observe from behavioral data alone. This feedback loop improves the model and builds sales team trust in the scoring system.",[185,2656],{},[20,2658,2659,2660],{},"If you want to build a lead scoring system that helps your sales team focus on the right opportunities, ",[98,2661,2664],{"href":2662,"rel":2663},"https://calendly.com/jamesrossjr",[591],"let's talk.",[185,2666],{},[15,2668,2670],{"id":2669},"keep-reading","Keep Reading",[192,2672,2673,2678,2684,2689],{},[195,2674,2675],{},[98,2676,2677],{"href":2576},"Predictive Analytics with AI: From Data to Decisions",[195,2679,2680],{},[98,2681,2683],{"href":2682},"/blog/ai-sales-forecasting","AI Sales Forecasting: Building Accurate Prediction Models",[195,2685,2686],{},[98,2687,2688],{"href":2620},"AI for Small Business: Where It Actually Makes Sense",[195,2690,2691],{},[98,2692,2694],{"href":2693},"/blog/llm-integration-enterprise-apps","LLM Integration in Enterprise Applications",{"title":213,"searchDepth":214,"depth":214,"links":2696},[2697,2698,2699,2700,2701],{"id":2536,"depth":217,"text":2537},{"id":2551,"depth":217,"text":2552},{"id":2583,"depth":217,"text":2584},{"id":2626,"depth":217,"text":2627},{"id":2669,"depth":217,"text":2670},"AI","2026-01-15","Not all leads are equal. AI lead scoring identifies which prospects are most likely to convert so your sales team spends time on the right opportunities.",[2706,2707,2708],"ai lead scoring","automated lead scoring","predictive lead scoring",{},"/blog/ai-lead-scoring",{"title":2530,"description":2704},"blog/ai-lead-scoring",[2702,2714,2715],"Lead Scoring","Sales Technology","EDI8Z-1Ai-pfa0HV0DcL73jAABOD6ykCVsnhQs_NwOA",{"id":2718,"title":2719,"author":2720,"body":2721,"category":2309,"date":2703,"description":3035,"extension":227,"featured":228,"image":229,"keywords":3036,"meta":3039,"navigation":237,"path":3040,"readTime":559,"seo":3041,"stem":3042,"tags":3043,"__hash__":3045},"blog/blog/building-saas-with-nuxt.md","Building a SaaS Application with Nuxt and TypeScript",{"name":9,"bio":10},{"type":12,"value":2722,"toc":3027},[2723,2727,2730,2733,2736,2738,2742,2745,2763,2787,2809,2819,2821,2825,2828,2846,2855,2864,2876,2878,2882,2893,2906,2915,2927,2949,2951,2955,2958,2969,2975,2985,3002,3005,3007,3009],[15,2724,2726],{"id":2725},"why-nuxt-for-saas","Why Nuxt for SaaS",[20,2728,2729],{},"Most SaaS applications are B2B dashboards — authenticated experiences where users manage data, configure settings, and view reports. These applications don't need the aggressive SEO optimization that drives server-side rendering adoption, which is why many teams default to client-side-only frameworks.",[20,2731,2732],{},"But Nuxt offers more than SSR. Its architecture — file-based routing, auto-imported composables, server routes with Nitro, and first-class TypeScript support — provides a structure that scales well with application complexity. As a SaaS product grows from a handful of pages to dozens of feature areas, Nuxt's conventions prevent the structural entropy that plagues large single-page applications.",[20,2734,2735],{},"I've built several SaaS applications with Nuxt, including a multi-tenant ERP platform, and the framework's opinions about project structure have consistently saved time over the lifetime of each project. The initial learning curve pays for itself by the time you have 30 pages and 50 components.",[185,2737],{},[15,2739,2741],{"id":2740},"project-structure-for-saas","Project Structure for SaaS",[20,2743,2744],{},"Nuxt's default directory structure works for marketing sites, but a SaaS application needs some adjustments to accommodate authentication, multi-tenancy, and feature organization.",[20,2746,2747,2750,2751,2754,2755,2758,2759,2762],{},[40,2748,2749],{},"Route organization"," should mirror your product's information architecture. For a SaaS application, this typically means a public area (marketing pages, login, signup), an authenticated application area, and an admin area. Nuxt's layout system handles this cleanly — define a ",[1068,2752,2753],{},"default"," layout for the marketing site, an ",[1068,2756,2757],{},"app"," layout with sidebar navigation for the authenticated experience, and an ",[1068,2760,2761],{},"admin"," layout for administrative functions.",[20,2764,2765,2768,2769,1071,2772,1071,2775,2778,2779,2782,2783,2786],{},[40,2766,2767],{},"Feature-based component organization"," prevents the components directory from becoming a flat list of hundreds of files. Group components by feature area: ",[1068,2770,2771],{},"components/billing/",[1068,2773,2774],{},"components/settings/",[1068,2776,2777],{},"components/projects/",". Nuxt auto-imports them with a prefix based on the directory name, so ",[1068,2780,2781],{},"components/billing/PlanSelector.vue"," is available as ",[1068,2784,2785],{},"\u003CBillingPlanSelector />"," without manual imports.",[20,2788,2789,2792,2793,2796,2797,2800,2801,2804,2805,2808],{},[40,2790,2791],{},"Composables for shared logic"," replace the utility function files that accumulate in other frameworks. ",[1068,2794,2795],{},"composables/useAuth.ts"," for authentication state and methods, ",[1068,2798,2799],{},"composables/useTenant.ts"," for current tenant context, ",[1068,2802,2803],{},"composables/usePermissions.ts"," for role-based access checks. Nuxt auto-imports these, so any component can use ",[1068,2806,2807],{},"useAuth()"," without an import statement.",[20,2810,2811,2814,2815,2818],{},[40,2812,2813],{},"Server routes for API"," endpoints live in ",[1068,2816,2817],{},"server/api/"," and run on the Nitro server. For a full-stack Nuxt SaaS application, this is where your business logic lives. Each server route is a TypeScript function that receives a request and returns a response. You get type safety from the route handler to the component that consumes the data, with no API client generation required.",[185,2820],{},[15,2822,2824],{"id":2823},"authentication-and-middleware","Authentication and Middleware",[20,2826,2827],{},"Authentication is the first thing a SaaS application needs, and Nuxt's middleware system provides a clean way to enforce it.",[20,2829,2830,2833,2834,2837,2838,2841,2842,2845],{},[40,2831,2832],{},"Route middleware"," runs before navigation and can redirect unauthenticated users. Define a global ",[1068,2835,2836],{},"auth"," middleware that checks for a valid session and redirects to ",[1068,2839,2840],{},"/login"," if none exists. Apply it selectively — marketing pages and the login page are public, everything under ",[1068,2843,2844],{},"/app/"," requires authentication.",[20,2847,2848,2851,2852,2854],{},[40,2849,2850],{},"Server middleware"," protects API routes. Every route in ",[1068,2853,2817],{}," that handles tenant-specific data needs to verify the session token, extract the user and tenant context, and make it available to the route handler. A shared utility function that extracts and validates the session keeps this logic DRY.",[20,2856,2857,2860,2861,2863],{},[40,2858,2859],{},"Session management"," with Nuxt can use HTTP-only cookies for session tokens, which the server middleware validates on each request. The ",[1068,2862,2807],{}," composable on the client side tracks the current user state and provides login, logout, and session refresh methods. The composable calls server routes for authentication operations, keeping sensitive logic (token validation, password hashing) on the server.",[20,2865,2866,2867,2870,2871,2875],{},"For role-based access control, a ",[1068,2868,2869],{},"usePermissions()"," composable checks the current user's role against required permissions before rendering sensitive UI elements. The server routes independently verify permissions — client-side permission checks are a UX convenience, not a security mechanism. I've written extensively about designing ",[98,2872,2874],{"href":2873},"/blog/role-based-access-control-guide","RBAC systems"," that enforce permissions at both layers.",[185,2877],{},[15,2879,2881],{"id":2880},"data-fetching-patterns","Data Fetching Patterns",[20,2883,2884,2885,2888,2889,2892],{},"Nuxt's ",[1068,2886,2887],{},"useFetch"," and ",[1068,2890,2891],{},"useAsyncData"," composables handle data fetching with built-in loading states, error handling, and caching. For a SaaS application, a few patterns make these more effective.",[20,2894,2895,2898,2899,2901,2902,2905],{},[40,2896,2897],{},"Typed API responses"," ensure that the data returned by ",[1068,2900,2887],{}," is correctly typed. Define TypeScript interfaces for your API responses and use them with ",[1068,2903,2904],{},"useFetch\u003CResponseType>()",". This gives you type safety from the server route through the component template.",[20,2907,2908,2911,2912,2914],{},[40,2909,2910],{},"Optimistic updates"," improve perceived performance for mutations. When a user updates a setting, immediately reflect the change in the UI and send the API request in the background. If the request fails, revert the change and show an error. Nuxt's ",[1068,2913,2891],{}," with manual refresh makes this pattern straightforward.",[20,2916,2917,2920,2921,2923,2924,2926],{},[40,2918,2919],{},"Pagination and infinite scroll"," are necessary for list views that display tenant data. Nuxt's ",[1068,2922,2887],{}," can be combined with reactive query parameters to implement cursor-based pagination. As the user scrolls or clicks \"next page,\" the query parameters update and ",[1068,2925,2887],{}," automatically re-fetches with the new cursor.",[20,2928,2929,2932,2933,2936,2937,2939,2940,2943,2944,2948],{},[40,2930,2931],{},"Error handling"," should use Nuxt's ",[1068,2934,2935],{},"NuxtErrorBoundary"," component to catch rendering errors and display graceful fallbacks. API errors from ",[1068,2938,2887],{}," are available via the ",[1068,2941,2942],{},"error"," ref and should be displayed inline rather than swallowed. For a ",[98,2945,2947],{"href":2946},"/blog/saas-development-guide","SaaS product",", a user who encounters a silent error is a user who loses trust.",[185,2950],{},[15,2952,2954],{"id":2953},"state-management-with-pinia","State Management with Pinia",[20,2956,2957],{},"Pinia is the official state management library for Nuxt, and for SaaS applications it handles the global state that doesn't belong to any single component.",[20,2959,2960,2963,2964,2968],{},[40,2961,2962],{},"Tenant store"," holds the current tenant's configuration — their plan, their feature flags, their branding settings (if you're building a ",[98,2965,2967],{"href":2966},"/blog/saas-white-labeling","white-label product","). This store is populated on initial page load and consulted throughout the application.",[20,2970,2971,2974],{},[40,2972,2973],{},"User store"," holds the current user's profile, preferences, and permissions. It's populated after authentication and cleared on logout.",[20,2976,2977,2980,2981,2984],{},[40,2978,2979],{},"Feature stores"," manage domain-specific state. A project management SaaS might have a ",[1068,2982,2983],{},"useProjectStore"," that holds the current project and its associated data. The key principle is that stores hold shared state — state that multiple components need to access or modify. Component-local state stays in the component.",[20,2986,2987,2990,2991,2994,2995,315,2998,3001],{},[40,2988,2989],{},"Persistence"," for stores that need to survive page refreshes uses the ",[1068,2992,2993],{},"pinia-plugin-persistedstate"," package, which serializes store state to ",[1068,2996,2997],{},"localStorage",[1068,2999,3000],{},"sessionStorage",". Use this sparingly — persisting too much state leads to stale data bugs. Authentication state and user preferences are good candidates. Business data should be re-fetched from the server.",[20,3003,3004],{},"Nuxt with TypeScript, Pinia, and Nitro server routes gives you a full-stack, type-safe development experience in a single project. The framework's opinions about structure prevent the architectural drift that makes large applications hard to maintain, and the auto-import system reduces boilerplate without sacrificing discoverability.",[185,3006],{},[15,3008,2670],{"id":2669},[192,3010,3011,3016,3022],{},[195,3012,3013],{},[98,3014,3015],{"href":2946},"SaaS Development Guide: From Idea to Paying Customers",[195,3017,3018],{},[98,3019,3021],{"href":3020},"/blog/multi-tenant-architecture","Multi-Tenant Architecture: Patterns for Building Software That Serves Many Clients",[195,3023,3024],{},[98,3025,3026],{"href":2966},"White-Label SaaS Architecture: Building for Multiple Brands",{"title":213,"searchDepth":214,"depth":214,"links":3028},[3029,3030,3031,3032,3033,3034],{"id":2725,"depth":217,"text":2726},{"id":2740,"depth":217,"text":2741},{"id":2823,"depth":217,"text":2824},{"id":2880,"depth":217,"text":2881},{"id":2953,"depth":217,"text":2954},{"id":2669,"depth":217,"text":2670},"Nuxt gives you server-side rendering, file-based routing, and full-stack TypeScript in one framework. Here's how to structure a real SaaS application with it.",[3037,3038],"building SaaS with Nuxt","Nuxt TypeScript SaaS",{},"/blog/building-saas-with-nuxt",{"title":2719,"description":3035},"blog/building-saas-with-nuxt",[3044,2324,704],"Nuxt.js","Nf81CIrxjJmo4rcNZY9UeNYMhM_spGNWFIylaxNVD5Q",{"id":3047,"title":3048,"author":3049,"body":3050,"category":693,"date":2703,"description":3138,"extension":227,"featured":228,"image":229,"keywords":3139,"meta":3142,"navigation":237,"path":3143,"readTime":239,"seo":3144,"stem":3145,"tags":3146,"__hash__":3150},"blog/blog/continuous-discovery-product.md","Continuous Discovery: Building Products Users Actually Want",{"name":9,"bio":10},{"type":12,"value":3051,"toc":3132},[3052,3056,3059,3062,3065,3067,3071,3074,3077,3080,3083,3085,3089,3092,3095,3098,3106,3108,3112,3115,3118,3121,3129],[15,3053,3055],{"id":3054},"the-problem-with-building-what-you-think-users-want","The Problem with Building What You Think Users Want",[20,3057,3058],{},"Most software projects start with someone's idea of what users need. Maybe it's the founder's vision, maybe it's a feature request from a loud customer, maybe it's a competitive analysis that identified a gap. The team builds the thing, ships it, and then discovers that users don't use it the way anyone expected — or don't use it at all.",[20,3060,3061],{},"This isn't a failure of execution. The code works. The design is polished. The feature does exactly what the specification described. It's a failure of discovery — the process of understanding what problems actually exist, how users currently cope with them, and what solution would genuinely improve their lives.",[20,3063,3064],{},"Continuous discovery is the discipline of maintaining an ongoing, structured connection between the product team and the people they're building for. Not a one-time research phase before development starts, but an embedded habit that runs alongside every sprint, informing every prioritization decision.",[185,3066],{},[15,3068,3070],{"id":3069},"weekly-touchpoints-with-real-users","Weekly Touchpoints With Real Users",[20,3072,3073],{},"The foundation of continuous discovery is talking to users every week. Not through surveys — which tell you what people say they want — but through conversations that reveal what they actually do, what frustrates them, and what they've given up trying to improve.",[20,3075,3076],{},"The conversations don't need to be long. Fifteen to twenty minutes, focused on understanding a specific part of the user's workflow, is more valuable than a sixty-minute unfocused interview. The key is consistency. One interview per week for six months gives you a deeper understanding of your users than a two-week research sprint conducted once a year.",[20,3078,3079],{},"Structure the conversations around behavior, not opinions. \"How did you handle X the last time it came up?\" reveals more than \"Would you use a feature that does Y?\" People are unreliable predictors of their own future behavior, but they're excellent reporters of their past behavior — if you ask specific enough questions.",[20,3081,3082],{},"Build a research panel of users who've agreed to periodic conversations. Five to eight regular contacts, supplemented by new recruits to avoid echo chamber effects, gives you a reliable stream of insights. Compensate their time appropriately. A $50 gift card for twenty minutes is a trivial expense compared to the cost of building the wrong feature.",[185,3084],{},[15,3086,3088],{"id":3087},"from-insights-to-validated-solutions","From Insights to Validated Solutions",[20,3090,3091],{},"Raw user insights are not product specifications. The gap between \"users struggle with X\" and \"we should build Y\" is where most teams make their biggest mistakes. They jump from a problem observation to a specific solution without validating that the solution actually addresses the problem.",[20,3093,3094],{},"Opportunity mapping helps bridge this gap. When you identify a user need, map it to specific opportunities — ways your product could address that need — and then generate multiple possible solutions for each opportunity. This prevents the common trap of falling in love with the first solution idea and building it without considering alternatives.",[20,3096,3097],{},"Prototype and test before building. This doesn't mean building throwaway code. It means creating the simplest possible artifact that lets you test whether your solution concept resonates with users. Sometimes that's a Figma prototype. Sometimes it's a spreadsheet. Sometimes it's a five-minute conversation describing the concept and asking for reactions. The goal is to fail cheaply and quickly on bad ideas so you invest development time only on validated solutions.",[20,3099,3100,3101,3105],{},"This iterative validation process connects directly to how I approach ",[98,3102,3104],{"href":3103},"/blog/mvp-development-guide","MVP development",". An MVP isn't just a smaller version of your product — it's a hypothesis about what users need, built to the minimum scope that lets you test that hypothesis with real behavior.",[185,3107],{},[15,3109,3111],{"id":3110},"making-discovery-a-team-sport","Making Discovery a Team Sport",[20,3113,3114],{},"Continuous discovery fails when it's one person's responsibility. If only the product manager talks to users and then translates those conversations into tickets, the development team builds based on secondhand interpretations. Context gets lost. Nuance disappears. The developer implementing a feature has no connection to the human whose problem they're solving.",[20,3116,3117],{},"Include developers in user interviews. Not every developer, not every week, but rotate participation so that everyone on the team regularly hears directly from users. A developer who watched a user struggle with a workflow brings that empathy into every design decision they make, in ways that a ticket description cannot convey.",[20,3119,3120],{},"Share insights broadly and immediately. After every user conversation, post a brief summary in your team channel. Highlight surprising observations, recurring patterns, and direct quotes that capture the user's experience. Over time, these summaries build a shared understanding of your users that informs decisions at every level.",[20,3122,3123,3124,3128],{},"Connect discovery insights to your ",[98,3125,3127],{"href":3126},"/blog/feature-prioritization-frameworks","feature prioritization process",". Every candidate feature should trace back to a validated user need, not just an internal idea. This doesn't mean you never build something speculative — but it means speculative features are explicitly labeled as bets, with clear criteria for evaluating whether they paid off.",[20,3130,3131],{},"The teams that build products users love aren't smarter or more creative than the teams that don't. They're more connected. They maintain a continuous, structured relationship with the people they serve, and they let that relationship guide what they build, how they prioritize, and what they choose not to build. Discovery isn't a phase — it's a habit, and it's the most valuable habit a product team can develop.",{"title":213,"searchDepth":214,"depth":214,"links":3133},[3134,3135,3136,3137],{"id":3054,"depth":217,"text":3055},{"id":3069,"depth":217,"text":3070},{"id":3087,"depth":217,"text":3088},{"id":3110,"depth":217,"text":3111},"How continuous discovery habits keep product teams aligned with real user needs. Practical frameworks for research, validation, and iterative product development.",[3140,3141],"continuous discovery","product discovery process",{},"/blog/continuous-discovery-product",{"title":3048,"description":3138},"blog/continuous-discovery-product",[3147,3148,3149],"Product Discovery","Product Management","User Research","NBs4j8lnBuFASlG6542O7jTjGCbeXKHBc9gvIpku9Z4",{"id":3152,"title":3153,"author":3154,"body":3155,"category":224,"date":2703,"description":3247,"extension":227,"featured":228,"image":229,"keywords":3248,"meta":3255,"navigation":237,"path":964,"readTime":364,"seo":3256,"stem":3257,"tags":3258,"__hash__":3260},"blog/blog/irish-high-kings-history.md","The High Kings of Ireland: Myth and Reality",{"name":9,"bio":10},{"type":12,"value":3156,"toc":3241},[3157,3161,3175,3178,3182,3188,3191,3194,3198,3201,3208,3215,3218,3222,3228,3235],[15,3158,3160],{"id":3159},"the-ard-ri","The Ard Ri",[20,3162,3163,3164,3167,3168,3170,3171,3174],{},"The concept of the High King -- the ",[312,3165,3166],{},"Ard Ri"," -- stands at the center of Irish historical tradition. According to the medieval annals, Ireland was ruled by a succession of High Kings stretching back into the mists of pre-Christian antiquity, each claiming sovereignty over the entire island from the sacred seat of ",[98,3169,1038],{"href":1034}," in County Meath. The list of High Kings recorded in texts like the ",[312,3172,3173],{},"Lebor Gabala Erenn"," and the various annalistic traditions runs to well over a hundred names, beginning with mythological figures and gradually shading into historical personages.",[20,3176,3177],{},"The reality is more complicated and more interesting than the legend. The High Kingship was not a unified institution with consistent powers throughout Irish history. It evolved from a largely symbolic or mythological concept into a genuine, if contested, political reality over the course of centuries. Understanding the distinction between the mythological High Kings and the historical ones is essential for anyone interested in the roots of Irish and, by extension, Scottish and Atlantic Celtic identity.",[15,3179,3181],{"id":3180},"the-mythological-kings","The Mythological Kings",[20,3183,3184,3185,3187],{},"The earliest \"High Kings\" in the Irish tradition are not historical figures but characters from the mythological cycles. The ",[98,3186,326],{"href":325}," assigns kingship to the successive waves of mythical settlers who colonized Ireland -- the Fir Bolg, the Tuatha De Danann, and the Milesians. These kings belong to a different order of narrative, one in which gods and humans intermingle and the landscape itself is shaped by royal power.",[20,3189,3190],{},"The transition from mythology to legend occurs with figures like Conn of the Hundred Battles, Cormac mac Airt, and Niall of the Nine Hostages. These figures occupy a gray zone between myth and history. Niall, traditionally placed in the late fourth and early fifth centuries AD, is the ancestor claimed by the Ui Neill dynasty, which dominated northern and central Ireland for centuries. Ancient DNA studies have identified a Y-chromosome signature associated with a rapid male-line expansion in Ireland roughly consistent with Niall's traditional dates, lending some credibility to the tradition of a powerful early figure whose descendants proliferated across the island.",[20,3192,3193],{},"Whether Niall was a historical individual or a legendary composite, the political reality he represents -- a powerful northern dynasty claiming preeminence over other Irish kingdoms -- is well attested in the historical record.",[15,3195,3197],{"id":3196},"the-historical-high-kingship","The Historical High Kingship",[20,3199,3200],{},"From roughly the sixth century AD onward, the High Kingship becomes a genuinely historical institution, though one that was always contested and never carried the kind of centralized authority that the word \"king\" implies in a modern context.",[20,3202,3203,3204,3207],{},"Ireland in the early medieval period was divided into dozens of small kingdoms (",[312,3205,3206],{},"tuatha","), grouped into larger provincial kingdoms -- Ulster, Connacht, Munster, Leinster, and Meath. The High Kingship was claimed by the dominant king of the moment, usually from one of the major dynasties: the Ui Neill (northern and southern branches), the Eoganachta of Munster, or later the Dal Cais of Thomond, from whom Brian Boru emerged.",[20,3209,3210,3211,3214],{},"The \"High King with opposition\" (",[312,3212,3213],{},"Ard Ri co fressabra",") was the more common reality -- a king powerful enough to demand hostages and tribute from other provincial kings but unable to exercise direct administrative control over the entire island. The \"High King without opposition\" was rare and perhaps never fully achieved until Brian Boru briefly unified Ireland under his authority in the early eleventh century.",[20,3216,3217],{},"Brian Boru is the most famous of the historical High Kings. A king of the Dal Cais who rose from relative obscurity to challenge and overthrow the Ui Neill monopoly on the High Kingship, Brian conquered or extracted submission from every provincial king in Ireland. His victory at the Battle of Clontarf in 1014, in which he defeated a coalition of Dublin Norse, Leinster rebels, and Orkney Vikings, cemented his legend -- though Brian himself was killed in the battle.",[15,3219,3221],{"id":3220},"what-the-high-kingship-meant","What the High Kingship Meant",[20,3223,3224,3225,3227],{},"The High Kingship was not a modern state office. It was a supremacy claim within a segmentary political system. The High King did not levy taxes across Ireland, did not maintain a standing army, and did not administer a bureaucracy. His power rested on military prestige, the submission of other kings (often expressed through the giving of hostages), and the symbolic authority conferred by association with ",[98,3226,1038],{"href":1034}," and the traditions of sovereignty.",[20,3229,3230,3231,139],{},"The inauguration of a king in early Ireland was a ritual act with deep mythological resonance. The king was said to be \"married\" to the land, and the prosperity of the kingdom depended on the righteousness of the ruler. A just king brought good harvests, calm seas, and victory in war. An unjust king brought famine, plague, and defeat. This concept of sacred kingship -- the ruler as the embodiment of the land's fertility -- is one of the most distinctive features of Celtic political thought and has parallels in other ",[98,3232,3234],{"href":3233},"/blog/indo-european-migration-theory","Indo-European traditions",[20,3236,3237,3238,3240],{},"For those tracing Irish or Scottish heritage, the High Kings matter because the genealogical claims of later Irish and Scottish families -- including those that became Highland clans -- often trace back to royal lineages. The ",[98,3239,563],{"href":151}," scattered these lineages across the world, but the genealogical traditions they carried preserved the memory of royal origins that connected ordinary families to the High Kings of Ireland and the ancient system of Celtic sovereignty.",{"title":213,"searchDepth":214,"depth":214,"links":3242},[3243,3244,3245,3246],{"id":3159,"depth":217,"text":3160},{"id":3180,"depth":217,"text":3181},{"id":3196,"depth":217,"text":3197},{"id":3220,"depth":217,"text":3221},"The High Kingship of Ireland, centered at the Hill of Tara, is one of the most enduring institutions in Celtic tradition. Separating historical reality from mythological embellishment reveals a complex political system that shaped Irish identity for over a millennium.",[3249,3250,3251,3252,3253,3254],"high kings ireland","irish high kings history","ard ri ireland","tara high kingship","irish kingship history","celtic kings ireland",{},{"title":3153,"description":3247},"blog/irish-high-kings-history",[965,1039,3259,1038,836],"Celtic Kingship","TTZP8XDTyOYisA8MPZVepDwaLI-biopYbXV7tlfNOsk",{"id":3262,"title":3263,"author":3264,"body":3265,"category":2197,"date":2703,"description":3448,"extension":227,"featured":228,"image":229,"keywords":3449,"meta":3452,"navigation":237,"path":3453,"readTime":829,"seo":3454,"stem":3455,"tags":3456,"__hash__":3459},"blog/blog/landing-page-optimization.md","Landing Page Optimization: The Technical Side",{"name":9,"bio":10},{"type":12,"value":3266,"toc":3442},[3267,3271,3274,3277,3280,3288,3290,3294,3297,3300,3315,3334,3345,3352,3354,3358,3361,3368,3388,3398,3401,3403,3407,3410,3425,3428,3436,3439],[15,3268,3270],{"id":3269},"performance-is-the-first-conversion-factor","Performance Is the First Conversion Factor",[20,3272,3273],{},"Marketing teams optimize headlines, copy, and button colors. Those optimizations are meaningless if the page takes 5 seconds to load because 53% of mobile users abandon pages that take longer than 3 seconds to become interactive. The highest-converting landing page in the world converts zero visitors who leave before seeing it.",[20,3275,3276],{},"Landing page performance is not the same problem as general web performance. A landing page has a specific job: load fast, communicate a value proposition, and move the visitor toward a single action. Every technical decision should support that job. Third-party scripts that add 2 seconds of load time for analytics you will never look at are actively working against conversion. A hero image that takes 3 seconds to render is hiding your value proposition during the critical first impression.",[20,3278,3279],{},"The technical baseline for a high-converting landing page: Largest Contentful Paint under 2 seconds, First Input Delay under 100ms, Cumulative Layout Shift under 0.1, and a total page weight under 500KB compressed. These are achievable with modern tooling — the challenge is not technical capability but discipline in saying no to features and scripts that add weight without proportional value.",[20,3281,3282,3283,3287],{},"Start by measuring where you are. Run a ",[98,3284,3286],{"href":3285},"/blog/web-app-performance-audit","performance audit"," on your current landing pages. You will almost certainly find that third-party scripts (analytics, chat widgets, retargeting pixels) account for more load time than your actual page content. That is the first optimization target.",[185,3289],{},[15,3291,3293],{"id":3292},"critical-rendering-path-for-landing-pages","Critical Rendering Path for Landing Pages",[20,3295,3296],{},"The critical rendering path is the sequence of steps the browser takes to go from receiving HTML to painting pixels on screen. For landing pages, optimizing this path is the highest-leverage technical work you can do.",[20,3298,3299],{},"The browser must download HTML, parse it, fetch CSS (which blocks rendering), fetch JavaScript (which blocks parsing by default), construct the DOM and CSSOM, calculate layout, and paint. Every resource in this chain adds latency.",[20,3301,3302,3303,3306,3307,3310,3311,3314],{},"Inline your critical CSS directly in the ",[1068,3304,3305],{},"\u003Chead>"," tag. Critical CSS is the subset of styles needed to render the above-the-fold content — typically 10-15KB. When CSS is inlined, the browser can render the visible content immediately without waiting for an external stylesheet to download. Load the full stylesheet asynchronously using ",[1068,3308,3309],{},"media=\"print\" onload=\"this.media='all'\""," or the ",[1068,3312,3313],{},"rel=\"preload\""," pattern.",[20,3316,3317,3318,315,3321,3324,3325,3328,3329,3333],{},"Defer all JavaScript. A landing page's primary content is static — the heading, copy, hero image, and CTA button do not require JavaScript to render. Add ",[1068,3319,3320],{},"defer",[1068,3322,3323],{},"async"," attributes to every script tag, or better yet, move scripts to the bottom of the ",[1068,3326,3327],{},"\u003Cbody>",". If you are using a framework like Nuxt, ensure you are ",[98,3330,3332],{"href":3331},"/blog/nuxt-performance-optimization","leveraging its SSR capabilities"," so the full HTML is delivered without waiting for JavaScript hydration.",[20,3335,3336,3337,3340,3341,3344],{},"Preload critical resources. The browser discovers resources as it parses HTML — it will not start downloading a hero image until it encounters the ",[1068,3338,3339],{},"\u003Cimg>"," tag, which might be hundreds of lines into the document. Use ",[1068,3342,3343],{},"\u003Clink rel=\"preload\">"," for the hero image, the primary font file, and any critical above-the-fold assets. This tells the browser to start downloading them immediately, in parallel with HTML parsing.",[20,3346,3347,3348,3351],{},"Serve images in modern formats. A WebP hero image is typically 30-50% smaller than JPEG at equivalent quality. AVIF is even smaller. Use the ",[1068,3349,3350],{},"\u003Cpicture>"," element with format fallbacks to serve the best format each browser supports.",[185,3353],{},[15,3355,3357],{"id":3356},"layout-stability-and-visual-trust","Layout Stability and Visual Trust",[20,3359,3360],{},"Layout shifts destroy user trust. When a visitor begins reading your headline and the page suddenly jumps because an image loaded or a font swapped, it feels broken. On a landing page, that broken feeling translates directly to distrust and abandonment.",[20,3362,3363,3364,3367],{},"Set explicit width and height on every image and video element. Use CSS ",[1068,3365,3366],{},"aspect-ratio"," for responsive elements. This reserves the correct space in the layout before the resource loads, eliminating content shifts.",[20,3369,3370,3371,3374,3375,3378,3379,3382,3383,3387],{},"Font loading is a common source of layout shifts. When a web font loads and replaces a fallback font, text reflows because the fonts have different metrics. Use ",[1068,3372,3373],{},"font-display: optional"," for body text (which keeps the fallback font if the web font does not load within 100ms) or ",[1068,3376,3377],{},"font-display: swap"," with ",[1068,3380,3381],{},"size-adjust"," to match the fallback font's metrics to the web font. For landing pages, strongly consider using ",[98,3384,3386],{"href":3385},"/blog/web-fonts-performance","optimized system font stacks"," that eliminate the web font loading problem entirely.",[20,3389,3390,3391,3394,3395,139],{},"Do not lazy-load above-the-fold images. Lazy loading is a performance optimization for images below the viewport — it delays loading images the user cannot see yet. Applying it to the hero image means showing a blank space or placeholder during the most important moment of the page load. The hero image should preload eagerly with ",[1068,3392,3393],{},"loading=\"eager\""," (the default) and ",[1068,3396,3397],{},"fetchpriority=\"high\"",[20,3399,3400],{},"Test layout stability with Chrome DevTools' Layout Shift Regions visualization. Load your page on a throttled connection and watch for any elements that shift position. Every shift is a CLS contributor and a potential moment of user distrust.",[185,3402],{},[15,3404,3406],{"id":3405},"forms-and-cta-performance","Forms and CTA Performance",[20,3408,3409],{},"The call-to-action is the entire point of a landing page, yet CTAs are frequently the worst-performing element. Buttons that depend on JavaScript to function fail during script loading. Forms that submit to slow APIs leave users staring at spinners. Validation that only runs on submit rather than inline forces users through a frustrating trial-and-error loop.",[20,3411,3412,3413,3416,3417,3420,3421,3424],{},"Build the CTA as a native HTML element. A ",[1068,3414,3415],{},"\u003Cbutton>"," inside a ",[1068,3418,3419],{},"\u003Cform>"," with a proper ",[1068,3422,3423],{},"action"," attribute works without JavaScript. Progressive enhancement means the form functions in its most basic state and JavaScript adds polish — inline validation, loading states, and error handling — on top. If JavaScript fails to load (which happens more often than developers think, especially on mobile), the form still works.",[20,3426,3427],{},"Keep form fields to an absolute minimum. Every field you add reduces completion rates. For lead generation, name and email are usually sufficient. For sign-ups, email and password. If you need more information, collect it in a second step after the initial conversion.",[20,3429,3430,3431,3435],{},"Implement inline validation that shows errors as soon as the user moves to the next field. Do not wait for form submission to reveal that the email format is wrong. Use the ",[98,3432,3434],{"href":3433},"/blog/web-forms-best-practices","form design patterns"," that respect user time and reduce frustration.",[20,3437,3438],{},"The submit action itself needs to be fast and provide immediate feedback. Show a loading indicator the instant the button is clicked. Disable the button to prevent double submission. If the API response takes more than 200ms, users start wondering if the click registered. For critical landing page forms, consider posting to an edge function that responds in under 100ms and processes the data asynchronously, rather than waiting for a round trip to a traditional server.",[20,3440,3441],{},"After successful submission, provide a clear confirmation. Redirecting to a thank-you page is common but adds latency. An inline success message that replaces the form is faster and keeps the user on the page where they can share the URL or explore further.",{"title":213,"searchDepth":214,"depth":214,"links":3443},[3444,3445,3446,3447],{"id":3269,"depth":217,"text":3270},{"id":3292,"depth":217,"text":3293},{"id":3356,"depth":217,"text":3357},{"id":3405,"depth":217,"text":3406},"Landing page optimization is not just about copy and design. The technical implementation determines whether visitors stay long enough to convert.",[3450,3451],"landing page optimization","landing page performance",{},"/blog/landing-page-optimization",{"title":3263,"description":3448},"blog/landing-page-optimization",[3457,3458,2197],"Performance","Conversion","_0_O_RwyMH5Dp-Yk90NhLZ9Qr2_ZwnZ2ysREP1paTRk",[3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3494,3495,3496,3497,3498,3499,3500,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,3512,3514,3515,3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698,3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,3714,3715,3716,3717,3718,3719,3720,3721,3722,3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105],{"category":2197},{"category":224},{"category":2702},{"category":2309},{"category":693},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":2702},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":3493},"Architecture",{"category":3493},{"category":2309},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":3501},"Security",{"category":3501},{"category":693},{"category":693},{"category":224},{"category":3501},{"category":224},{"category":3493},{"category":3501},{"category":2309},{"category":693},{"category":3513},"DevOps",{"category":2702},{"category":224},{"category":2309},{"category":3493},{"category":2309},{"category":224},{"category":224},{"category":224},{"category":3493},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":3513},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":2309},{"category":3546},"Career",{"category":2702},{"category":2702},{"category":693},{"category":3493},{"category":693},{"category":2309},{"category":2309},{"category":693},{"category":2309},{"category":3493},{"category":2309},{"category":3513},{"category":3513},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":3493},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":2702},{"category":3493},{"category":693},{"category":3513},{"category":3513},{"category":3513},{"category":224},{"category":2309},{"category":2309},{"category":224},{"category":2197},{"category":2702},{"category":3513},{"category":3513},{"category":3501},{"category":3513},{"category":693},{"category":2702},{"category":224},{"category":2309},{"category":224},{"category":3493},{"category":224},{"category":3493},{"category":3501},{"category":224},{"category":224},{"category":2309},{"category":693},{"category":2309},{"category":2197},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":693},{"category":693},{"category":224},{"category":2197},{"category":3501},{"category":3493},{"category":3501},{"category":2197},{"category":2309},{"category":2309},{"category":3513},{"category":2309},{"category":2309},{"category":3493},{"category":2309},{"category":3513},{"category":2309},{"category":2309},{"category":224},{"category":224},{"category":3501},{"category":3493},{"category":3493},{"category":3546},{"category":3546},{"category":3546},{"category":693},{"category":2309},{"category":3513},{"category":3493},{"category":224},{"category":224},{"category":3513},{"category":3493},{"category":3493},{"category":2197},{"category":2309},{"category":224},{"category":224},{"category":2309},{"category":224},{"category":3513},{"category":3513},{"category":224},{"category":3501},{"category":224},{"category":3493},{"category":3501},{"category":3493},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":3501},{"category":2309},{"category":3513},{"category":3513},{"category":693},{"category":2309},{"category":2309},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":3493},{"category":3493},{"category":3493},{"category":2309},{"category":224},{"category":224},{"category":224},{"category":3513},{"category":693},{"category":224},{"category":224},{"category":2309},{"category":224},{"category":2309},{"category":2197},{"category":224},{"category":693},{"category":693},{"category":2309},{"category":2309},{"category":2702},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":2309},{"category":3513},{"category":3513},{"category":3513},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":224},{"category":3493},{"category":224},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":693},{"category":693},{"category":224},{"category":2309},{"category":2197},{"category":3493},{"category":3546},{"category":224},{"category":224},{"category":3501},{"category":2309},{"category":224},{"category":224},{"category":3513},{"category":224},{"category":2197},{"category":3513},{"category":3513},{"category":3501},{"category":2309},{"category":2309},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":3546},{"category":224},{"category":3493},{"category":2309},{"category":2309},{"category":224},{"category":3513},{"category":224},{"category":224},{"category":224},{"category":2197},{"category":224},{"category":224},{"category":2309},{"category":224},{"category":2309},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":2702},{"category":2702},{"category":2309},{"category":224},{"category":3513},{"category":3513},{"category":224},{"category":2309},{"category":224},{"category":224},{"category":2702},{"category":224},{"category":224},{"category":224},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":2309},{"category":2309},{"category":2309},{"category":3501},{"category":2309},{"category":2309},{"category":2197},{"category":2309},{"category":2197},{"category":2197},{"category":3501},{"category":3493},{"category":2309},{"category":3493},{"category":224},{"category":224},{"category":2309},{"category":2309},{"category":2309},{"category":693},{"category":2309},{"category":2309},{"category":224},{"category":3493},{"category":2702},{"category":2702},{"category":224},{"category":224},{"category":224},{"category":224},{"category":693},{"category":2309},{"category":224},{"category":224},{"category":2309},{"category":2309},{"category":2197},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":2309},{"category":3493},{"category":224},{"category":693},{"category":2702},{"category":224},{"category":693},{"category":3501},{"category":224},{"category":3501},{"category":2309},{"category":3513},{"category":224},{"category":224},{"category":2309},{"category":224},{"category":3493},{"category":224},{"category":224},{"category":2309},{"category":693},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":693},{"category":2309},{"category":2309},{"category":693},{"category":3513},{"category":2309},{"category":2702},{"category":224},{"category":224},{"category":2309},{"category":2309},{"category":224},{"category":224},{"category":224},{"category":2702},{"category":2309},{"category":2309},{"category":3493},{"category":2197},{"category":2309},{"category":224},{"category":2309},{"category":3493},{"category":693},{"category":693},{"category":2197},{"category":2197},{"category":224},{"category":693},{"category":3501},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":3493},{"category":2309},{"category":2309},{"category":3493},{"category":2309},{"category":2309},{"category":2309},{"category":3936},"Programming",{"category":2309},{"category":2309},{"category":3493},{"category":3493},{"category":2309},{"category":2309},{"category":693},{"category":3501},{"category":2309},{"category":693},{"category":2309},{"category":2309},{"category":2309},{"category":2309},{"category":3513},{"category":3493},{"category":693},{"category":693},{"category":2309},{"category":2309},{"category":693},{"category":2309},{"category":3501},{"category":693},{"category":2309},{"category":2309},{"category":3493},{"category":3493},{"category":224},{"category":693},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":224},{"category":2197},{"category":224},{"category":3513},{"category":3501},{"category":3501},{"category":3501},{"category":3501},{"category":3501},{"category":3501},{"category":224},{"category":2309},{"category":3513},{"category":3493},{"category":3513},{"category":3493},{"category":2309},{"category":2197},{"category":224},{"category":3493},{"category":2197},{"category":224},{"category":224},{"category":224},{"category":3493},{"category":3493},{"category":3493},{"category":693},{"category":693},{"category":693},{"category":3493},{"category":3493},{"category":693},{"category":693},{"category":693},{"category":224},{"category":3501},{"category":2309},{"category":3513},{"category":2309},{"category":224},{"category":693},{"category":693},{"category":224},{"category":224},{"category":3493},{"category":2309},{"category":3493},{"category":3493},{"category":3493},{"category":2197},{"category":2309},{"category":224},{"category":224},{"category":693},{"category":693},{"category":3493},{"category":2309},{"category":3546},{"category":3493},{"category":3546},{"category":693},{"category":224},{"category":3493},{"category":224},{"category":224},{"category":224},{"category":2309},{"category":2309},{"category":224},{"category":2702},{"category":2702},{"category":3513},{"category":224},{"category":224},{"category":224},{"category":224},{"category":2309},{"category":2309},{"category":2197},{"category":2309},{"category":3501},{"category":3493},{"category":2197},{"category":2197},{"category":2309},{"category":2309},{"category":2197},{"category":2197},{"category":2197},{"category":3501},{"category":2309},{"category":2309},{"category":693},{"category":2309},{"category":3493},{"category":224},{"category":224},{"category":3493},{"category":224},{"category":224},{"category":3493},{"category":224},{"category":2309},{"category":224},{"category":3501},{"category":224},{"category":224},{"category":224},{"category":3513},{"category":3513},{"category":3501},1772951194584]