Eight Hour Architecture Specification Session
TL;DR - Session insights
- Longest session at nearly 8 hours, demonstrating agent persistence through extensive technical requirements specification work
- User provided comprehensive CONTEXT block defining 4 MCPs (note, todo, zet, graphviz) with explicit instructions for state externalization to survive context limits
- Requirements format specified with engineering company style: TECHREQ/SYSTEST keywords, bracketed IDs like [COMPOSE_BLOG_0001], and hash-tagged cross-references
- User emphasized asking questions for technical context, treating this as architecture work requiring deep technical decisions before specification
- POSA patterns (Layered, Pipes and Filters, Blackboard, Broker, MVC, PAC, Microkernel, Reflection) explicitly referenced as architectural vocabulary for decision-making
Session Log
USER: ## CONTEXT
We are going to build technical requirements and system tests. You have already discussed with the customer on their needs and captured everything as
NEEDitems (usingtodoMCP) and the acceptance criteria for these needs asVERIFYitems (usingtodoMCP). You have also spent time translating these two into formal requirements, captured asREQentries (usingtodoMCP) and associated QA tests asQAenteries (usingtodoMCP)You have access to a bunch of MCPs to help you work on these -
note,todo,zetandgraphviz.noteMCP - This is a notetaking MCP that follows the zettelkasten method. Each note is a zettel. All zettels are stored as markdown files. These files can contain project notes, outstanding tasks (see next point) and other information about the project.todoMCP - This is a unified task management tool that gives you access to outstanding tasks across all projects. This MCP sources its markdown files from those project directories thatnoteMCP works with.zetMCP - This is a freeform zettelkasten (close to how Niklas Luhmann envisioned it) that is used to hold notes that are not part of any project. This is my personal knowledge base and note taking space. Use this MCP when you want to look for knowledge that customer already has about things.graphvizMCP - This is a simple shell script that accepts graphviz content along with the diagram format to use and returns path to a temporary diagram file that you must then copy into the appropriate location in your project directory. Use this MCP when you want to include diagrams in the specifications to provide quicker clarity to the reader (remember the saying - “an image is worth a thousand words”?)
Since you are an AI agent with limited context window, you need to externalize all your notes, tasks and other project information so that you can continue where you left off, immaterial of whether you run out of context window or abruptly stop working for some reason beyond your control. So make sure you externalize and update information frequently.
ROLE
You are an experience architect with many decades of experience in converting formal product requirements into technical requirements for project teams. You pay lot of attention to detail and make sure the level of detail used to specify technical requirements is sufficient for project teams to have all the information to perform code level design and implement it.
- You a well versed with all the architecture patterns like “Layered architecture”, “Pipes and Filters”, “Blackboard”, “Broker”, “Model View Controller (MVC)”, “Presentation Abstraction Control (PAC)”, “Microkernel” and “Reflection” (all part of the POSA book written by engineers from Siemens AG).
- You are also well versed with “Service Oriented Architecture (SOA)” and all the standards associated with it that can be leveraged to deploy large scale SOA projects
- You prefer simplicity over standardization. While you know all possibile architecture and design patterns in the world, you like to keep things as simple as possible (and not any more simpler) because you know that long term stability requires comprehensible architectures that can be easily decomposed into any form or structure and still be usable.
- While you don’t work on code-design you are a big proponent of DRY, YAGNI and SOLID principles.
- You don’t like including design patterns that are programming language specific (or only used predominantly by practitioners of a specific language) since you are not responsible for making programming language / implementation level decisions.
NOTE: Like all other folks in the team here, you love to use RFC 2119 for requirements keywords and pay attention to the meaning of these keywords.
ADDITIONAL INSTRUCTIONS
General Instructions
- Technical requirements are architecture and high-level design specification captured in a similar structure as the product requirements you are using as the source.
- Technical requirements dig deeper into technical decisions and use those decisions to specify technical requirements.
- Technical requirements give equal weightage to product requirements, infrastructure requirements, user requirements, experience design requireements, security requirements as well as non-function requirements like performance, resilience, etc. (not all non-functional requirements are mentioned here. You need to think about all of them and apply)
- While you are focusing on all aspects of technical requirements (see previous point), you have to make sure they are listed in proper order so that the reader who is responsible for implementing it gets entire context required for implementation by reading adjacent requirements i.e., your technical requirements doc should read like a story, not an overly-formalized and overly-structured specification)
- Requriements from these areas must be kept adjacent to each other to make it easier for the reader to get full context.
- Technical requirements must be captured in a separate set of zettels in the same project.
- When creating zettels, each zettel MUST focus only on one product. Hence, the zettel file title must include a short product name to indicate the product as well as text to point out that this is a technical requirement zettel.
- You must style each requirement as a formal statement similar to how engineering companies (industrial automation, automotive, building automation, banks, government, etc.) do it.
- Technical requirements specification involves lot of decision making on technical choices. You can ask me questions to gain additional context for building these requirements and associated system test specifications.
Building technical requirements from product requirements
- Check if the required zettels for capturing technical requirements, across all applicable products, are already present. If not, create them.
- Use
todoMCP to look forREQtasks and pick one product requirement to work on.
- Read the content under that product requirement. Determine if it requires one or multiple technical requirement to satisfy that product requirement.
- Requirements must be created as
TECH_REQentries usingtodoMCP. Add each each technical requirement you define to the right zettel. - Each
TECH_REQitem must be structured like a formal requirements specification. You must follow RFC 2119 and use their requirements level specification for each requirement. You must style each requirement as a formal specification, similar to how engineering companies (industrial automation, automotive, building automation, banks, government, etc.) do it. - Each requirement should be structured as follows -
TECHREQ: [<3_TO_8_LETTER_PRODUCT_PLUS_TECH_AREA_KEYWORD>_0001] - <Short product name -> Tech requirement title> #<1_TO_4_LETTER_PRODUCT_KEYWORD>001 * Key information about the technical requirement along with specific technical information and decisions * Key information about the technical requirement along with specific technical information and decisions * Last point listing any references to external documents, websites, blogs, etc. that was used to build this requirement. Include other zettels (from my freeform `zet`) that you may have identified as being relevant for this requirement. + [link](reference URI) + [link](reference URI)a. The
TECHREQkeyword indicates that it is a technical requirement item for a specific product. b. The ID inside square brackets (for eg.,[COMPOSE_BLOG_0001]for a blog site) in the title description indicates the unique ID for that specific technical requirement. c. The#<1_TO_4_LETTER_PRODUCT_KEYWORD>001is a tag that indicates the product requirement ID to which this technical requirement is connected to. This lets you use tag searching with thetodoMCP to get all the technical requirements for a given product requirement.Building system tests to verify technnical requirements
- We need one or more system tests to confirm that each technical requirement has been implemented correctly.
- System tests must be added next to the product requirement item that they are testing. This lets us keep the requirements and associated tests together to improve readability.
- Use all the standard test design methods like like equivalence partitioning, boundary value analysis, etc. when creating QA tests.
- There may be more than one system test for a given technical requirement. Be a maximalist when creating system ests to make sure you’ve captured all kinds of tests - happy cases, alternate cases, boundary cases, failure cases, load cases, security cases, etc. Sometimes, this may mean that system test count is orders of magnitude bigger than the technical requirements count.
- We are not writing test scripts here. Rather, it is a test specification of how to test so that we can confirm if a specific technical requirement has been correctly implemented. This information will be fed to a system testing LLM agent who will run these test under minimal supervision. So be thorough in your test specifications.
- The level of detail must be deep enough that anyone reading these test specifications should be able to write automation test scripts to test the technical reuirement completely. The tests must stay true to the actual needs from the user and the formal requriement from the requirements analyst.
- The system test entry should be structured as follows -
SYSTEST: [<3_TO_8_LETTER_PRODUCT_PLUS_TECH_AREA_KEYWORD>_TEST_0001] - <Short product name -> System test title> #<3_TO_8_LETTER_PRODUCT_PLUS_TECH_AREA_KEYWORD>_0001 * Key information about the system test along with highly specific guidance on the setup and steps for the test * Key information about the system test along with highly specific guidance on the setup and steps for the test * (optional) Specific sub-scenario that must be tested as part of this test * (optional) Specific sub-scenario that must be tested as part of this test * Last point listing any references to external documents, websites, blogs, etc. that was used to build this test. Include other zettels (from my freeform `zet`) that you may have identified as being relevant for this test. + [link](reference URI) + [link](reference URI)- The
SYSTESTkeyword indicates that it is a system test. - The
[<3_TO_8_LETTER_PRODUCT_PLUS_TECH_AREA_KEYWORD>_TEST_0001]in the title description indicates the unique ID for this test. The_TEST_in the ID says that it is a system test. - The
#<3_TO_8_LETTER_PRODUCT_PLUS_TECH_AREA_KEYWORD>_0001is a tag that indicates the technical requirement ID to which this test is connected to. This lets you use tag searching with thetodoMCP to get the tests for a given technical requirement.
IMPORTANT: Technical requirements require lot more technical context than product requirements spec. So keep asking me questions as much as you want to gain this context. I will provide information on technical decisions made. You can then think deeply and critically of these resopnses in the context of everything captured for the products till now before feeling comfortable applying them to define technical requirements. It is imperative that you don’t stop till you are absolutely sure of the technical context and all other information required to build the biggest and most badass technical requirements specification ever!
TASK
- Go through every product requirement (look for
REQitems usingtodoMCP) and create one or more technical requirement to satisfy that product requirement. Follow the instructions for creating technical requirements when doing this. - For the technical requirement created just now, use the already picked
REQitem and pick one QA test for thatREQitem (look forQAitems usingtodoMCP). Use these as context to build detailed system test specifications to satisfy the technical requirement. Follow the instructions for creating system tests when doing this. - If you have completed work on the
REQandQAentries, mark them as “DONE” usingtodoMCP.
On a side note, don’t add unnecessary new lines in a zettel. One singe empty line is sufficient to separate headings from its content or to separate logical parts of the content.
TOOL-CALL: mcp_todo_list_tasks
{}TOOL-CALL: mcp_note_list_projects
{}TOOL:
{"count":151,"tasks":[{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N031","title":"[SL001] - Session Log Sync → GitHub Wiki Publication","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"SL001","title":"[SL_QA_001] - Session Log Sync → Wiki Publication Test","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N033","title":"[SL002] - Session Log Sync → Independent Updates","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"SL002","title":"[SL_QA_002] - Session Log Sync → Independent Updates Test","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N034","title":"[SL003] - Session Log Sync → Automatic Synchronization","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"SL003","title":"[SL_QA_003] - Session Log Sync → Automatic Sync Test","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N034","title":"[SL004] - Session Log Sync → GitHub Actions Workflow","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"SL004","title":"[SL_QA_004] - Session Log Sync → Workflow Implementation Test","zettel":"20260105040109"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N035","title":"[CX001] - crush-export → Session Data Processing","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"CX001","title":"[CX_QA_001] - crush-export → Session Processing Test","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N036","title":"[CX002] - crush-export → Metadata Extraction","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"CX002","title":"[CX_QA_002] - crush-export → Metadata Extraction Test","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N032","title":"[CX003] - crush-export → Document Structure","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"CX003","title":"[CX_QA_003] - crush-export → Document Structure Test","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N035","title":"[CX004] - crush-export → Command-Line Interface","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"CX004","title":"[CX_QA_004] - crush-export → CLI Interface Test","zettel":"20260105040107"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N001","title":"[BP001] - Blog Platform → Primary URL Endpoint","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP001","title":"[BP_QA_001] - Blog Platform → Primary URL Accessibility Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N002","title":"[BP002] - Blog Platform → JavaScript-Free Core Functionality","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP002","title":"[BP_QA_002] - Blog Platform → JavaScript-Free Operation Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N003","title":"[BP003] - Blog Platform → Responsive Layout Design","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP003","title":"[BP_QA_003] - Blog Platform → Responsive Layout Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N004","title":"[BP004] - Blog Platform → Performance Optimization","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP004","title":"[BP_QA_004] - Blog Platform → Performance Metrics Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N005","title":"[BP005] - Blog Platform → Continuous Deployment Pipeline","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP005","title":"[BP_QA_005] - Blog Platform → Continuous Deployment Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N006","title":"[BP006] - Blog Platform → CLI Browser Compatibility","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP006","title":"[BP_QA_006] - Blog Platform → CLI Browser Compatibility Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N007","title":"[BP007] - Blog Platform → Tmux-Inspired Interface Design","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP007","title":"[BP_QA_007] - Blog Platform → Tmux-Inspired Design Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N008","title":"[BP008] - Blog Platform → Dual Theme Color System","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP008","title":"[BP_QA_008] - Blog Platform → Dual Theme Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N009","title":"[BP009] - Blog Platform → Theme Toggle Control","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP009","title":"[BP_QA_009] - Blog Platform → Theme Toggle Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N010","title":"[BP010] - Blog Platform → Typography System","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP010","title":"[BP_QA_010] - Blog Platform → Typography Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N011","title":"[BP011] - Blog Platform → CSS Border Styling","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP011","title":"[BP_QA_011] - Blog Platform → CSS Border Styling Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N012","title":"[BP012] - Blog Platform → Week Navigation Status Bar","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP012","title":"[BP_QA_012] - Blog Platform → Week Navigation Status Bar Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N013","title":"[BP013] - Blog Platform → Week Number Tooltips","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP013","title":"[BP_QA_013] - Blog Platform → Week Tooltips Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N014","title":"[BP014] - Blog Platform → Weekly Index Navigation Link","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP014","title":"[BP_QA_014] - Blog Platform → Weekly Index Link Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N015","title":"[BP015] - Blog Platform → Footer Navigation Bar","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP015","title":"[BP_QA_015] - Blog Platform → Footer Navigation Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N016","title":"[BP016] - Blog Platform → Accessible Navigation Labels","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP016","title":"[BP_QA_016] - Blog Platform → Navigation Labels Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N017","title":"[BP017] - Blog Platform → Table of Contents","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP017","title":"[BP_QA_017] - Blog Platform → Table of Contents Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N018","title":"[BP018] - Blog Platform → Sticky Section Indicator","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP018","title":"[BP_QA_018] - Blog Platform → Section Indicator Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N019","title":"[BP019] - Blog Platform → About Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP019","title":"[BP_QA_019] - Blog Platform → About Page Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N020","title":"[BP020] - Blog Platform → Weekly Index Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP020","title":"[BP_QA_020] - Blog Platform → Weekly Index Page Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N021","title":"[BP021] - Blog Platform → Reports Section","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP021","title":"[BP_QA_021] - Blog Platform → Reports Section Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N022","title":"[BP022] - Blog Platform → Community Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP022","title":"[BP_QA_022] - Blog Platform → Community Page Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N023","title":"[BP023] - Blog Platform → Blog Index Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP023","title":"[BP_QA_023] - Blog Platform → Blog Index Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N024","title":"[BP024] - Blog Platform → Weekly Post URL Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP024","title":"[BP_QA_024] - Blog Platform → Weekly Post URL Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N025","title":"[BP025] - Blog Platform → Monthly Report URL Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP025","title":"[BP_QA_025] - Blog Platform → Monthly Report URL Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N026","title":"[BP026] - Blog Platform → Quarterly Report URL Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP026","title":"[BP_QA_026] - Blog Platform → Quarterly Report URL Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N027","title":"[BP027] - Blog Platform → Post Metadata Display","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP027","title":"[BP_QA_027] - Blog Platform → Post Metadata Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N028","title":"[BP028] - Blog Platform → Previous/Next Post Navigation","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP028","title":"[BP_QA_028] - Blog Platform → Post Navigation Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N029","title":"[BP029] - Blog Platform → Session Log Links","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP029","title":"[BP_QA_029] - Blog Platform → Session Log Links Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N030","title":"[BP030] - Blog Platform → Repository/Code Links","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP030","title":"[BP_QA_030] - Blog Platform → Repository Links Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N037","title":"[BP031] - Blog Platform → RSS/Atom Feed","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP031","title":"[BP_QA_031] - Blog Platform → RSS Feed Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N038","title":"[BP032] - Blog Platform → Basic Meta Tags","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP032","title":"[BP_QA_032] - Blog Platform → Basic Meta Tags Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N039","title":"[BP033] - Blog Platform → Open Graph Meta Tags","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP033","title":"[BP_QA_033] - Blog Platform → Open Graph Tags Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N040","title":"[BP034] - Blog Platform → Twitter Card Meta Tags","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP034","title":"[BP_QA_034] - Blog Platform → Twitter Cards Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N041","title":"[BP035] - Blog Platform → XML Sitemap","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP035","title":"[BP_QA_035] - Blog Platform → Sitemap Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N042","title":"[BP036] - Blog Platform → JSON-LD Structured Data","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP036","title":"[BP_QA_036] - Blog Platform → JSON-LD Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N043","title":"[BP037] - Blog Platform → Social Card Images","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP037","title":"[BP_QA_037] - Blog Platform → Social Card Images Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N044","title":"[BP038] - Blog Platform → GitHub Discussion Links","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP038","title":"[BP_QA_038] - Blog Platform → Discussion Links Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N045","title":"[BP039] - Blog Platform → Discussion Deep Linking","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP039","title":"[BP_QA_039] - Blog Platform → Discussion Deep Linking Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N046","title":"[BP040] - Blog Platform → Semantic HTML Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP040","title":"[BP_QA_040] - Blog Platform → Semantic HTML Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N047","title":"[BP041] - Blog Platform → Image Alt Text","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP041","title":"[BP_QA_041] - Blog Platform → Image Alt Text Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N048","title":"[BP042] - Blog Platform → Skip to Content Link","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP042","title":"[BP_QA_042] - Blog Platform → Skip Navigation Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N049","title":"[BP043] - Blog Platform → Keyboard Navigation","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP043","title":"[BP_QA_043] - Blog Platform → Keyboard Navigation Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N050","title":"[BP044] - Blog Platform → Color Contrast Compliance","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP044","title":"[BP_QA_044] - Blog Platform → Color Contrast Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N051","title":"[BP045] - Blog Platform → Logical Reading Order","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP045","title":"[BP_QA_045] - Blog Platform → Reading Order Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N052","title":"[BP046] - Blog Platform → Markdown Authoring","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP046","title":"[BP_QA_046] - Blog Platform → Markdown Authoring Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N053","title":"[BP047] - Blog Platform → Syntax Highlighting","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP047","title":"[BP_QA_047] - Blog Platform → Syntax Highlighting Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N054","title":"[BP048] - Blog Platform → Callout Boxes","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP048","title":"[BP_QA_048] - Blog Platform → Callout Boxes Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N055","title":"[BP049] - Blog Platform → Local Preview","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP049","title":"[BP_QA_049] - Blog Platform → Local Preview Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N056","title":"[BP050] - Blog Platform → Server-Side Analytics","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP050","title":"[BP_QA_050] - Blog Platform → Analytics Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N057","title":"[BP051] - Blog Platform → Community Repository Display","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP051","title":"[BP_QA_051] - Blog Platform → Community Repository Display Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N058","title":"[BP052] - Blog Platform → Repository Information Display","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP052","title":"[BP_QA_052] - Blog Platform → Repository Information Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N059","title":"[BP053] - Blog Platform → API Failure Handling","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP053","title":"[BP_QA_053] - Blog Platform → API Failure Handling Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N060","title":"[BP054] - Blog Platform → Community Empty State","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP054","title":"[BP_QA_054] - Blog Platform → Empty State Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N061","title":"[BP055] - Blog Platform → Client-Side API Caching","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP055","title":"[BP_QA_055] - Blog Platform → API Caching Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N062","title":"[BP056] - Blog Platform → Site Branding","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP056","title":"[BP_QA_056] - Blog Platform → Branding Test","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N063","title":"[BP057] - Blog Platform → Consistent Header","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"QA","priority":2,"project":"52vibes","status":"active","tag":"BP057","title":"[BP_QA_057] - Blog Platform → Consistent Header Test","zettel":"20260105040104"},{"assignee":"Vinay","file_path":"~/Documents/projects/97things/notes/20251016025013/README.md","keyword":"TODO","priority":2,"project":"97things","status":"active","tag":"priority:high","title":"Expand on attack modeling as a key step in SSDLC","zettel":"20251016025013"},{"due_at":"2026-12-31","file_path":"~/Documents/projects/97things/notes/20251016025013/README.md","keyword":"TODO","priority":2,"project":"97things","status":"active","title":"Create a dedicated Product Security Engineering textbook","zettel":"20251016025013"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203706/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Define detection rules for each threat category","zettel":"20251226203706"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203706/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Map threats to AWS-native controls","zettel":"20251226203706"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203429/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Conduct stakeholder review of key decisions","zettel":"20251226203429"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203429/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Finalize scope based on decisions","zettel":"20251226203429"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203429/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Begin detailed requirements specification","zettel":"20251226203429"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203742/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Create compliance checklist per regulation","zettel":"20251226203742"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203742/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Define evidence collection mechanisms for AWS","zettel":"20251226203742"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203917/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Schedule stakeholder discussion on these decisions","zettel":"20251226203917"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203917/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Document decision outcomes after discussion","zettel":"20251226203917"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226210953/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Review and validate business requirements with stakeholders","zettel":"20251226210953"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226210953/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Prioritize requirements for MVP scope","zettel":"20251226210953"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226210953/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Derive functional requirements from business requirements","zettel":"20251226210953"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203535/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Create detailed AWS API mapping for AI workload discovery","zettel":"20251226203535"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203813/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Define detailed user stories per persona","zettel":"20251226203813"},{"file_path":"~/Documents/projects/ai.spm.prod/notes/20251226203813/README.md","keyword":"TODO","priority":2,"project":"ai.spm.prod","status":"active","title":"Create capability-to-feature mapping","zettel":"20251226203813"},{"file_path":"~/Documents/projects/feature-x/notes/20251226072510/README.md","keyword":"TODO","priority":2,"project":"feature-x","status":"active","title":"Define detailed user stories","zettel":"20251226072510"},{"file_path":"~/Documents/projects/feature-x/notes/20251226072511/README.md","keyword":"TODO","priority":2,"project":"feature-x","status":"active","title":"Create API specification document","zettel":"20251226072511"},{"file_path":"~/Documents/projects/feature-x/notes/20251226072511/README.md","keyword":"TODO","priority":2,"project":"feature-x","status":"active","title":"Set up development environment","zettel":"20251226072511"},{"file_path":"~/Documents/projects/multiagent/notes/20251117183249/README.md","keyword":"TODO","priority":2,"project":"multiagent","status":"active","title":"Send context from current editor to a agent CLI","zettel":"20251117183249"}]}TOOL:
{"count":49,"projects":[{"has_notes":true,"name":"52vibes","note_count":13,"path":"~/Documents/projects/52vibes","task_count":0},{"has_notes":true,"name":"97things","note_count":2,"path":"~/Documents/projects/97things","task_count":2},{"has_notes":false,"name":"AI","note_count":0,"path":"~/Documents/projects/AI","task_count":0},{"has_notes":false,"name":"ARCHIVES","note_count":0,"path":"~/Documents/projects/ARCHIVES","task_count":0},{"has_notes":true,"name":"Karya MCP testing","note_count":12,"path":"~/Documents/projects/Karya MCP testing","task_count":0},{"has_notes":false,"name":"Programming","note_count":0,"path":"~/Documents/projects/Programming","task_count":0},{"has_notes":false,"name":"Startup","note_count":0,"path":"~/Documents/projects/Startup","task_count":0},{"has_notes":false,"name":"addb","note_count":0,"path":"~/Documents/projects/addb","task_count":0},{"has_notes":false,"name":"adm","note_count":0,"path":"~/Documents/projects/adm","task_count":0},{"has_notes":false,"name":"adm-web","note_count":0,"path":"~/Documents/projects/adm-web","task_count":0},{"has_notes":false,"name":"ads","note_count":0,"path":"~/Documents/projects/ads","task_count":0},{"has_notes":false,"name":"adsm","note_count":0,"path":"~/Documents/projects/adsm","task_count":0},{"has_notes":false,"name":"adsm-workspace","note_count":0,"path":"~/Documents/projects/adsm-workspace","task_count":0},{"has_notes":true,"name":"ai.spm.prod","note_count":15,"path":"~/Documents/projects/ai.spm.prod","task_count":15},{"has_notes":false,"name":"aoc2025","note_count":0,"path":"~/Documents/projects/aoc2025","task_count":0},{"has_notes":false,"name":"build","note_count":0,"path":"~/Documents/projects/build","task_count":0},{"has_notes":false,"name":"build-tests","note_count":0,"path":"~/Documents/projects/build-tests","task_count":0},{"has_notes":false,"name":"colony.ai","note_count":0,"path":"~/Documents/projects/colony.ai","task_count":0},{"has_notes":false,"name":"crush-tests","note_count":0,"path":"~/Documents/projects/crush-tests","task_count":0},{"has_notes":false,"name":"dac","note_count":0,"path":"~/Documents/projects/dac","task_count":0},{"has_notes":false,"name":"dac-experiment","note_count":0,"path":"~/Documents/projects/dac-experiment","task_count":0},{"has_notes":false,"name":"devnode","note_count":0,"path":"~/Documents/projects/devnode","task_count":0},{"has_notes":false,"name":"distributed-storage","note_count":0,"path":"~/Documents/projects/distributed-storage","task_count":0},{"has_notes":false,"name":"dotfiles","note_count":0,"path":"~/Documents/projects/dotfiles","task_count":0},{"has_notes":false,"name":"dsync","note_count":0,"path":"~/Documents/projects/dsync","task_count":0},{"has_notes":true,"name":"feature-x","note_count":2,"path":"~/Documents/projects/feature-x","task_count":3},{"has_notes":true,"name":"finance","note_count":1,"path":"~/Documents/projects/finance","task_count":0},{"has_notes":false,"name":"gherkinmatch","note_count":0,"path":"~/Documents/projects/gherkinmatch","task_count":0},{"has_notes":false,"name":"gherkinplus","note_count":0,"path":"~/Documents/projects/gherkinplus","task_count":0},{"has_notes":false,"name":"gof-patterns-spec","note_count":0,"path":"~/Documents/projects/gof-patterns-spec","task_count":0},{"has_notes":false,"name":"gtd","note_count":0,"path":"~/Documents/projects/gtd","task_count":0},{"has_notes":false,"name":"homelab","note_count":0,"path":"~/Documents/projects/homelab","task_count":0},{"has_notes":false,"name":"homelab-mk1","note_count":0,"path":"~/Documents/projects/homelab-mk1","task_count":0},{"has_notes":false,"name":"homelab_old","note_count":0,"path":"~/Documents/projects/homelab_old","task_count":0},{"has_notes":false,"name":"homelab_older","note_count":0,"path":"~/Documents/projects/homelab_older","task_count":0},{"has_notes":false,"name":"karya","note_count":0,"path":"~/Documents/projects/karya","task_count":0},{"has_notes":true,"name":"lab","note_count":3,"path":"~/Documents/projects/lab","task_count":0},{"has_notes":true,"name":"lab.mk1","note_count":1,"path":"~/Documents/projects/lab.mk1","task_count":0},{"has_notes":false,"name":"learn-c","note_count":0,"path":"~/Documents/projects/learn-c","task_count":0},{"has_notes":false,"name":"learn_llm","note_count":0,"path":"~/Documents/projects/learn_llm","task_count":0},{"has_notes":false,"name":"local.ai","note_count":0,"path":"~/Documents/projects/local.ai","task_count":0},{"has_notes":true,"name":"multiagent","note_count":1,"path":"~/Documents/projects/multiagent","task_count":1},{"has_notes":false,"name":"omnisource","note_count":0,"path":"~/Documents/projects/omnisource","task_count":0},{"has_notes":false,"name":"pipal","note_count":0,"path":"~/Documents/projects/pipal","task_count":0},{"has_notes":false,"name":"sdlc-as-code","note_count":0,"path":"~/Documents/projects/sdlc-as-code","task_count":0},{"has_notes":false,"name":"securitydesign.adm.vscode","note_count":0,"path":"~/Documents/projects/securitydesign.adm.vscode","task_count":0},{"has_notes":false,"name":"ssdlc","note_count":0,"path":"~/Documents/projects/ssdlc","task_count":0},{"has_notes":false,"name":"syspec","note_count":0,"path":"~/Documents/projects/syspec","task_count":0},{"has_notes":false,"name":"syspec_old","note_count":0,"path":"~/Documents/projects/syspec_old","task_count":0}]}AI: Let me examine the existing notes structure and read the product requirements to understand what we’re working with.
TOOL-CALL: mcp_note_list_notes
{"project":"52vibes"}TOOL-CALL: mcp_todo_filter_tasks
{"filter":"REQ","project":"52vibes"}TOOL:
{"count":13,"notes":[{"id":"20260105040109","path":"./notes/20260105040109/README.md","title":"Week 1: Requirements - Session Log Sync (SL)"},{"id":"20260105040107","path":"./notes/20260105040107/README.md","title":"Week 1: Requirements - crush-export Tool (CX)"},{"id":"20260105040104","path":"./notes/20260105040104/README.md","title":"Week 1: Requirements - Blog Platform (BP)"},{"id":"20260104215938","path":"./notes/20260104215938/README.md","title":"Week 1: Blog Platform Needs - Community Features and Branding"},{"id":"20260104215933","path":"./notes/20260104215933/README.md","title":"Week 1: Blog Platform Needs - Content Authoring and Analytics"},{"id":"20260104215928","path":"./notes/20260104215928/README.md","title":"Week 1: Blog Platform Needs - Engagement and Accessibility"},{"id":"20260104215922","path":"./notes/20260104215922/README.md","title":"Week 1: Blog Platform Needs - Discovery and SEO"},{"id":"20260104215917","path":"./notes/20260104215917/README.md","title":"Week 1: Blog Platform Needs - Session Logs"},{"id":"20260104215909","path":"./notes/20260104215909/README.md","title":"Week 1: Blog Platform Needs - Blog Posts"},{"id":"20260104215903","path":"./notes/20260104215903/README.md","title":"Week 1: Blog Platform Needs - Content Pages"},{"id":"20260104215858","path":"./notes/20260104215858/README.md","title":"Week 1: Blog Platform Needs - Navigation Structure"},{"id":"20260104215851","path":"./notes/20260104215851/README.md","title":"Week 1: Blog Platform Needs - Visual Design"},{"id":"20260104215844","path":"./notes/20260104215844/README.md","title":"Week 1: Blog Platform Needs - Core Platform"}],"project":"52vibes"}TOOL:
{"count":65,"tasks":[{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N035","title":"[CX001] - crush-export → Session Data Processing","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N036","title":"[CX002] - crush-export → Metadata Extraction","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N032","title":"[CX003] - crush-export → Document Structure","zettel":"20260105040107"},{"file_path":"./notes/20260105040107/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N035","title":"[CX004] - crush-export → Command-Line Interface","zettel":"20260105040107"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N031","title":"[SL001] - Session Log Sync → GitHub Wiki Publication","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N033","title":"[SL002] - Session Log Sync → Independent Updates","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N034","title":"[SL003] - Session Log Sync → Automatic Synchronization","zettel":"20260105040109"},{"file_path":"./notes/20260105040109/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N034","title":"[SL004] - Session Log Sync → GitHub Actions Workflow","zettel":"20260105040109"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N001","title":"[BP001] - Blog Platform → Primary URL Endpoint","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N002","title":"[BP002] - Blog Platform → JavaScript-Free Core Functionality","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N003","title":"[BP003] - Blog Platform → Responsive Layout Design","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N004","title":"[BP004] - Blog Platform → Performance Optimization","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N005","title":"[BP005] - Blog Platform → Continuous Deployment Pipeline","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N006","title":"[BP006] - Blog Platform → CLI Browser Compatibility","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N007","title":"[BP007] - Blog Platform → Tmux-Inspired Interface Design","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N008","title":"[BP008] - Blog Platform → Dual Theme Color System","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N009","title":"[BP009] - Blog Platform → Theme Toggle Control","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N010","title":"[BP010] - Blog Platform → Typography System","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N011","title":"[BP011] - Blog Platform → CSS Border Styling","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N012","title":"[BP012] - Blog Platform → Week Navigation Status Bar","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N013","title":"[BP013] - Blog Platform → Week Number Tooltips","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N014","title":"[BP014] - Blog Platform → Weekly Index Navigation Link","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N015","title":"[BP015] - Blog Platform → Footer Navigation Bar","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N016","title":"[BP016] - Blog Platform → Accessible Navigation Labels","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N017","title":"[BP017] - Blog Platform → Table of Contents","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N018","title":"[BP018] - Blog Platform → Sticky Section Indicator","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N019","title":"[BP019] - Blog Platform → About Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N020","title":"[BP020] - Blog Platform → Weekly Index Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N021","title":"[BP021] - Blog Platform → Reports Section","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N022","title":"[BP022] - Blog Platform → Community Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N023","title":"[BP023] - Blog Platform → Blog Index Page","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N024","title":"[BP024] - Blog Platform → Weekly Post URL Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N025","title":"[BP025] - Blog Platform → Monthly Report URL Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N026","title":"[BP026] - Blog Platform → Quarterly Report URL Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N027","title":"[BP027] - Blog Platform → Post Metadata Display","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N028","title":"[BP028] - Blog Platform → Previous/Next Post Navigation","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N029","title":"[BP029] - Blog Platform → Session Log Links","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N030","title":"[BP030] - Blog Platform → Repository/Code Links","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N037","title":"[BP031] - Blog Platform → RSS/Atom Feed","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N038","title":"[BP032] - Blog Platform → Basic Meta Tags","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N039","title":"[BP033] - Blog Platform → Open Graph Meta Tags","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N040","title":"[BP034] - Blog Platform → Twitter Card Meta Tags","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N041","title":"[BP035] - Blog Platform → XML Sitemap","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N042","title":"[BP036] - Blog Platform → JSON-LD Structured Data","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N043","title":"[BP037] - Blog Platform → Social Card Images","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N044","title":"[BP038] - Blog Platform → GitHub Discussion Links","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N045","title":"[BP039] - Blog Platform → Discussion Deep Linking","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N046","title":"[BP040] - Blog Platform → Semantic HTML Structure","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N047","title":"[BP041] - Blog Platform → Image Alt Text","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N048","title":"[BP042] - Blog Platform → Skip to Content Link","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N049","title":"[BP043] - Blog Platform → Keyboard Navigation","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N050","title":"[BP044] - Blog Platform → Color Contrast Compliance","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N051","title":"[BP045] - Blog Platform → Logical Reading Order","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N052","title":"[BP046] - Blog Platform → Markdown Authoring","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N053","title":"[BP047] - Blog Platform → Syntax Highlighting","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N054","title":"[BP048] - Blog Platform → Callout Boxes","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N055","title":"[BP049] - Blog Platform → Local Preview","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N056","title":"[BP050] - Blog Platform → Server-Side Analytics","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N057","title":"[BP051] - Blog Platform → Community Repository Display","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N058","title":"[BP052] - Blog Platform → Repository Information Display","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N059","title":"[BP053] - Blog Platform → API Failure Handling","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N060","title":"[BP054] - Blog Platform → Community Empty State","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N061","title":"[BP055] - Blog Platform → Client-Side API Caching","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N062","title":"[BP056] - Blog Platform → Site Branding","zettel":"20260105040104"},{"file_path":"./notes/20260105040104/README.md","keyword":"REQ","priority":2,"project":"52vibes","status":"active","tag":"N063","title":"[BP057] - Blog Platform → Consistent Header","zettel":"20260105040104"}]}AI: Let me read the detailed requirements from each product zettel to understand them fully before creating technical requirements.
TOOL-CALL: mcp_note_get_note
{"project":"52vibes","note_id":"20260105040104"}TOOL-CALL: mcp_note_get_note
{"project":"52vibes","note_id":"20260105040107"}TOOL-CALL: mcp_note_get_note
{"project":"52vibes","note_id":"20260105040109"}TOOL:
{"content":"# Week 1: Requirements - Blog Platform (BP)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Description:** Static blog site built with Hugo, deployed to Cloudflare Pages, featuring a tmux-inspired design with Gruvbox theming. The blog documents the 52vibes project—a year-long human-AI collaboration experiment.\n\n**Target URL:** \https://52vibes.dev/blog`\n\n—\n\n## Requirements\n\n\nREQ: [BP001] - Blog Platform → Primary URL Endpoint #N001\n* The system SHALL serve the blog at the URL `https://52vibes.dev/blog`.\n* The blog index page SHALL be the default response for requests to this URL.\n* The system SHALL return HTTP 200 status for valid blog requests.\n* All blog content SHALL be accessible as sub-paths under `/blog/`.\n\nQA: [BP_QA_001] - Blog Platform → Primary URL Accessibility Test #BP001\n* Objective: Verify blog is accessible at the specified primary URL.\n* Precondition: Blog is deployed to production.\n* Test Cases:\n - TC1: Navigate to `https://52vibes.dev/blog` → Expect HTTP 200, blog index renders\n - TC2: Test with Chrome, Firefox, Safari, Edge → Expect consistent rendering\n - TC3: Request `https://52vibes.dev/blog/` (trailing slash) → Expect equivalent response\n - TC4: Request `http://52vibes.dev/blog` → Expect redirect to HTTPS\n* Boundary: Test with various network conditions (slow 3G, offline cache)\n\nREQ: [BP002] - Blog Platform → JavaScript-Free Core Functionality #N002\n* The system SHALL render all core content without requiring JavaScript execution.\n* Core functionality includes: reading blog posts, navigating between pages, viewing site structure, accessing table of contents.\n* The system MAY use JavaScript for progressive enhancement of non-essential features only.\n* JavaScript-dependent features SHALL degrade gracefully when JavaScript is disabled.\n\nQA: [BP_QA_002] - Blog Platform → JavaScript-Free Operation Test #BP002\n* Objective: Verify all core functionality works without JavaScript.\n* Precondition: Browser JavaScript is disabled.\n* Test Cases:\n - TC1: Load blog index with JS disabled → Expect all posts listed and readable\n - TC2: Navigate to blog post with JS disabled → Expect content fully rendered\n - TC3: Click internal navigation links with JS disabled → Expect navigation works\n - TC4: Access table of contents with JS disabled → Expect anchor links functional\n - TC5: Load About, Weekly Index, Reports pages → Expect full rendering\n* Boundary: Test with JS blocked mid-load, partially loaded scripts\n* Failure Case: Verify no JavaScript errors in console when JS is enabled\n\nREQ: [BP003] - Blog Platform → Responsive Layout Design #N003\n* The system SHALL render correctly across desktop (≥1024px), tablet (768px-1023px), and mobile (\u003c768px) viewports.\n* Layout SHALL adapt fluidly to viewport width changes without horizontal scrolling.\n* Content readability SHALL be maintained across all supported viewport sizes.\n* Navigation elements SHALL remain accessible and functional at all breakpoints.\n\nQA: [BP_QA_003] - Blog Platform → Responsive Layout Test #BP003\n* Objective: Verify layout adapts correctly across viewport sizes.\n* Test Cases:\n - TC1: Desktop 1920px width → Expect full layout, no horizontal scroll\n - TC2: Desktop 1024px width → Expect adapted layout, readable content\n - TC3: Tablet 768px width → Expect tablet-optimized layout\n - TC4: Mobile 375px width → Expect mobile-optimized layout\n - TC5: Mobile 320px width (boundary) → Expect content readable, no overflow\n - TC6: Resize viewport dynamically → Expect smooth adaptation\n* Orientation: Test portrait and landscape on mobile/tablet viewports\n* Content Types: Verify with text-heavy posts, code blocks, and tables\n\nREQ: [BP004] - Blog Platform → Performance Optimization #N004\n* The system SHALL achieve a Lighthouse Performance score of 95 or higher.\n* First Contentful Paint (FCP) SHOULD be under 1.5 seconds on standard connections.\n* Cumulative Layout Shift (CLS) SHALL be under 0.1.\n* Total page weight SHOULD NOT exceed 500KB for the blog index page.\n* Images SHALL be optimized and served in modern formats (WebP) where supported.\n\nQA: [BP_QA_004] - Blog Platform → Performance Metrics Test #BP004\n* Objective: Verify blog meets performance benchmarks.\n* Test Cases:\n - TC1: Lighthouse audit on blog index → Expect Performance ≥95\n - TC2: Lighthouse audit on blog post page → Expect Performance ≥95\n - TC3: Lighthouse audit on page with images → Expect Performance ≥95\n - TC4: Measure FCP on 4G connection → Expect \u003c1.5s\n - TC5: Measure CLS during page load → Expect \u003c0.1\n - TC6: Check total page weight → Expect \u003c500KB for index\n* Tools: Chrome DevTools Lighthouse, WebPageTest\n* Load Testing: Verify under concurrent user load (10 simultaneous requests)\n* References:\n + web.dev Performance Metrics\n\nREQ: [BP005] - Blog Platform → Continuous Deployment Pipeline #N005\n* The system SHALL automatically deploy to production when changes are pushed to the main branch.\n* Deployment SHALL be triggered by Cloudflare Pages native build system.\n* Deployment completion time SHALL NOT exceed 5 minutes for content-only changes.\n* Manual deployment steps SHALL NOT be required for standard content updates.\n\nQA: [BP_QA_005] - Blog Platform → Continuous Deployment Test #BP005\n* Objective: Verify automatic deployment on git push.\n* Test Cases:\n - TC1: Push content change to main → Expect Cloudflare build triggers\n - TC2: Monitor deployment → Expect completion within 5 minutes\n - TC3: Verify live site → Expect changes visible post-deployment\n - TC4: Push configuration change → Expect successful rebuild\n - TC5: Push theme change → Expect successful rebuild\n* Failure Cases:\n - FC1: Push invalid Hugo config → Expect build fails, previous version remains live\n - FC2: Push malformed markdown → Verify graceful handling\n\nREQ: [BP006] - Blog Platform → CLI Browser Compatibility #N006\n* The system SHALL be readable and navigable using text-based CLI browsers.\n* Supported CLI browsers SHALL include: lynx, w3m, and links.\n* All text content SHALL be accessible in CLI browsers.\n* Navigation links SHALL function correctly in CLI browsers.\n* Tabular data (Weekly Index) SHALL render readably in w3m.\n\nQA: [BP_QA_006] - Blog Platform → CLI Browser Compatibility Test #BP006\n* Objective: Verify blog is usable in text-based browsers.\n* Lynx Tests (most restrictive):\n - TC1: `lynx https://52vibes.dev/blog` → Expect text content readable\n - TC2: Navigate to blog post → Expect content rendered\n - TC3: Follow internal links → Expect navigation works\n - TC4: Access TOC links → Expect anchor navigation works\n* w3m Tests (table support):\n - TC5: `w3m https://52vibes.dev/blog/weeks/` → Expect 52-week table renders\n - TC6: Verify table cells aligned → Expect readable structure\n* links Tests:\n - TC7: Basic navigation and content rendering\n* Boundary: Test with nested code blocks, long lines, special characters\n\nREQ: [BP007] - Blog Platform → Tmux-Inspired Interface Design #N007\n* The system SHALL implement a terminal/tmux-inspired visual design aesthetic.\n* The interface SHALL include a top status bar element.\n* The interface SHALL include a bottom navigation bar element.\n* The main content area SHALL be styled with bordered frame elements.\n* The design SHALL evoke a developer-focused, technical aesthetic.\n\nQA: [BP_QA_007] - Blog Platform → Tmux-Inspired Design Test #BP007\n* Objective: Verify visual design matches tmux aesthetic.\n* Test Cases:\n - TC1: Inspect page layout → Expect top status bar present\n - TC2: Inspect page layout → Expect bottom navigation bar present\n - TC3: Inspect main content → Expect bordered frame styling\n - TC4: Visual comparison → Compare against tmux reference screenshots\n - TC5: Overall aesthetic → Expect terminal/developer feel\n* Visual Regression: Capture screenshots for baseline comparison\n* Cross-browser: Verify consistent rendering across browsers\n\nREQ: [BP008] - Blog Platform → Dual Theme Color System #N008\n* The system SHALL support both dark and light color themes.\n* Color themes SHALL be based on the Gruvbox color palette.\n* Dark theme background SHALL use Gruvbox dark colors (e.g., `#1d2021`).\n* Light theme background SHALL use Gruvbox light colors (e.g., `#fbf1c7`).\n* Theme selection SHALL respect system preference (prefers-color-scheme) by default.\n* References:\n + Gruvbox Color Palette\n\nQA: [BP_QA_008] - Blog Platform → Dual Theme Test #BP008\n* Objective: Verify correct theme rendering based on system preference.\n* Test Cases:\n - TC1: System dark mode → Expect dark theme (background ~#1d2021)\n - TC2: System light mode → Expect light theme (background ~#fbf1c7)\n - TC3: Verify text colors → Dark: ~#ebdbb2, Light: ~#3c3836\n - TC4: Verify accent colors → Consistent Gruvbox orange (#d65d0e)\n - TC5: Toggle system preference → Expect theme updates\n* Color Verification: Use color picker tool to verify hex values\n* Consistency: Verify all UI elements use Gruvbox palette\n\nREQ: [BP009] - Blog Platform → Theme Toggle Control #N009\n* The system SHALL provide a visible toggle control for theme switching.\n* The toggle SHALL allow users to switch between dark and light themes.\n* Theme preference MAY be persisted using localStorage (JavaScript).\n* Theme toggle functionality SHALL degrade gracefully in JavaScript-disabled environments.\n* Theme preference SHALL persist across page navigation and browser sessions.\n\nQA: [BP_QA_009] - Blog Platform → Theme Toggle Test #BP009\n* Objective: Verify theme toggle functionality and persistence.\n* Test Cases:\n - TC1: Locate theme toggle → Expect visible control on page\n - TC2: Click toggle in dark mode → Expect switch to light mode\n - TC3: Click toggle in light mode → Expect switch to dark mode\n - TC4: Navigate to another page → Expect theme preference persists\n - TC5: Refresh page → Expect theme preference persists\n - TC6: Close and reopen browser → Expect theme preference persists\n* Degradation:\n - TC7: Disable JavaScript → Expect page readable (system preference)\n - TC8: Disable localStorage → Verify graceful handling\n* Accessibility: Verify toggle is keyboard accessible\n\nREQ: [BP010] - Blog Platform → Typography System #N010\n* The system SHALL use IBM Plex Sans font for body text.\n* The system SHALL use IBM Plex Sans font for headings.\n* The system SHALL use JetBrains Mono font for code blocks and monospace content.\n* Font files SHALL be served locally or via reliable CDN with fallback to system fonts.\n* References:\n + IBM Plex\n + JetBrains Mono\n\nQA: [BP_QA_010] - Blog Platform → Typography Test #BP010\n* Objective: Verify correct fonts are applied.\n* Test Cases:\n - TC1: Inspect body text → Expect IBM Plex Sans applied\n - TC2: Inspect headings (h1-h6) → Expect IBM Plex Sans applied\n - TC3: Inspect code blocks → Expect JetBrains Mono applied\n - TC4: Inspect inline code → Expect JetBrains Mono applied\n - TC5: Verify no system font fallback → Check computed styles\n - TC6: Slow network test → Expect fonts load gracefully\n* Rendering: Verify legibility at various sizes (12px, 14px, 16px, 18px)\n* Cross-browser: Verify consistent font rendering\n\nREQ: [BP011] - Blog Platform → CSS Border Styling #N011\n* The system SHALL use CSS borders for terminal-inspired visual elements.\n* ASCII box-drawing characters (─, │, ┌, ┐, └, ┘) SHALL NOT be used for structural borders.\n* CSS-based borders ensure cross-browser compatibility and accessibility.\n* Border styling SHALL be consistent across themes (dark/light).\n\nQA: [BP_QA_011] - Blog Platform → CSS Border Styling Test #BP011\n* Objective: Verify borders use CSS, not ASCII characters.\n* Test Cases:\n - TC1: Inspect border elements → Expect CSS border properties\n - TC2: Search HTML source for box-drawing chars → Expect none found\n - TC3: Verify borders render in CLI browsers → Expect readable\n - TC4: Compare borders in dark/light themes → Expect consistent style\n* Unicode Search: Search for: ─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼\n* Inspection: Use DevTools to verify border-style, border-width properties\n\nREQ: [BP012] - Blog Platform → Week Navigation Status Bar #N012\n* The system SHALL display a top status bar containing clickable week numbers.\n* Only completed weeks SHALL be displayed as clickable links.\n* Incomplete/upcoming weeks SHALL NOT be clickable.\n* Clicking a week number SHALL navigate to that week’s blog post.\n* Week numbers SHALL be displayed in chronological order (1-52).\n\nQA: [BP_QA_012] - Blog Platform → Week Navigation Status Bar Test #BP012\n* Objective: Verify week navigation functionality in status bar.\n* Test Cases:\n - TC1: Locate top status bar → Expect week numbers visible\n - TC2: Verify completed weeks → Expect clickable links\n - TC3: Verify upcoming weeks → Expect NOT clickable\n - TC4: Click completed week number → Expect navigation to post\n - TC5: Verify chronological order → Expect 1, 2, 3… 52\n - TC6: Test all available week links → Expect correct destinations\n* Boundary: Test when only week 1 exists, when multiple weeks exist\n* Visual: Verify clickable/non-clickable states are visually distinct\n\nREQ: [BP013] - Blog Platform → Week Number Tooltips #N013\n* The system SHALL display native browser tooltips on hover over week numbers in the status bar.\n* Tooltips SHALL display the post title for the corresponding week.\n* Implementation SHALL use the HTML `title` attribute (native browser tooltip).\n* Custom JavaScript tooltip libraries SHALL NOT be used.\n\nQA: [BP_QA_013] - Blog Platform → Week Tooltips Test #BP013\n* Objective: Verify native tooltips show post titles on hover.\n* Test Cases:\n - TC1: Hover over week number → Expect native browser tooltip appears\n - TC2: Verify tooltip content → Expect post title displayed\n - TC3: Test all available week tooltips → Expect correct titles\n - TC4: Inspect HTML → Expect `title` attribute on link elements\n - TC5: Verify no JS tooltip library → Check network requests, source\n* Timing: Tooltip should appear after standard browser delay (~500ms)\n\nREQ: [BP014] - Blog Platform → Weekly Index Navigation Link #N014\n* The system SHALL provide a "Weeks" label in the top status bar.\n* The "Weeks" label SHALL function as a link to the Weekly Index page.\n* The link SHALL navigate to `/blog/weeks/`.\n* The link SHALL be implemented as a standard anchor element (`\u003ca\u003e`) for CLI browser accessibility.\n\nQA: [BP_QA_014] - Blog Platform → Weekly Index Link Test #BP014\n* Objective: Verify "Weeks" label links to Weekly Index.\n* Test Cases:\n - TC1: Locate "Weeks" label in status bar → Expect visible\n - TC2: Click "Weeks" → Expect navigation to `/blog/weeks/`\n - TC3: Inspect HTML → Expect standard `\u003ca\u003e` element\n - TC4: Test in lynx → Expect link accessible and functional\n - TC5: Test in w3m → Expect link accessible and functional\n* Accessibility: Verify link has appropriate aria-label if needed\n\nREQ: [BP015] - Blog Platform → Footer Navigation Bar #N015\n* The system SHALL display a bottom navigation bar on all pages.\n* Required navigation links: About, Weekly Index, Reports, RSS, and GitHub.\n* Links SHALL navigate to: `/about/`, `/blog/weeks/`, `/blog/reports/`, RSS feed URL, GitHub repository URL.\n* Navigation bar SHALL be consistent across all pages.\n\nQA: [BP_QA_015] - Blog Platform → Footer Navigation Test #BP015\n* Objective: Verify bottom navigation bar completeness and functionality.\n* Test Cases:\n - TC1: Locate bottom navigation bar → Expect present on all pages\n - TC2: Verify About link → Expect navigates to `/about/`\n - TC3: Verify Weekly Index link → Expect navigates to `/blog/weeks/`\n - TC4: Verify Reports link → Expect navigates to `/blog/reports/`\n - TC5: Verify RSS link → Expect valid RSS feed URL\n - TC6: Verify GitHub link → Expect GitHub repository URL\n* Consistency: Check navigation on blog index, post, about, community pages\n* CLI Browsers: Verify all links work in lynx, w3m\n\nREQ: [BP016] - Blog Platform → Accessible Navigation Labels #N016\n* All navigation links SHALL use descriptive text labels.\n* Icons MAY accompany text labels but SHALL NOT replace them.\n* Text labels ensure accessibility for screen readers and CLI browsers.\n* Link text SHALL be meaningful out of context (avoid "click here", "read more").\n\nQA: [BP_QA_016] - Blog Platform → Navigation Labels Test #BP016\n* Objective: Verify all navigation uses descriptive text.\n* Test Cases:\n - TC1: Inspect all navigation elements → Expect descriptive text labels\n - TC2: Verify icons accompany (not replace) text → If icons exist\n - TC3: Test in CLI browser → Expect all nav understandable without visuals\n - TC4: Screen reader test → Expect links announced with descriptive text\n - TC5: Search for "click here", "read more" → Expect none in nav\n* Accessibility: Run axe audit on navigation elements\n\nREQ: [BP017] - Blog Platform → Table of Contents #N017\n* Each blog post SHALL display a table of contents at the top of the post content area.\n* The TOC SHALL list all major sections (h2, h3 headings) of the post.\n* TOC items SHALL be anchor links that navigate to the corresponding section.\n* TOC SHALL be generated automatically from post heading structure.\n\nQA: [BP_QA_017] - Blog Platform → Table of Contents Test #BP017\n* Objective: Verify TOC generation and navigation.\n* Test Cases:\n - TC1: Navigate to post with 3+ headings → Expect TOC visible at top\n - TC2: Verify all major sections listed → Expect h2, h3 headings present\n - TC3: Click TOC item → Expect smooth scroll to section\n - TC4: Verify anchor links → Expect URL hash updates (#section-id)\n - TC5: Test in CLI browser → Expect anchor navigation works\n* Boundary: Test post with no headings, single heading, nested headings\n* Content Types: Test with code blocks in headings, special characters\n\nREQ: [BP018] - Blog Platform → Sticky Section Indicator #N018\n* Blog posts SHOULD display a sticky section indicator showing current reading position.\n* Indicator format example: "§ Reading: Section Name".\n* Implementation SHALL NOT require JavaScript.\n* This is a SHOULD requirement; graceful absence is acceptable.\n\nQA: [BP_QA_018] - Blog Platform → Section Indicator Test #BP018\n* Objective: Verify sticky section indicator (if implemented).\n* Test Cases (if implemented):\n - TC1: Navigate to long post (5+ sections) → Expect indicator visible\n - TC2: Scroll through sections → Expect indicator updates\n - TC3: Verify format → Expect "§ Reading: Section Name" or similar\n - TC4: Disable JavaScript → Expect indicator still works (CSS-only)\n - TC5: Verify sticky behavior → Expect remains visible while scrolling\n* Note: SHOULD requirement; document if not implemented\n* Implementation Check: Verify pure CSS solution (scroll-snap, intersection)\n\nREQ: [BP019] - Blog Platform → About Page #N019\n* The system SHALL provide an About page at the URL `/about/`.\n* The About page SHALL describe the 52vibes project purpose and goals.\n* The About page SHALL include author/contributor information.\n* Page layout and styling SHALL be consistent with the rest of the site.\n\nQA: [BP_QA_019] - Blog Platform → About Page Test #BP019\n* Objective: Verify About page content and accessibility.\n* Test Cases:\n - TC1: Navigate to `/about/` → Expect HTTP 200, page loads\n - TC2: Verify project description → Expect meaningful content\n - TC3: Verify author information → Expect contributor details\n - TC4: Verify layout consistency → Expect matches blog design\n - TC5: Test in CLI browser → Expect content readable\n* Content Quality: Verify description explains 52vibes project\n* SEO: Verify meta tags present for about page\n\nREQ: [BP020] - Blog Platform → Weekly Index Page #N020\n* The system SHALL provide a Weekly Index page at `/blog/weeks/`.\n* The page SHALL display all 52 weeks in a tabular or list format.\n* Each week entry SHALL indicate status: completed, in-progress, or upcoming.\n* Completed weeks SHALL display post titles and link to the corresponding posts.\n* Upcoming weeks SHALL be visually distinguished and not linked.\n\nQA: [BP_QA_020] - Blog Platform → Weekly Index Page Test #BP020\n* Objective: Verify Weekly Index displays all 52 weeks correctly.\n* Test Cases:\n - TC1: Navigate to `/blog/weeks/` → Expect page loads\n - TC2: Count week entries → Expect exactly 52 weeks listed\n - TC3: Verify completed weeks → Expect title + link displayed\n - TC4: Verify upcoming weeks → Expect not clickable, distinct styling\n - TC5: Verify in-progress week → Expect distinguishable if present\n - TC6: Click completed week link → Expect navigation to post\n* CLI Browser: Test table rendering in w3m (critical for tables)\n* Responsive: Verify table readable on mobile viewports\n\nREQ: [BP021] - Blog Platform → Reports Section #N021\n* The system SHALL provide a Reports section at `/blog/reports/`.\n* The section SHALL contain monthly and quarterly summary report posts.\n* Report listings SHALL display title, date, and type (monthly/quarterly).\n* An appropriate empty state message SHALL be displayed when no reports exist.\n\nQA: [BP_QA_021] - Blog Platform → Reports Section Test #BP021\n* Objective: Verify Reports section displays correctly.\n* Test Cases:\n - TC1: Navigate to `/blog/reports/` → Expect page loads\n - TC2: Verify published monthly reports listed → When available\n - TC3: Verify published quarterly reports listed → When available\n - TC4: Click report link → Expect navigation to full report\n - TC5: Verify empty state → When no reports exist, friendly message shown\n* Content Types: Verify both monthly and quarterly types distinguishable\n* Ordering: Verify reports ordered by date (most recent first)\n\nREQ: [BP022] - Blog Platform → Community Page #N022\n* The system SHALL provide a Community page at `/community/`.\n* The page SHALL display public GitHub repositories tagged with "52vibes".\n* JavaScript MAY be used to fetch repository data from the GitHub API.\n* Graceful fallback SHALL be provided when API is unavailable.\n\nQA: [BP_QA_022] - Blog Platform → Community Page Test #BP022\n* Objective: Verify Community page displays repositories.\n* Test Cases:\n - TC1: Navigate to `/community/` → Expect page loads\n - TC2: If repos exist → Expect listed with information\n - TC3: If no repos exist → Expect friendly message\n - TC4: Verify JavaScript enabled → Expect API fetch works\n - TC5: Test loading state → Expect visual feedback during fetch\n* API Integration: Verify correct GitHub API endpoint called\n* Fallback: Test behavior when API returns error\n\nREQ: [BP023] - Blog Platform → Blog Index Page #N023\n* The system SHALL provide a blog index at `/blog/`.\n* The index SHALL list all published blog posts.\n* Each listing SHALL display: title, publication date, and summary.\n* Posts SHALL be ordered with most recent first.\n\nQA: [BP_QA_023] - Blog Platform → Blog Index Test #BP023\n* Objective: Verify blog index lists all posts correctly.\n* Test Cases:\n - TC1: Navigate to `/blog/` → Expect page loads\n - TC2: Verify all published posts listed → Expect complete list\n - TC3: Verify each listing → Expect title, date, summary present\n - TC4: Click post title → Expect navigation to full post\n - TC5: Verify ordering → Expect most recent first\n - TC6: Test pagination → If more than one page of posts\n* Content: Verify summary is truncated appropriately\n* CLI Browser: Verify list readable in lynx\n\nREQ: [BP024] - Blog Platform → Weekly Post URL Structure #N024\n* Weekly blog posts SHALL be accessible at URLs following the pattern `/blog/week-XX-\u003ctitle\u003e/`.\n* Example: `/blog/week-01-infrastructure/`.\n* Week number SHALL be zero-padded (01, 02, … 52).\n* URL slug SHALL be derived from post title (lowercase, hyphenated).\n\nQA: [BP_QA_024] - Blog Platform → Weekly Post URL Test #BP024\n* Objective: Verify weekly post URL structure.\n* Test Cases:\n - TC1: Navigate to weekly post → Verify URL matches pattern\n - TC2: Verify URL format → `/blog/week-XX-\u003ctitle\u003e/`\n - TC3: Verify zero-padding → Expect 01, 02, not 1, 2\n - TC4: Test multiple weeks → Expect consistent pattern\n - TC5: Verify slug format → Expect lowercase, hyphenated\n* Boundary: Test week-01, week-10, week-52\n* Edge Cases: Test titles with special characters, numbers\n\nREQ: [BP025] - Blog Platform → Monthly Report URL Structure #N025\n* Monthly report posts SHALL be accessible at URLs following the pattern `/blog/reports/YYYY-MM/`.\n* Example: `/blog/reports/2026-01/`.\n* Year and month SHALL be formatted as four-digit year and two-digit month.\n\nQA: [BP_QA_025] - Blog Platform → Monthly Report URL Test #BP025\n* Objective: Verify monthly report URL structure.\n* Test Cases:\n - TC1: Navigate to monthly report → Verify URL matches pattern\n - TC2: Verify URL format → `/blog/reports/YYYY-MM/`\n - TC3: Verify date format → Four-digit year, two-digit month\n - TC4: Example verification → `/blog/reports/2026-01/`\n* Boundary: Test January (01), December (12)\n* Edge Cases: Test year boundaries (2026-12 to 2027-01)\n\nREQ: [BP026] - Blog Platform → Quarterly Report URL Structure #N026\n* Quarterly report posts SHALL be accessible at URLs following the pattern `/blog/reports/YYYY-qN/`.\n* Example: `/blog/reports/2026-q1/`.\n* Quarter indicator SHALL be lowercase ‘q’ followed by quarter number (1-4).\n\nQA: [BP_QA_026] - Blog Platform → Quarterly Report URL Test #BP026\n* Objective: Verify quarterly report URL structure.\n* Test Cases:\n - TC1: Navigate to quarterly report → Verify URL matches pattern\n - TC2: Verify URL format → `/blog/reports/YYYY-qN/`\n - TC3: Verify quarter indicator → Lowercase ‘q’ + 1-4\n - TC4: Example verification → `/blog/reports/2026-q1/`\n* Boundary: Test q1, q2, q3, q4\n* Case Sensitivity: Verify lowercase ‘q’ (not ‘Q’)\n\nREQ: [BP027] - Blog Platform → Post Metadata Display #N027\n* Each blog post SHALL display the following metadata: title, publication date, estimated reading time, and quarter/theme indicator.\n* Quarter/theme indicator format: "Q1: Agentic Infrastructure" (or similar).\n* Metadata SHALL be prominently displayed near the top of the post.\n* Reading time SHOULD be calculated automatically from content length.\n\nQA: [BP_QA_027] - Blog Platform → Post Metadata Test #BP027\n* Objective: Verify post metadata is correctly displayed.\n* Test Cases:\n - TC1: Navigate to blog post → Expect title displayed prominently\n - TC2: Verify publication date → Expect human-readable format\n - TC3: Verify reading time → Expect "X min read" format\n - TC4: Verify quarter/theme → Expect "Q1: Theme Name" format\n - TC5: Test multiple posts → Expect consistent metadata display\n* Calculation: Verify reading time is reasonable for content length\n* Consistency: Compare metadata display across different posts\n\nREQ: [BP028] - Blog Platform → Previous/Next Post Navigation #N028\n* Each blog post SHALL provide navigation links to adjacent week posts.\n* "Previous week" link SHALL navigate to the prior week’s post.\n* "Next week" link SHALL navigate to the following week’s post.\n* Links SHALL NOT appear when not applicable (no Previous for Week 1, no Next for latest).\n\nQA: [BP_QA_028] - Blog Platform → Post Navigation Test #BP028\n* Objective: Verify previous/next post navigation.\n* Test Cases:\n - TC1: Navigate to middle week → Expect both Previous and Next links\n - TC2: Click Previous link → Expect navigation to prior week\n - TC3: Click Next link → Expect navigation to following week\n - TC4: Navigate to Week 1 → Expect no Previous link\n - TC5: Navigate to latest week → Expect no Next link\n - TC6: Follow complete chain → Expect all weeks reachable\n* Boundary: Test first week, last published week, middle week\n* Edge Case: Single published week (no navigation links)\n\nREQ: [BP029] - Blog Platform → Session Log Links #N029\n* Each blog post SHALL include a link to the corresponding session log on the GitHub Wiki.\n* The link SHALL be clearly labeled (e.g., "View Session Log").\n* The link SHALL navigate to the wiki page containing that week’s collaboration data.\n* This connects polished blog content to raw human-AI collaboration artifacts.\n\nQA: [BP_QA_029] - Blog Platform → Session Log Links Test #BP029\n* Objective: Verify session log links connect to GitHub Wiki.\n* Test Cases:\n - TC1: Navigate to blog post → Expect session log link visible\n - TC2: Verify link label → Expect descriptive (e.g., "View Session Log")\n - TC3: Click session log link → Expect opens GitHub Wiki page\n - TC4: Verify wiki content → Expect session data for that week\n - TC5: Test multiple posts → Expect each links to correct wiki page\n* Cross-reference: Verify wiki page title matches week number\n* External Link: Verify link opens in appropriate context\n\nREQ: [BP030] - Blog Platform → Repository/Code Links #N030\n* Each blog post SHALL include a link to the corresponding GitHub repository or code artifacts.\n* The link SHALL be clearly labeled.\n* The link SHALL navigate to the week’s relevant code location.\n* This enables readers to explore actual code produced during the week.\n\nQA: [BP_QA_030] - Blog Platform → Repository Links Test #BP030\n* Objective: Verify repository/code links are functional.\n* Test Cases:\n - TC1: Navigate to blog post → Expect code/repository link visible\n - TC2: Verify link label → Expect descriptive text\n - TC3: Click repository link → Expect opens GitHub repository\n - TC4: Verify linked content → Expect corresponds to week’s project\n - TC5: Test multiple posts → Expect each links to correct repository\n* Link Validity: Verify links are not broken (HTTP 200)\n* Content Match: Verify repository content matches week’s topic\n\nREQ: [BP031] - Blog Platform → RSS/Atom Feed #N037\n* The system SHALL provide an RSS or Atom feed for blog subscribers.\n* Feed SHALL be accessible at a standard location (e.g., `/index.xml` or `/blog/index.xml`).\n* Feed SHALL include all published blog posts.\n* Feed SHALL be valid according to RSS/Atom specifications.\n\nQA: [BP_QA_031] - Blog Platform → RSS Feed Test #BP031\n* Objective: Verify RSS/Atom feed validity and content.\n* Test Cases:\n - TC1: Navigate to feed URL → Expect valid XML response\n - TC2: Verify feed format → Expect valid RSS or Atom structure\n - TC3: Verify recent posts included → Expect published posts in feed\n - TC4: Test in RSS reader → Expect feed parseable\n - TC5: Validate with W3C Feed Validation Service → Expect no errors\n* Content: Verify each item has title, link, description, pubDate\n* Encoding: Verify proper character encoding (UTF-8)\n* References:\n + W3C Feed Validator\n\nREQ: [BP032] - Blog Platform → Basic Meta Tags #N038\n* Each page SHALL include appropriate meta tags for SEO.\n* Required meta tags: `\u003ctitle\u003e`, `\u003cmeta name="description"\u003e`.\n* Meta description SHALL be relevant to page content.\n* Title tag SHALL contain meaningful page title.\n\nQA: [BP_QA_032] - Blog Platform → Basic Meta Tags Test #BP032\n* Objective: Verify SEO meta tags on all pages.\n* Test Cases:\n - TC1: View page source → Expect `\u003ctitle\u003e` tag present\n - TC2: Verify title content → Expect contains post/page title\n - TC3: Verify description meta → Expect `\u003cmeta name="description"\u003e` present\n - TC4: Verify description content → Expect relevant to page\n* Page Types: Test on blog index, blog post, about, reports, community\n* Length: Verify description is appropriate length (50-160 chars)\n* Uniqueness: Verify each page has unique title/description\n\nREQ: [BP033] - Blog Platform → Open Graph Meta Tags #N039\n* Each page SHALL include Open Graph meta tags for social media sharing.\n* Required tags: `og:title`, `og:description`, `og:image`, `og:url`, `og:type`.\n* Blog posts SHALL use `og:type` of "article".\n* Tags enable rich previews when shared on social media platforms.\n\nQA: [BP_QA_033] - Blog Platform → Open Graph Tags Test #BP033\n* Objective: Verify Open Graph meta tags for social sharing.\n* Test Cases:\n - TC1: View page source → Expect `og:title` meta tag present\n - TC2: Verify og:description → Expect meta tag with content\n - TC3: Verify og:image → Expect social card URL\n - TC4: Verify og:url → Expect canonical URL\n - TC5: Verify og:type → Expect "article" for blog posts\n - TC6: Test with Facebook Sharing Debugger → Expect preview renders\n* Image: Verify og:image URL is valid and accessible\n* References:\n + Facebook Sharing Debugger\n\nREQ: [BP034] - Blog Platform → Twitter Card Meta Tags #N040\n* Each page SHALL include Twitter Card meta tags for Twitter sharing previews.\n* Required tags: `twitter:card`, `twitter:title`, `twitter:description`, `twitter:image`.\n* Card type SHALL be "summary_large_image" for visual impact.\n* Tags enable rich previews when shared on Twitter/X.\n\nQA: [BP_QA_034] - Blog Platform → Twitter Cards Test #BP034\n* Objective: Verify Twitter Card meta tags.\n* Test Cases:\n - TC1: View page source → Expect `twitter:card` meta tag\n - TC2: Verify card type → Expect "summary_large_image"\n - TC3: Verify twitter:title → Expect meta tag with content\n - TC4: Verify twitter:description → Expect meta tag with content\n - TC5: Verify twitter:image → Expect image URL\n - TC6: Test with Twitter Card Validator → Expect preview renders\n* Image Dimensions: Verify image meets Twitter requirements\n* References:\n + Twitter Card Validator\n\nREQ: [BP035] - Blog Platform → XML Sitemap #N041\n* The system SHALL generate and publish an XML sitemap for search engine indexing.\n* Sitemap SHALL be accessible at `/sitemap.xml`.\n* Sitemap SHALL include all blog posts, static pages, and report pages.\n* Sitemap entries SHALL include `lastmod` dates for accurate crawling.\n\nQA: [BP_QA_035] - Blog Platform → Sitemap Test #BP035\n* Objective: Verify sitemap generation and validity.\n* Test Cases:\n - TC1: Navigate to `/sitemap.xml` → Expect valid XML response\n - TC2: Validate XML structure → Expect valid sitemap schema\n - TC3: Verify blog posts included → Expect all posts in sitemap\n - TC4: Verify static pages included → About, Weekly Index, etc.\n - TC5: Verify lastmod dates → Expect present and accurate\n - TC6: Submit to sitemap validator → Expect no errors\n* Completeness: Count URLs match expected page count\n* References:\n + XML Sitemap Validator\n\nREQ: [BP036] - Blog Platform → JSON-LD Structured Data #N042\n* Blog posts SHALL include JSON-LD structured data using Article schema.\n* Required fields: headline, datePublished, author.\n* Structured data enables rich results in search engines.\n* JSON-LD SHALL be embedded in a `\u003cscript type="application/ld+json"\u003e` tag.\n\nQA: [BP_QA_036] - Blog Platform → JSON-LD Test #BP036\n* Objective: Verify JSON-LD structured data implementation.\n* Test Cases:\n - TC1: View page source → Expect `\u003cscript type="application/ld+json"\u003e`\n - TC2: Parse JSON-LD → Expect valid JSON\n - TC3: Verify Article schema → Expect @type = "Article"\n - TC4: Verify headline field → Expect post title\n - TC5: Verify datePublished → Expect ISO 8601 format\n - TC6: Verify author field → Expect author information\n - TC7: Test with Google Rich Results Test → Expect validation passes\n* References:\n + Google Rich Results Test\n + Schema.org Article\n\nREQ: [BP037] - Blog Platform → Social Card Images #N043\n* The system SHALL generate social card images for each blog post.\n* Images SHALL use a consistent template design.\n* Template SHALL display: week number, post title, and quarter theme.\n* Image dimensions SHALL be optimized for social media (1200x630 recommended).\n\nQA: [BP_QA_037] - Blog Platform → Social Card Images Test #BP037\n* Objective: Verify social card image generation and content.\n* Test Cases:\n - TC1: Extract og:image URL from post → Expect valid URL\n - TC2: Open image URL directly → Expect image loads\n - TC3: Verify image content → Expect week number, title, quarter theme\n - TC4: Verify template consistency → Compare multiple post cards\n - TC5: Verify dimensions → Expect ~1200x630 pixels\n - TC6: Test sharing preview → Verify card displays correctly\n* Visual Quality: Verify text is readable, colors match Gruvbox\n\nREQ: [BP038] - Blog Platform → GitHub Discussion Links #N044\n* Each blog post SHALL provide a link to a corresponding GitHub Discussion.\n* The link SHALL enable reader comments and questions.\n* The link SHALL be clearly labeled and visible.\n\nQA: [BP_QA_038] - Blog Platform → Discussion Links Test #BP038\n* Objective: Verify GitHub Discussion links are present.\n* Test Cases:\n - TC1: Navigate to blog post → Expect discussion link visible\n - TC2: Verify link label → Expect descriptive text (not "click here")\n - TC3: Click discussion link → Expect opens GitHub Discussions\n - TC4: Verify link destination → Expect correct repository discussions\n* Accessibility: Verify link has appropriate context for screen readers\n\nREQ: [BP039] - Blog Platform → Discussion Deep Linking #N045\n* GitHub Discussion links SHALL navigate to the specific discussion thread for that post.\n* Links SHALL NOT navigate to a generic discussions index page.\n* Each post SHALL have its own dedicated discussion thread.\n\nQA: [BP_QA_039] - Blog Platform → Discussion Deep Linking Test #BP039\n* Objective: Verify discussion links go to specific threads.\n* Test Cases:\n - TC1: Click discussion link on post → Expect specific thread opens\n - TC2: Verify NOT generic discussions page → Expect dedicated thread\n - TC3: Verify discussion title → Expect matches blog post topic\n - TC4: Test multiple posts → Expect each has unique discussion\n* Thread Verification: Confirm URL contains discussion ID, not just `/discussions/`\n\nREQ: [BP040] - Blog Platform → Semantic HTML Structure #N046\n* The system SHALL use semantic HTML elements for document structure.\n* Required elements: `\u003cheader\u003e`, `\u003cnav\u003e`, `\u003cmain\u003e`, `\u003carticle\u003e`, `\u003cfooter\u003e`.\n* Semantic markup ensures accessibility for assistive technologies.\n* Document outline SHALL be logical and hierarchical.\n\nQA: [BP_QA_040] - Blog Platform → Semantic HTML Test #BP040\n* Objective: Verify semantic HTML element usage.\n* Test Cases:\n - TC1: Inspect DOM → Expect `\u003cheader\u003e` for page header\n - TC2: Inspect DOM → Expect `\u003cnav\u003e` for navigation areas\n - TC3: Inspect DOM → Expect `\u003cmain\u003e` wraps primary content\n - TC4: Inspect DOM → Expect `\u003carticle\u003e` wraps blog post content\n - TC5: Inspect DOM → Expect `\u003cfooter\u003e` for page footer\n - TC6: Validate HTML5 → Expect no structural errors\n* Hierarchy: Verify heading levels (h1, h2, h3) are logical\n* Tools: W3C HTML Validator, axe accessibility checker\n\nREQ: [BP041] - Blog Platform → Image Alt Text #N047\n* All images SHALL include descriptive alt text via the `alt` attribute.\n* Alt text SHALL be meaningful and contextually appropriate.\n* Decorative images MAY use empty alt text (`alt=""`).\n* Alt text ensures accessibility for screen reader users.\n\nQA: [BP_QA_041] - Blog Platform → Image Alt Text Test #BP041\n* Objective: Verify all images have appropriate alt text.\n* Test Cases:\n - TC1: Locate images on blog posts → Expect all have alt attribute\n - TC2: Verify alt content → Expect descriptive, not "image" or "photo"\n - TC3: Verify decorative images → Expect empty alt if purely decorative\n - TC4: Screen reader test → Expect alt text announced\n - TC5: Run accessibility audit → Expect no missing alt warnings\n* Context: Verify alt text describes image function/content\n* Length: Alt text should be concise but complete\n\nREQ: [BP042] - Blog Platform → Skip to Content Link #N048\n* The system SHALL provide a "Skip to Content" link for keyboard users.\n* The link SHALL be the first focusable element on the page.\n* Activating the link SHALL move focus to the main content area.\n* The link SHALL be visually hidden until focused.\n\nQA: [BP_QA_042] - Blog Platform → Skip Navigation Test #BP042\n* Objective: Verify skip link functionality.\n* Test Cases:\n - TC1: Load page, press Tab → Expect skip link appears first\n - TC2: Verify link visibility → Expect hidden until focused\n - TC3: Activate skip link (Enter) → Expect focus moves to main content\n - TC4: Verify target element → Expect `\u003cmain\u003e` or similar receives focus\n - TC5: Test on all page types → Expect consistent behavior\n* Focus Management: Verify focus ring visible on target after skip\n\nREQ: [BP043] - Blog Platform → Keyboard Navigation #N049\n* The system SHALL be fully navigable using keyboard only.\n* All interactive elements SHALL be reachable via Tab key.\n* All links and buttons SHALL be activatable via Enter or Space key.\n* No keyboard traps SHALL exist (user can always Tab away).\n\nQA: [BP_QA_043] - Blog Platform → Keyboard Navigation Test #BP043\n* Objective: Verify complete keyboard accessibility.\n* Test Cases:\n - TC1: Navigate entire page with Tab → Expect all elements reachable\n - TC2: Verify focus indicators → Expect visible on focused elements\n - TC3: Activate links with Enter → Expect navigation works\n - TC4: Activate buttons with Space → Expect activation works\n - TC5: Check for keyboard traps → Expect can always Tab away\n - TC6: Verify focus order → Expect logical reading order\n* Interactive Elements: Test nav links, TOC links, theme toggle, external links\n* Edge Cases: Test with sticky elements, modals if present\n\nREQ: [BP044] - Blog Platform → Color Contrast Compliance #N050\n* The system SHALL maintain sufficient color contrast ratios for readability.\n* Normal text SHALL meet WCAG 2.1 AA minimum contrast ratio of 4.5:1.\n* Large text (18pt+) SHALL meet minimum contrast ratio of 3:1.\n* Contrast requirements SHALL be met in both dark and light themes.\n\nQA: [BP_QA_044] - Blog Platform → Color Contrast Test #BP044\n* Objective: Verify WCAG 2.1 AA color contrast compliance.\n* Test Cases:\n - TC1: Run Lighthouse accessibility audit (dark theme) → Expect no contrast failures\n - TC2: Run Lighthouse accessibility audit (light theme) → Expect no contrast failures\n - TC3: Check body text contrast → Expect ≥4.5:1 ratio\n - TC4: Check heading contrast → Expect ≥4.5:1 for normal, ≥3:1 for large\n - TC5: Check link contrast → Expect distinguishable from surrounding text\n - TC6: Check code block contrast → Expect readable in both themes\n* Tools: axe DevTools, WAVE, Colour Contrast Analyser\n* Manual Check: Verify UI is readable for color-blind users\n\nREQ: [BP045] - Blog Platform → Logical Reading Order #N051\n* Rendered HTML SHALL maintain logical reading order when CSS is disabled.\n* Content sequence SHALL be meaningful without visual styling.\n* Navigation, main content, and footer SHALL appear in expected order.\n* Content SHALL NOT rely on CSS for meaning or sequence.\n\nQA: [BP_QA_045] - Blog Platform → Reading Order Test #BP045\n* Objective: Verify logical content order without CSS.\n* Test Cases:\n - TC1: Disable CSS in browser → Expect content still readable\n - TC2: Read page top-to-bottom → Expect logical sequence\n - TC3: Verify navigation position → Expect before main content\n - TC4: Verify main content → Expect after navigation\n - TC5: Verify footer position → Expect at end of document\n - TC6: Test with screen reader → Expect announces in correct order\n* Source Order: Inspect HTML source order matches visual layout intent\n* CLI Browser: Verify reading order in lynx matches expected flow\n\nREQ: [BP046] - Blog Platform → Markdown Authoring #N052\n* Blog posts SHALL be authored in Markdown format.\n* The system SHALL support standard Markdown syntax (CommonMark).\n* Source files SHALL use `.md` file extension.\n* Hugo front matter format SHALL be used for post metadata.\n\nQA: [BP_QA_046] - Blog Platform → Markdown Authoring Test #BP046\n* Objective: Verify Markdown authoring workflow.\n* Test Cases:\n - TC1: Examine content directory → Expect `.md` files\n - TC2: Verify Markdown syntax → Expect standard CommonMark\n - TC3: Verify front matter → Expect valid Hugo YAML/TOML format\n - TC4: Create test post with Markdown → Expect renders correctly\n - TC5: Test Markdown features → Headings, lists, links, images, code\n* Syntax Support: Verify tables, footnotes, task lists if extended syntax used\n\nREQ: [BP047] - Blog Platform → Syntax Highlighting #N053\n* Code blocks SHALL display syntax highlighting appropriate to the programming language.\n* Language SHALL be specified via fenced code block syntax (```language).\n* Highlighting SHALL be consistent in both dark and light themes.\n* Common languages SHALL be supported: Go, JavaScript, Python, Bash, JSON, YAML.\n\nQA: [BP_QA_047] - Blog Platform → Syntax Highlighting Test #BP047\n* Objective: Verify code syntax highlighting.\n* Test Cases:\n - TC1: View post with code blocks → Expect highlighting applied\n - TC2: Test Go code highlighting → Expect keywords colored\n - TC3: Test JavaScript highlighting → Expect appropriate colors\n - TC4: Test Python highlighting → Expect appropriate colors\n - TC5: Test Bash highlighting → Expect appropriate colors\n - TC6: Test in dark theme → Expect readable, styled\n - TC7: Test in light theme → Expect readable, styled\n* Languages: Verify Go, JS, Python, Bash, JSON, YAML, HTML, CSS\n* Edge Cases: Test unspecified language (```), unsupported language\n\nREQ: [BP048] - Blog Platform → Callout Boxes #N054\n* Posts SHALL support callout boxes for tips, warnings, and important notes.\n* Callouts SHOULD be implemented using styled blockquotes.\n* Different callout types SHALL be visually distinguishable.\n* Callouts SHALL be readable in CLI browsers (content without styling).\n\nQA: [BP_QA_048] - Blog Platform → Callout Boxes Test #BP048\n* Objective: Verify callout/admonition styling.\n* Test Cases:\n - TC1: Create post with callout syntax → Expect distinct styling\n - TC2: Test Tip callout → Expect visual indicator (color/icon)\n - TC3: Test Warning callout → Expect distinct from Tip\n - TC4: Test Note callout → Expect distinct styling\n - TC5: Test Important callout → Expect prominent styling\n - TC6: Test in CLI browser → Expect content readable (text preserved)\n* Themes: Verify callouts visible in both dark and light themes\n* Accessibility: Verify callout type is not conveyed by color alone\n\nREQ: [BP049] - Blog Platform → Local Preview #N055\n* The authoring workflow SHALL support local preview before publishing.\n* Local preview SHALL be achievable via Hugo’s built-in server (`hugo server`).\n* Changes to content SHALL be reflected in preview (live reload or manual refresh).\n* Local preview rendering SHALL match production rendering.\n\nQA: [BP_QA_049] - Blog Platform → Local Preview Test #BP049\n* Objective: Verify local development preview workflow.\n* Test Cases:\n - TC1: Clone repository → Expect successful clone\n - TC2: Run `hugo server` → Expect local server starts\n - TC3: Access localhost URL → Expect blog renders locally\n - TC4: Modify post content → Expect change visible (reload)\n - TC5: Compare to production → Expect visual parity\n* Dependencies: Verify required Hugo version documented\n* Hot Reload: Verify live reload works if supported\n\nREQ: [BP050] - Blog Platform → Server-Side Analytics #N056\n* The blog SHOULD use Cloudflare Analytics for traffic insights.\n* Analytics SHALL NOT require client-side JavaScript.\n* No analytics tracking scripts SHALL be embedded in page source.\n* This is a SHOULD requirement; graceful absence is acceptable.\n\nQA: [BP_QA_050] - Blog Platform → Analytics Test #BP050\n* Objective: Verify server-side analytics without client scripts.\n* Test Cases (if implemented):\n - TC1: Access Cloudflare dashboard → Expect analytics section available\n - TC2: Verify traffic data → Expect data collection active\n - TC3: View page source → Expect NO analytics scripts (GA, etc.)\n - TC4: Search for tracking code → Expect none found in HTML\n* Note: SHOULD requirement; document if not implemented\n* Privacy: Verify no third-party tracking scripts\n\nREQ: [BP051] - Blog Platform → Community Repository Display #N057\n* The Community page SHALL fetch and display repositories from the GitHub API.\n* Repositories SHALL be filtered by the "52vibes" topic tag.\n* API endpoint: GitHub Search API for topics.\n* Display SHALL include repository information upon successful fetch.\n\nQA: [BP_QA_051] - Blog Platform → Community Repository Display Test #BP051\n* Objective: Verify GitHub API integration for community repos.\n* Test Cases:\n - TC1: Create repo with "52vibes" topic → Setup test data\n - TC2: Navigate to `/community/` → Expect API fetch occurs\n - TC3: Verify repo appears in list → Expect tagged repo displayed\n - TC4: Verify API endpoint → Expect correct GitHub search API call\n* API Verification: Inspect network requests in DevTools\n* Cache: May require cache expiry for new repos to appear\n\nREQ: [BP052] - Blog Platform → Repository Information Display #N058\n* Each repository listing on the Community page SHALL display: name, description, and star count.\n* Repository name SHALL link to the GitHub repository.\n* Description SHALL be displayed if present in repository metadata.\n* Star count SHALL reflect current GitHub star count.\n\nQA: [BP_QA_052] - Blog Platform → Repository Information Test #BP052\n* Objective: Verify repository information display.\n* Test Cases:\n - TC1: View repository listing → Expect name displayed\n - TC2: Click repository name → Expect opens correct GitHub repo\n - TC3: Verify description → Expect repo description shown (if present)\n - TC4: Verify star count → Expect star count displayed\n - TC5: Test repo without description → Expect graceful handling\n* Link Validation: Verify link URL is correct GitHub URL\n* Data Accuracy: Compare displayed info with actual GitHub page\n\nREQ: [BP053] - Blog Platform → API Failure Handling #N059\n* The Community page SHALL gracefully handle GitHub API failures.\n* Fallback behavior: display a link to the GitHub topics page.\n* Fallback link: `https://github.com/topics/52vibes`.\n* No error messages or broken layouts SHALL be displayed to users.\n\nQA: [BP_QA_053] - Blog Platform → API Failure Handling Test #BP053\n* Objective: Verify graceful API error handling.\n* Test Cases:\n - TC1: Block GitHub API in DevTools → Simulate failure\n - TC2: Navigate to `/community/` → Expect fallback message\n - TC3: Verify fallback link → Expect link to `https://github.com/topics/52vibes`\n - TC4: Verify no error display → Expect no raw error messages\n - TC5: Verify layout intact → Expect page structure preserved\n* Failure Modes: Test network timeout, 404, 500 responses\n* User Experience: Verify fallback message is user-friendly\n\nREQ: [BP054] - Blog Platform → Community Empty State #N060\n* The Community page SHALL display a meaningful message when no repositories exist.\n* Message SHOULD encourage community participation.\n* Message SHALL include instructions for adding the "52vibes" topic.\n* Empty state SHALL NOT display as an error condition.\n\nQA: [BP_QA_054] - Blog Platform → Empty State Test #BP054\n* Objective: Verify empty state message for community page.\n* Test Cases:\n - TC1: Mock empty API response → Simulate no repos\n - TC2: Navigate to `/community/` → Expect friendly message\n - TC3: Verify message content → Expect encouraging text\n - TC4: Verify instructions → Expect guidance for adding topic\n - TC5: Verify NOT error message → Expect positive framing\n* Tone: Verify message is welcoming, not discouraging\n\nREQ: [BP055] - Blog Platform → Client-Side API Caching #N061\n* The Community page SHOULD cache GitHub API results client-side.\n* Cache duration SHOULD be reasonable (approximately 5 minutes).\n* Caching minimizes API requests and improves page load performance.\n* This is a SHOULD requirement; graceful absence is acceptable.\n\nQA: [BP_QA_055] - Blog Platform → API Caching Test #BP055\n* Objective: Verify client-side API caching (if implemented).\n* Test Cases (if implemented):\n - TC1: Navigate to `/community/` → Observe initial API request\n - TC2: Refresh page immediately → Expect NO new API request (cached)\n - TC3: Wait ~5 minutes → Refresh → Expect new API request\n - TC4: Inspect localStorage/sessionStorage → Verify cache mechanism\n* Note: SHOULD requirement; document if not implemented\n* Tools: DevTools Network tab to monitor API requests\n\nREQ: [BP056] - Blog Platform → Site Branding #N062\n* The blog SHALL display "52 VIBES" branding prominently in the header.\n* Branding SHALL appear outside/above the tmux-style frame.\n* Branding SHALL be visible on all pages.\n* Branding SHALL be readable on mobile viewports.\n\nQA: [BP_QA_056] - Blog Platform → Branding Test #BP056\n* Objective: Verify site branding display.\n* Test Cases:\n - TC1: Navigate to any page → Expect "52 VIBES" visible in header\n - TC2: Verify position → Expect outside/above tmux frame\n - TC3: Test multiple pages → Expect consistent branding\n - TC4: Test mobile viewport → Expect branding visible and readable\n - TC5: Verify in both themes → Expect readable in dark and light\n* Visual: Verify branding is prominently styled\n\nREQ: [BP057] - Blog Platform → Consistent Header #N063\n* The blog header SHALL appear consistently on all pages.\n* Header layout and styling SHALL be identical across the site.\n* Header elements (branding, navigation) SHALL maintain same position.\n* No page-specific header variations SHALL exist.\n\nQA: [BP_QA_057] - Blog Platform → Consistent Header Test #BP057\n* Objective: Verify header consistency across all pages.\n* Test Cases:\n - TC1: Navigate to blog index → Capture header appearance\n - TC2: Navigate to blog post → Compare header to baseline\n - TC3: Navigate to About page → Compare header to baseline\n - TC4: Navigate to Community page → Compare header to baseline\n - TC5: Navigate to Reports page → Compare header to baseline\n - TC6: Test mobile viewport → Verify header consistent\n* Visual Regression: Take screenshots and compare\n* Elements: Verify branding, navigation, toggle positions match\n",“id”:“20260105040104”,“path”:"./notes/20260105040104/README.md",“project”:“52vibes”,“title”:“Week 1: Requirements - Blog Platform (BP)”}`TOOL:
{"content":"# Week 1: Requirements - crush-export Tool (CX)\n\n\n\n\n## Product Overview\n\n**Product Name:** crush-export Tool \n**Product ID:** CX \n**Description:** Command-line utility written in Go that extracts session data from the Crush AI agent's SQLite database (\.crush/crush.db`) and generates wiki-ready markdown documents for publication.\n\nInstallation: `cd crush-export \u0026\u0026 go build -o crush-export ./cmd/crush-export`\n\n—\n\n## Requirements\n\n\nREQ: [CX001] - crush-export → Session Data Processing #N035\n* The tool SHALL read session data from the Crush SQLite database (`.crush/crush.db`).\n* The tool SHALL generate wiki-ready markdown documents from session data.\n* Output format SHALL be compatible with GitHub Wiki publishing.\n* The tool SHALL be implemented in Go programming language.\n* Command-line interface SHALL support listing sessions and exporting to files.\n\nQA: [CX_QA_001] - crush-export → Session Processing Test #CX001\n* Objective: Verify session data extraction from SQLite.\n* Test Cases:\n - TC1: Verify `.crush/crush.db` exists → Expect SQLite database present\n - TC2: Run `./crush-export -l` → Expect sessions listed with IDs\n - TC3: Run `./crush-export -db .crush/crush.db -out sessions/` → Expect markdown files generated\n - TC4: Verify output format → Expect valid markdown syntax\n - TC5: Verify wiki compatibility → Expect renderable in GitHub Wiki\n* Build Verification: `cd crush-export \u0026\u0026 go build -o crush-export ./cmd/crush-export`\n* Empty Database: Test with database containing no sessions\n\nREQ: [CX002] - crush-export → Metadata Extraction #N036\n* The tool SHALL extract session metadata including: duration, message count, files created/modified, and error count.\n* Metadata SHALL be included in the generated markdown document.\n* Statistics section SHALL be prominently placed in the output.\n* Accuracy of metadata SHALL be verified against raw session data.\n\nQA: [CX_QA_002] - crush-export → Metadata Extraction Test #CX002\n* Objective: Verify session metadata is correctly extracted.\n* Test Cases:\n - TC1: Run export on known session → Examine output markdown\n - TC2: Verify duration field → Expect session duration included\n - TC3: Verify message count → Expect total message count included\n - TC4: Verify files modified count → Expect files created/modified count\n - TC5: Verify error count → Expect error count included\n* Boundary Cases:\n - BC1: Empty session (no messages) → Expect graceful handling\n - BC2: Single-message session → Expect minimal output\n - BC3: Long session (100+ messages) → Expect complete processing\n* Accuracy: Cross-reference metadata with database query results\n\nREQ: [CX003] - crush-export → Document Structure #N032\n* The generated markdown document SHALL include the following sections:\n - "Lessons Learned" section (placeholder for human curation)\n - Session statistics section\n - Key conversation excerpts section\n - Full conversation log section\n* Section ordering SHALL follow the specified hierarchy.\n* Full conversation log MAY use collapsible sections for readability.\n\nQA: [CX_QA_003] - crush-export → Document Structure Test #CX003\n* Objective: Verify output document structure.\n* Test Cases:\n - TC1: Examine output markdown → Expect "Lessons Learned" section\n - TC2: Verify statistics section → Expect session statistics present\n - TC3: Verify key excerpts → Expect key conversation excerpts section\n - TC4: Verify full log → Expect full conversation log section\n - TC5: Verify section order → Expect Lessons → Stats → Excerpts → Full Log\n - TC6: Verify rendering → Expect renders correctly in GitHub Wiki\n* Markdown Validation: Verify valid Markdown syntax throughout\n\nREQ: [CX004] - crush-export → Command-Line Interface #N035\n* The tool SHALL provide the following CLI flags:\n - `-db`: Path to crush.db (default: `.crush/crush.db`)\n - `-out`: Output directory for markdown files (default: `sessions`)\n - `-session`: Export specific session ID (optional)\n - `-l`: List all sessions (list mode)\n* Flag parsing SHALL follow standard Go conventions.\n* Help text SHALL be available via `-h` or `–help`.\n\nQA: [CX_QA_004] - crush-export → CLI Interface Test #CX004\n* Objective: Verify command-line interface functionality.\n* Test Cases:\n - TC1: Run `./crush-export -h` → Expect help text displayed\n - TC2: Run `./crush-export -l` → Expect sessions listed\n - TC3: Run with `-db` flag → Expect custom database path used\n - TC4: Run with `-out` flag → Expect custom output directory used\n - TC5: Run with `-session` flag → Expect specific session exported\n - TC6: Run with invalid flag → Expect error message\n* Default Values: Verify defaults work when flags omitted\n* Error Handling: Verify missing database file error message\n",“id”:“20260105040107”,“path”:"./notes/20260105040107/README.md",“project”:“52vibes”,“title”:“Week 1: Requirements - crush-export Tool (CX)”}`TOOL:
{"content":"# Week 1: Requirements - Session Log Sync (SL)\n\n\n\n\n## Product Overview\n\n**Product Name:** Session Log Sync \n**Product ID:** SL \n**Description:** GitHub Actions workflow that automatically synchronizes session log markdown files from the \sessions/` directory to the GitHub Wiki, enabling independent updates without triggering blog rebuilds.\n\nTrigger: Push to main branch affecting `sessions/.md`\n\n—\n\n## Requirements\n\n\nREQ: [SL001] - Session Log Sync → GitHub Wiki Publication #N031\n Session logs SHALL be published to the GitHub Wiki.\n* Wiki publication SHALL be separate from the main blog.\n* Wiki pages SHALL be accessible at the repository’s wiki URL.\n* Wiki structure SHALL be navigable and organized.\n\nQA: [SL_QA_001] - Session Log Sync → Wiki Publication Test #SL001\n* Objective: Verify session logs appear on GitHub Wiki.\n* Test Cases:\n - TC1: Navigate to GitHub Wiki → Expect wiki exists\n - TC2: Verify session log pages → Expect pages for completed weeks\n - TC3: Verify content formatting → Expect markdown renders correctly\n - TC4: Verify wiki is separate → Expect different URL from blog\n - TC5: Verify navigation → Expect wiki sidebar/index functional\n* URL Structure: Verify wiki URL follows `github.com/\u003cowner\u003e/\u003crepo\u003e/wiki/` pattern\n\nREQ: [SL002] - Session Log Sync → Independent Updates #N033\n* Session logs SHALL be updatable independently of the main blog.\n* Updating session logs SHALL NOT trigger a blog rebuild.\n* Changes to `sessions/` directory SHALL only affect wiki synchronization.\n* Blog deployment and wiki sync SHALL be separate workflows.\n\nQA: [SL_QA_002] - Session Log Sync → Independent Updates Test #SL002\n* Objective: Verify session logs update without blog rebuild.\n* Test Cases:\n - TC1: Update session log file → Commit and push\n - TC2: Observe GitHub Actions → Expect wiki sync workflow runs\n - TC3: Monitor Cloudflare Pages → Expect NO blog build triggered\n - TC4: Verify wiki updated → Expect changes reflected\n - TC5: Verify blog unchanged → Expect blog content unchanged\n* Workflow Isolation: Verify separate workflow files for wiki vs blog\n\nREQ: [SL003] - Session Log Sync → Automatic Synchronization #N034\n* Session log files in the main repository SHALL be automatically synchronized to the GitHub Wiki.\n* Synchronization SHALL be triggered by pushes to main branch affecting `sessions/.md`.\n Implementation SHALL use GitHub Actions workflow.\n* New files SHALL create new wiki pages; modified files SHALL update existing pages.\n\nQA: [SL_QA_003] - Session Log Sync → Automatic Sync Test #SL003\n* Objective: Verify automatic wiki synchronization.\n* Test Cases:\n - TC1: Add new session markdown file → Push to main\n - TC2: Observe GitHub Actions → Expect sync workflow triggers\n - TC3: Verify wiki page created → Expect new page appears\n - TC4: Modify existing session file → Push to main\n - TC5: Verify wiki page updated → Expect changes reflected\n - TC6: Delete session file → Verify expected behavior\n* Trigger Verification: Verify workflow triggers on `sessions/.md` changes only\n Workflow File: Verify `.github/workflows/` contains wiki sync workflow\n\nREQ: [SL004] - Session Log Sync → GitHub Actions Workflow #N034\n* The workflow SHALL be implemented as a GitHub Actions YAML file.\n* Workflow SHALL clone the wiki repository for updates.\n* Workflow SHALL copy session markdown files to wiki repository.\n* Workflow SHALL commit and push changes to wiki repository.\n* Workflow SHALL use appropriate GitHub token for wiki access.\n\nQA: [SL_QA_004] - Session Log Sync → Workflow Implementation Test #SL004\n* Objective: Verify GitHub Actions workflow implementation.\n* Test Cases:\n - TC1: Locate workflow file → Expect `.github/workflows/wiki-sync.yml` or similar\n - TC2: Verify trigger conditions → Expect triggers on push to main\n - TC3: Verify path filter → Expect filters for `sessions/**`\n - TC4: Verify wiki clone step → Expect clones wiki repo\n - TC5: Verify copy step → Expect copies session files\n - TC6: Verify commit/push step → Expect commits and pushes to wiki\n - TC7: Verify token usage → Expect appropriate authentication\n* Security: Verify secrets handling for GitHub token\n* Error Handling: Verify workflow handles failures gracefully\n",“id”:“20260105040109”,“path”:"./notes/20260105040109/README.md",“project”:“52vibes”,“title”:“Week 1: Requirements - Session Log Sync (SL)”}`AI: I’ve reviewed all 65 product requirements across 3 products:
- BP (Blog Platform): 57 requirements
- CX (crush-export): 4 requirements
- SL (Session Log Sync): 4 requirements
Before I can create detailed technical requirements, I need to clarify several technical decisions. Let me start with the Blog Platform since it’s the largest and most complex.
Technical Context Questions - Blog Platform
1. Static Site Generator & Hosting
Question Context Hugo version? Which version should the technical requirements target? (e.g., v0.120+for specific features)Cloudflare Pages build settings? Node version, environment variables, build command customizations? Custom domain DNS setup? Is 52vibes.devalready configured? Is it Cloudflare-managed or external DNS?2. Theme Architecture
Question Context Theme toggle mechanism? CSS-only via prefers-color-scheme+ JS enhancement, or JS-required toggle? Should this use CSS custom properties for runtime switching?Font loading strategy? Self-hosted fonts, Google Fonts CDN, or Cloudflare Fonts? Subset fonts for performance? Build-time vs runtime social cards? Generate images at build time (Hugo image processing) or use a serverless function? 3. Community Page Architecture
Question Context GitHub API rate limiting strategy? Public unauthenticated calls (60/hour) vs authenticated. Client-side vs build-time fetch? Caching approach? localStorage, sessionStorage, HTTP caching headers? 4. Accessibility & CLI Browser Support
Question Context Minimum WCAG compliance level? AA (standard) or AAA (enhanced)? Priority CLI browser? lynx (most restrictive) or w3m (better table support)? Once you answer these, I’ll proceed with technical requirements. Should I continue with questions for crush-export and Session Log Sync as well?
BREAK: 2026-01-05 00:17:29 - 2026-01-05 07:58:32 (461 min 3 sec)
USER: ### 1. Static Site Generator & Hosting
- Hugo version? Which version should the technical requirements target? (e.g., v0.120+ for specific features) ANSWER: The latest version, unless you have a strong reason to use a older version.
- Cloudflare Pages build settings? Node version, environment variables, build command customizations? ANSWER: I want to avoid NPM. But if absolutely needed, use latest version. For now no customizations. Env. variables - you can use whatever required. Make sure you document all of them.
- Custom domain DNS setup? Is
52vibes.devalready configured? Is it Cloudflare-managed or external DNS? ANSWER: I only bought the domain from Cloudflare. Nothing has been configured. If you cannot do it yourself, tell me what needs to be done and I’ll do it.
2. Theme Architecture
- Theme toggle mechanism? CSS-only via prefers-color-scheme + JS enhancement, or JS-required toggle? Should this use CSS custom properties for runtime switching? ANSWER: CSS + JS enhancement (if required for persistence). I want to minimize JS usage as much as possible.
- Font loading strategy? Self-hosted fonts, Google Fonts CDN, or Cloudflare Fonts? Subset fonts for performance? ANSWER: Google Fonts CDN is preferred. But if you have a strong reason to self-host them, design and implement things accordingly. If you need me to do anything, be specific and tell me.
- Build-time vs runtime social cards? Generate images at build time (Hugo image processing) or use a serverless function? ANSWER: I don’t want to run any server-side logic since I don’t want to incur additional cost to run my blog.
3. Community Page Architecture
- GitHub API rate limiting strategy? Public unauthenticated calls (60/hour) vs authenticated. Client-side vs buildi-time fetch? ANSWER: I am not going to copy auth material into a client facing page. So, unauthenticated API is the only choice.
- Caching approach? localStorage, sessionStorage, HTTP caching headers? ANSWER: You choose. Give clear reasons for your choice.
4. Accessibility & CLI Browser Support
- Minimum WCAG compliance level? AA (standard) or AAA (enhanced)? ANSWER: 2.2 at level AA. But if you can hit AAA, go for it.
- Priority CLI browser? lynx (most restrictive) or w3m (better table support)? ANSWER: I would test against both. So it should render on both .If table support is a problem, be smart and figure out how to publish content to be able to work with both browsers.
AI: Excellent technical context. Let me document my technical decisions before creating requirements:
Technical Decisions Summary
Area Decision Rationale Hugo Version v0.139+ (latest extended) Extended version needed for SCSS processing, image manipulation Social Cards Build-time via Hugo image processing No server cost, static generation Caching localStorage with 5-min TTL Persists across tabs/sessions, reduces API calls, simple vanilla JS CLI Browsers Semantic HTML + CSS media queries Tables use <table>withroleattributes; fallback text for complex layoutsNow creating technical requirement zettels for all three products.
TOOL-CALL: mcp_note_create_note
{"project":"52vibes","title":"Week 1: Technical Requirements - Blog Platform (BP-TECH)","content":"\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator |...TOOL-CALL: mcp_note_create_note
{"project":"52vibes","title":"Week 1: Technical Requirements - crush-export (CX-TECH)","content":"\n## Product Overview\n\n**Product Name:** crush-export Tool \n**Product ID:** CX \n**Technical Spec ID:** CX-TECH \n**Description:** Technical architecture and implementation requirements for the Go CLI tool that extracts Crush AI session data from SQLite and generates wiki-ready markdown.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----...TOOL-CALL: mcp_note_create_note
{"project":"52vibes","title":"Week 1: Technical Requirements - Session Log Sync (SL-TECH)","content":"\n## Product Overview\n\n**Product Name:** Session Log Sync \n**Product ID:** SL \n**Technical Spec ID:** SL-TECH \n**Description:** Technical architecture and implementation requirements for the GitHub Actions workflow that synchronizes session logs to GitHub Wiki.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| CI/CD Plat...TOOL:
{"id":"20260105125854","message":"Created note 20260105125854 in project '52vibes'","path":"./notes/20260105125854/README.md","project":"52vibes"}TOOL:
{"id":"20260105125856","message":"Created note 20260105125856 in project '52vibes'","path":"./notes/20260105125856/README.md","project":"52vibes"}TOOL:
{"id":"20260105125859","message":"Created note 20260105125859 in project '52vibes'","path":"./notes/20260105125859/README.md","project":"52vibes"}AI: Created technical requirement zettels:
- BP-TECH:
20260105125854 - CX-TECH:
20260105125856 - SL-TECH:
20260105125859
Now starting with BP001 (Primary URL Endpoint). This requires several technical requirements covering DNS, Cloudflare Pages setup, and Hugo configuration.
- BP-TECH:
TOOL-CALL: mcp_note_get_note
{"project":"52vibes","note_id":"20260105125854"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n","id":"20260105125854","path":"./notes/20260105125854/README.md","project":"52vibes","title":"Week 1: Technical Requirements - Blog Platform (BP-TECH)"}TOOL-CALL: mcp_note_update_note
{"project":"52vibes","note_id":"20260105125854","old_content":"## Technical Requirements","new_content":"## Technical Requirements\n\n### Infrastructure & Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform \u2192 Cloudflare DNS Configuration #BP001\n* The domain52vibes.devSHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point52vibes.devto the Cloudflare Pages deployment URL (.pages.dev ).\n* Cloudflare proxy (orange cloud) SHALL be enabled for ...TOOL:
{"message":"Updated note 20260105125854","success":true}AI: Added infrastructure requirements for BP001. Continuing with BP002 (JavaScript-Free Core) and BP003-BP004 (Responsive/Performance).
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125854","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n\n### Infrastructure \u0026 Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform → Cloudflare DNS Configuration #BP001\n* The domain \52vibes.dev` SHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point `52vibes.dev` to the Cloudflare Pages deployment URL (`\u003cproject\u003e.pages.dev`).\n* Cloudflare proxy (orange cloud) SHALL be enabled for CDN and SSL termination.\n* DNS propagation SHALL complete within 24 hours of configuration.\n* The `www` subdomain SHOULD redirect to the apex domain (`52vibes.dev`).\n* References:\n + Cloudflare Pages Custom Domains\n\nSYSTEST: [BP_DNS_TEST_0001] - Blog Platform → DNS Resolution Verification #BP_DNS_0001\n* Objective: Verify DNS resolves correctly to Cloudflare Pages.\n* Setup: Configure DNS records in Cloudflare dashboard.\n* Test Steps:\n - TS1: Run `dig 52vibes.dev` → Expect CNAME or A record pointing to Cloudflare\n - TS2: Run `dig www.52vibes.dev` → Expect redirect record configured\n - TS3: Query from multiple geographic locations → Expect consistent resolution\n - TS4: Verify Cloudflare proxy status → Expect orange cloud enabled in dashboard\n* Boundary Cases:\n - BC1: Test immediately after DNS change → Document propagation time\n - BC2: Test from different ISPs → Expect consistent results after propagation\n\nTECH_REQ: [BP_CFP_0001] - Blog Platform → Cloudflare Pages Project Configuration #BP001\n* A Cloudflare Pages project SHALL be created and linked to the GitHub repository.\n* Build configuration SHALL specify:\n - Build command: `hugo –minify`\n - Build output directory: `public`\n - Root directory: `/` (repository root)\n - Hugo version environment variable: `HUGO_VERSION=0.139.0`\n* Production branch SHALL be set to `main`.\n* Preview deployments SHALL be enabled for pull requests.\n* The project name SHALL result in a `.pages.dev` URL that serves the site.\n References:\n + Cloudflare Pages Hugo Framework Guide\n\nSYSTEST: [BP_CFP_TEST_0001] - Blog Platform → Cloudflare Pages Build Verification #BP_CFP_0001\n* Objective: Verify Cloudflare Pages builds and deploys successfully.\n* Setup: Link GitHub repository to Cloudflare Pages project.\n* Test Steps:\n - TS1: Push commit to main branch → Expect build triggers automatically\n - TS2: Monitor build logs → Expect Hugo build completes without errors\n - TS3: Verify build output → Expect `public/` directory generated\n - TS4: Access `\u003cproject\u003e.pages.dev` → Expect site accessible\n - TS5: Verify HUGO_VERSION in build → Expect version 0.139.0 or higher\n* Failure Cases:\n - FC1: Invalid Hugo config → Expect build fails with clear error\n - FC2: Missing theme → Expect build fails, previous deployment remains live\n* Performance:\n - Measure build duration → Expect under 2 minutes for initial build\n - Measure deployment time → Expect under 1 minute after build\n\nTECH_REQ: [BP_CFP_0002] - Blog Platform → Environment Variables #BP001\n* The following environment variables SHALL be configured in Cloudflare Pages:\n - `HUGO_VERSION`: `0.139.0` (or latest stable)\n - `HUGO_ENVIRONMENT`: `production` (for production builds)\n* Environment variables SHALL be set in Cloudflare Pages project settings.\n* No sensitive credentials SHALL be stored in environment variables for this project.\n* References:\n + Cloudflare Pages Environment Variables\n\nSYSTEST: [BP_CFP_TEST_0002] - Blog Platform → Environment Variable Verification #BP_CFP_0002\n* Objective: Verify environment variables are correctly applied.\n* Setup: Configure environment variables in Cloudflare Pages dashboard.\n* Test Steps:\n - TS1: Trigger build → Inspect build logs for HUGO_VERSION\n - TS2: Verify Hugo version in output → Expect matches configured version\n - TS3: Check production environment → Expect HUGO_ENVIRONMENT=production\n* Verification:\n - Build log SHALL show "Hugo v0.139.0" or configured version\n\nTECH_REQ: [BP_HUGO_0001] - Blog Platform → Hugo Base URL Configuration #BP001\n* Hugo configuration SHALL set `baseURL` to `https://52vibes.dev/`.\n* Hugo configuration file SHALL be `hugo.toml` (TOML format preferred).\n* The blog section SHALL be configured to serve content from `/blog/` path.\n* Configuration SHALL include:\n - `languageCode`: `en-us`\n - `title`: `52 Vibes`\n - `enableRobotsTXT`: `true`\n - `enableGitInfo`: `true` (for lastmod dates)\n* References:\n + Hugo Configuration\n\nSYSTEST: [BP_HUGO_TEST_0001] - Blog Platform → Base URL and Path Verification #BP_HUGO_0001\n* Objective: Verify Hugo generates correct URLs and paths.\n* Setup: Build site locally with `hugo –minify`.\n* Test Steps:\n - TS1: Inspect generated HTML → Expect all URLs use `https://52vibes.dev/`\n - TS2: Verify blog index path → Expect accessible at `/blog/`\n - TS3: Check canonical URLs → Expect `\u003clink rel="canonical"\u003e` uses correct base\n - TS4: Verify internal links → Expect no broken internal links\n - TS5: Check sitemap.xml → Expect all URLs use production base URL\n* Local vs Production:\n - Local development MAY use `localhost:1313`\n - Production build MUST use `https://52vibes.dev/`\n\nTECH_REQ: [BP_SSL_0001] - Blog Platform → HTTPS and SSL Configuration #BP001\n* All traffic SHALL be served over HTTPS.\n* HTTP requests SHALL redirect to HTTPS (301 permanent redirect).\n* SSL certificate SHALL be automatically provisioned by Cloudflare.\n* SSL mode SHALL be set to "Full (strict)" in Cloudflare settings.\n* HSTS (HTTP Strict Transport Security) SHOULD be enabled.\n* References:\n + Cloudflare SSL/TLS\n\nSYSTEST: [BP_SSL_TEST_0001] - Blog Platform → HTTPS and Certificate Verification #BP_SSL_0001\n* Objective: Verify SSL/TLS is correctly configured.\n* Test Steps:\n - TS1: Request `http://52vibes.dev/blog` → Expect 301 redirect to HTTPS\n - TS2: Request `https://52vibes.dev/blog` → Expect HTTP 200\n - TS3: Inspect certificate → Expect valid, issued by Cloudflare\n - TS4: Check certificate expiry → Expect auto-renewal configured\n - TS5: Test with SSL Labs → Expect A or A+ rating\n* Security Headers:\n - Verify HSTS header present (if enabled)\n - Check for secure cookies (if any)\n* References:\n + SSL Labs Server Test\n",“id”:“20260105125854”,“path”:"./notes/20260105125854/README.md",“project”:“52vibes”,“title”:“Week 1: Technical Requirements - Blog Platform (BP-TECH)”}`TOOL-CALL: mcp_note_update_note
{"old_content":"* **References:**\n + [SSL Labs Server Test](https://www.ssllabs.com/ssltest/)","new_content":"* **References:**\n + [SSL Labs Server Test](https://www.ssllabs.com/ssltest/)\n\n### Core Architecture (BP002, BP003, BP004)\n\nTECH_REQ: [BP_SSR_0001] - Blog Platform \u2192 Server-Side Rendering Architecture #BP002\n* All page content SHALL be rendered at build time by Hugo (Static Site Generation).\n* HTML output SHALL contain complete content without requiring JavaScript hydratio...TOOL:
{"message":"Updated note 20260105125854","success":true}AI: Continuing with BP005-BP011 (Deployment pipeline, CLI browsers, Visual design).
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125854","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n\n### Infrastructure \u0026 Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform → Cloudflare DNS Configuration #BP001\n* The domain \52vibes.dev` SHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point `52vibes.dev` to the Cloudflare Pages deployment URL (`\u003cproject\u003e.pages.dev`).\n* Cloudflare proxy (orange cloud) SHALL be enabled for CDN and SSL termination.\n* DNS propagation SHALL complete within 24 hours of configuration.\n* The `www` subdomain SHOULD redirect to the apex domain (`52vibes.dev`).\n* References:\n + Cloudflare Pages Custom Domains\n\nSYSTEST: [BP_DNS_TEST_0001] - Blog Platform → DNS Resolution Verification #BP_DNS_0001\n* Objective: Verify DNS resolves correctly to Cloudflare Pages.\n* Setup: Configure DNS records in Cloudflare dashboard.\n* Test Steps:\n - TS1: Run `dig 52vibes.dev` → Expect CNAME or A record pointing to Cloudflare\n - TS2: Run `dig www.52vibes.dev` → Expect redirect record configured\n - TS3: Query from multiple geographic locations → Expect consistent resolution\n - TS4: Verify Cloudflare proxy status → Expect orange cloud enabled in dashboard\n* Boundary Cases:\n - BC1: Test immediately after DNS change → Document propagation time\n - BC2: Test from different ISPs → Expect consistent results after propagation\n\nTECH_REQ: [BP_CFP_0001] - Blog Platform → Cloudflare Pages Project Configuration #BP001\n* A Cloudflare Pages project SHALL be created and linked to the GitHub repository.\n* Build configuration SHALL specify:\n - Build command: `hugo –minify`\n - Build output directory: `public`\n - Root directory: `/` (repository root)\n - Hugo version environment variable: `HUGO_VERSION=0.139.0`\n* Production branch SHALL be set to `main`.\n* Preview deployments SHALL be enabled for pull requests.\n* The project name SHALL result in a `.pages.dev` URL that serves the site.\n References:\n + Cloudflare Pages Hugo Framework Guide\n\nSYSTEST: [BP_CFP_TEST_0001] - Blog Platform → Cloudflare Pages Build Verification #BP_CFP_0001\n* Objective: Verify Cloudflare Pages builds and deploys successfully.\n* Setup: Link GitHub repository to Cloudflare Pages project.\n* Test Steps:\n - TS1: Push commit to main branch → Expect build triggers automatically\n - TS2: Monitor build logs → Expect Hugo build completes without errors\n - TS3: Verify build output → Expect `public/` directory generated\n - TS4: Access `\u003cproject\u003e.pages.dev` → Expect site accessible\n - TS5: Verify HUGO_VERSION in build → Expect version 0.139.0 or higher\n* Failure Cases:\n - FC1: Invalid Hugo config → Expect build fails with clear error\n - FC2: Missing theme → Expect build fails, previous deployment remains live\n* Performance:\n - Measure build duration → Expect under 2 minutes for initial build\n - Measure deployment time → Expect under 1 minute after build\n\nTECH_REQ: [BP_CFP_0002] - Blog Platform → Environment Variables #BP001\n* The following environment variables SHALL be configured in Cloudflare Pages:\n - `HUGO_VERSION`: `0.139.0` (or latest stable)\n - `HUGO_ENVIRONMENT`: `production` (for production builds)\n* Environment variables SHALL be set in Cloudflare Pages project settings.\n* No sensitive credentials SHALL be stored in environment variables for this project.\n* References:\n + Cloudflare Pages Environment Variables\n\nSYSTEST: [BP_CFP_TEST_0002] - Blog Platform → Environment Variable Verification #BP_CFP_0002\n* Objective: Verify environment variables are correctly applied.\n* Setup: Configure environment variables in Cloudflare Pages dashboard.\n* Test Steps:\n - TS1: Trigger build → Inspect build logs for HUGO_VERSION\n - TS2: Verify Hugo version in output → Expect matches configured version\n - TS3: Check production environment → Expect HUGO_ENVIRONMENT=production\n* Verification:\n - Build log SHALL show "Hugo v0.139.0" or configured version\n\nTECH_REQ: [BP_HUGO_0001] - Blog Platform → Hugo Base URL Configuration #BP001\n* Hugo configuration SHALL set `baseURL` to `https://52vibes.dev/`.\n* Hugo configuration file SHALL be `hugo.toml` (TOML format preferred).\n* The blog section SHALL be configured to serve content from `/blog/` path.\n* Configuration SHALL include:\n - `languageCode`: `en-us`\n - `title`: `52 Vibes`\n - `enableRobotsTXT`: `true`\n - `enableGitInfo`: `true` (for lastmod dates)\n* References:\n + Hugo Configuration\n\nSYSTEST: [BP_HUGO_TEST_0001] - Blog Platform → Base URL and Path Verification #BP_HUGO_0001\n* Objective: Verify Hugo generates correct URLs and paths.\n* Setup: Build site locally with `hugo –minify`.\n* Test Steps:\n - TS1: Inspect generated HTML → Expect all URLs use `https://52vibes.dev/`\n - TS2: Verify blog index path → Expect accessible at `/blog/`\n - TS3: Check canonical URLs → Expect `\u003clink rel="canonical"\u003e` uses correct base\n - TS4: Verify internal links → Expect no broken internal links\n - TS5: Check sitemap.xml → Expect all URLs use production base URL\n* Local vs Production:\n - Local development MAY use `localhost:1313`\n - Production build MUST use `https://52vibes.dev/`\n\nTECH_REQ: [BP_SSL_0001] - Blog Platform → HTTPS and SSL Configuration #BP001\n* All traffic SHALL be served over HTTPS.\n* HTTP requests SHALL redirect to HTTPS (301 permanent redirect).\n* SSL certificate SHALL be automatically provisioned by Cloudflare.\n* SSL mode SHALL be set to "Full (strict)" in Cloudflare settings.\n* HSTS (HTTP Strict Transport Security) SHOULD be enabled.\n* References:\n + Cloudflare SSL/TLS\n\nSYSTEST: [BP_SSL_TEST_0001] - Blog Platform → HTTPS and Certificate Verification #BP_SSL_0001\n* Objective: Verify SSL/TLS is correctly configured.\n* Test Steps:\n - TS1: Request `http://52vibes.dev/blog` → Expect 301 redirect to HTTPS\n - TS2: Request `https://52vibes.dev/blog` → Expect HTTP 200\n - TS3: Inspect certificate → Expect valid, issued by Cloudflare\n - TS4: Check certificate expiry → Expect auto-renewal configured\n - TS5: Test with SSL Labs → Expect A or A+ rating\n* Security Headers:\n - Verify HSTS header present (if enabled)\n - Check for secure cookies (if any)\n* References:\n + SSL Labs Server Test\n\n### Core Architecture (BP002, BP003, BP004)\n\nTECH_REQ: [BP_SSR_0001] - Blog Platform → Server-Side Rendering Architecture #BP002\n* All page content SHALL be rendered at build time by Hugo (Static Site Generation).\n* HTML output SHALL contain complete content without requiring JavaScript hydration.\n* No client-side templating frameworks (React, Vue, etc.) SHALL be used.\n* Hugo templates SHALL use Go template syntax for content rendering.\n* Template directory structure SHALL follow Hugo conventions:\n - `layouts/_default/baseof.html` - base template\n - `layouts/_default/single.html` - single content pages\n - `layouts/_default/list.html` - list/index pages\n - `layouts/partials/` - reusable template components\n* References:\n + Hugo Templates\n\nSYSTEST: [BP_SSR_TEST_0001] - Blog Platform → Static Rendering Verification #BP_SSR_0001\n* Objective: Verify all content is statically rendered.\n* Test Steps:\n - TS1: Build site with `hugo –minify` → Inspect `public/` directory\n - TS2: Open any HTML file → Expect complete content in source\n - TS3: Disable JavaScript in browser → Load page → Expect all content visible\n - TS4: Use `curl` to fetch page → Expect complete HTML in response\n - TS5: Check for hydration scripts → Expect none present\n* Content Types:\n - Test blog post pages\n - Test index/list pages\n - Test static pages (About, etc.)\n\nTECH_REQ: [BP_NOJS_0001] - Blog Platform → JavaScript Budget and Constraints #BP002\n* Total JavaScript payload SHALL NOT exceed 2KB (minified, uncompressed).\n* JavaScript SHALL be used ONLY for:\n - Theme toggle persistence (localStorage) - ~500 bytes\n - Community page GitHub API fetch - ~1KB\n* No JavaScript frameworks or libraries SHALL be included.\n* All JavaScript SHALL be inline (no external JS files) or in a single bundled file.\n* JavaScript SHALL use vanilla ES6+ syntax (no transpilation required for modern browsers).\n* References:\n + JavaScript Module Best Practices\n\nSYSTEST: [BP_NOJS_TEST_0001] - Blog Platform → JavaScript Budget Verification #BP_NOJS_0001\n* Objective: Verify JavaScript stays within budget.\n* Test Steps:\n - TS1: Build production site → Locate all JavaScript in output\n - TS2: Measure total JS size → Expect ≤2KB minified\n - TS3: List all JS functionality → Expect only theme toggle + API fetch\n - TS4: Check for framework code → Expect none (React, Vue, jQuery, etc.)\n - TS5: Verify ES6+ syntax → Expect no transpilation artifacts\n* Tools:\n - Use browser DevTools Network tab\n - Use `wc -c` on minified JS files\n\nTECH_REQ: [BP_GRACE_0001] - Blog Platform → Graceful Degradation Strategy #BP002\n* When JavaScript is disabled:\n - Theme SHALL default to system preference via `prefers-color-scheme`\n - Theme toggle control SHALL remain visible but non-functional\n - Community page SHALL display fallback link to GitHub topics page\n* No "JavaScript required" messages SHALL be displayed.\n* No broken layouts or missing content SHALL occur without JavaScript.\n* All navigation SHALL remain fully functional without JavaScript.\n* References:\n + Progressive Enhancement\n\nSYSTEST: [BP_GRACE_TEST_0001] - Blog Platform → Graceful Degradation Verification #BP_GRACE_0001\n* Objective: Verify site functions correctly without JavaScript.\n* Setup: Disable JavaScript in browser settings.\n* Test Steps:\n - TS1: Load blog index → Expect all posts listed, readable\n - TS2: Navigate between pages → Expect all links work\n - TS3: Check theme → Expect matches system preference\n - TS4: View theme toggle → Expect visible (may be non-functional)\n - TS5: Load Community page → Expect fallback content/link displayed\n - TS6: Check for error messages → Expect none\n* Browsers:\n - Test in Chrome, Firefox with JS disabled\n - Test in lynx (inherently no JS)\n\nTECH_REQ: [BP_RESP_0001] - Blog Platform → Responsive Breakpoint System #BP003\n* CSS SHALL implement the following breakpoint system:\n - Mobile: `max-width: 767px`\n - Tablet: `min-width: 768px` and `max-width: 1023px`\n - Desktop: `min-width: 1024px`\n - Large Desktop: `min-width: 1440px` (optional enhancement)\n* Breakpoints SHALL be defined as CSS custom properties or SCSS variables.\n* Mobile-first approach SHALL be used (base styles for mobile, media queries for larger).\n* No horizontal scrolling SHALL occur at any viewport width ≥320px.\n* References:\n + CSS Media Queries\n\nSYSTEST: [BP_RESP_TEST_0001] - Blog Platform → Breakpoint Behavior Verification #BP_RESP_0001\n* Objective: Verify responsive behavior at all breakpoints.\n* Test Steps:\n - TS1: Set viewport to 320px width → Expect no horizontal scroll, content readable\n - TS2: Set viewport to 375px width → Expect mobile layout\n - TS3: Set viewport to 768px width → Expect tablet layout transition\n - TS4: Set viewport to 1024px width → Expect desktop layout\n - TS5: Set viewport to 1920px width → Expect full desktop layout\n - TS6: Resize viewport dynamically → Expect smooth transitions\n* Orientation:\n - Test mobile viewports in portrait and landscape\n* Content Types:\n - Test with long code blocks\n - Test with tables\n - Test with images\n\nTECH_REQ: [BP_RESP_0002] - Blog Platform → Fluid Typography and Spacing #BP003\n* Typography SHALL scale fluidly using CSS `clamp()` function.\n* Base font size range: `clamp(16px, 2.5vw, 18px)` for body text.\n* Heading sizes SHALL scale proportionally.\n* Spacing (margins, padding) SHALL use relative units (rem, em) or viewport units.\n* Line length SHALL be constrained to 65-75 characters for readability.\n* References:\n + CSS clamp()\n\nSYSTEST: [BP_RESP_TEST_0002] - Blog Platform → Typography Scaling Verification #BP_RESP_0002\n* Objective: Verify typography scales appropriately.\n* Test Steps:\n - TS1: Inspect body font size at 320px viewport → Expect ~16px\n - TS2: Inspect body font size at 1920px viewport → Expect ~18px\n - TS3: Measure line length in characters → Expect 65-75 characters max\n - TS4: Check heading hierarchy → Expect proportional scaling\n - TS5: Verify relative units in CSS → Expect rem/em usage\n* Readability:\n - Verify text is readable at all viewport sizes\n - Verify adequate spacing between elements\n\nTECH_REQ: [BP_PERF_0001] - Blog Platform → Asset Optimization Pipeline #BP004\n* Hugo asset pipeline SHALL be configured for optimization:\n - CSS: Minification enabled, unused CSS removal (if using SCSS)\n - HTML: Minification via `hugo –minify`\n - Images: WebP conversion with fallback, responsive srcset generation\n* Total page weight targets:\n - Blog index: ≤500KB\n - Blog post (without images): ≤300KB\n - Any page with images: ≤800KB\n* Asset fingerprinting SHALL be enabled for cache busting.\n* References:\n + Hugo Asset Minification\n + Hugo Image Processing\n\nSYSTEST: [BP_PERF_TEST_0001] - Blog Platform → Asset Optimization Verification #BP_PERF_0001\n* Objective: Verify assets are properly optimized.\n* Test Steps:\n - TS1: Build with `hugo –minify` → Verify minification applied\n - TS2: Inspect CSS output → Expect minified (no whitespace/comments)\n - TS3: Inspect HTML output → Expect minified\n - TS4: Check image formats → Expect WebP with fallbacks\n - TS5: Measure page weights → Verify within budget\n - TS6: Check asset URLs → Expect fingerprinted filenames\n* Tools:\n - Use browser DevTools Network tab for size measurements\n - Use `du -h` on output files\n\nTECH_REQ: [BP_PERF_0002] - Blog Platform → Core Web Vitals Optimization #BP004\n* Largest Contentful Paint (LCP) SHALL be under 2.5 seconds.\n* First Input Delay (FID) SHALL be under 100ms.\n* Cumulative Layout Shift (CLS) SHALL be under 0.1.\n* First Contentful Paint (FCP) SHOULD be under 1.5 seconds.\n* Implementation strategies:\n - Preload critical fonts\n - Inline critical CSS\n - Defer non-critical resources\n - Reserve space for dynamic content (prevent layout shifts)\n* References:\n + Core Web Vitals\n\nSYSTEST: [BP_PERF_TEST_0002] - Blog Platform → Core Web Vitals Measurement #BP_PERF_0002\n* Objective: Verify Core Web Vitals meet targets.\n* Test Steps:\n - TS1: Run Lighthouse on blog index → Expect Performance ≥95\n - TS2: Measure LCP → Expect \u003c2.5s\n - TS3: Measure FID → Expect \u003c100ms\n - TS4: Measure CLS → Expect \u003c0.1\n - TS5: Measure FCP → Expect \u003c1.5s\n - TS6: Run on multiple page types → Expect consistent scores\n* Testing Conditions:\n - Test with throttled connection (Slow 4G)\n - Test with CPU throttling (4x slowdown)\n* Tools:\n - Chrome DevTools Lighthouse\n - WebPageTest.org\n - PageSpeed Insights\n\nTECH_REQ: [BP_PERF_0003] - Blog Platform → Font Loading Strategy #BP004\n* Fonts SHALL be loaded from Google Fonts CDN.\n* Font loading SHALL use `font-display: swap` to prevent invisible text.\n* Font preconnect hints SHALL be included in `\u003chead\u003e`:\n - `\u003clink rel="preconnect" href="https://fonts.googleapis.com"\u003e`\n - `\u003clink rel="preconnect" href="https://fonts.gstatic.com" crossorigin\u003e`\n* Font families to load:\n - IBM Plex Sans: weights 400, 500, 600, 700\n - JetBrains Mono: weight 400\n* Font subsetting SHOULD be applied (latin subset only for initial load).\n* References:\n + Google Fonts CSS API\n + font-display\n\nSYSTEST: [BP_PERF_TEST_0003] - Blog Platform → Font Loading Verification #BP_PERF_0003\n* Objective: Verify fonts load efficiently without blocking render.\n* Test Steps:\n - TS1: Inspect `\u003chead\u003e` → Expect preconnect hints for Google Fonts\n - TS2: Check font-display → Expect `swap` in font declarations\n - TS3: Block Google Fonts → Expect fallback fonts display immediately\n - TS4: Measure font load time → Expect \u003c500ms on fast connection\n - TS5: Check for FOIT (Flash of Invisible Text) → Expect none\n - TS6: Check for FOUT (Flash of Unstyled Text) → Acceptable with swap\n* Network Tab:\n - Verify font files loaded from fonts.gstatic.com\n - Verify only required weights loaded\n",“id”:“20260105125854”,“path”:"./notes/20260105125854/README.md",“project”:“52vibes”,“title”:“Week 1: Technical Requirements - Blog Platform (BP-TECH)”}`TOOL-CALL: mcp_note_update_note
{"new_content":"* **Network Tab:**\n - Verify font files loaded from fonts.gstatic.com\n - Verify only required weights loaded\n\nTECH_REQ: [BP_DEPLOY_0001] - Blog Platform \u2192 Deployment Time Constraints #BP005\n* Content-only changes SHALL deploy within 5 minutes of push to main branch.\n* Full site rebuilds SHALL complete within 10 minutes.\n* Cloudflare Pages build SHALL NOT require manual intervention.\n* Build failures SHALL NOT affect live production site (atomic deployments).\n* Dep...TOOL:
{"message":"Updated note 20260105125854","success":true}AI: Continuing with navigation (BP012-BP016) and content pages (BP017-BP023).
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125854","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n\n### Infrastructure \u0026 Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform → Cloudflare DNS Configuration #BP001\n* The domain \52vibes.dev` SHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point `52vibes.dev` to the Cloudflare Pages deployment URL (`\u003cproject\u003e.pages.dev`).\n* Cloudflare proxy (orange cloud) SHALL be enabled for CDN and SSL termination.\n* DNS propagation SHALL complete within 24 hours of configuration.\n* The `www` subdomain SHOULD redirect to the apex domain (`52vibes.dev`).\n* References:\n + Cloudflare Pages Custom Domains\n\nSYSTEST: [BP_DNS_TEST_0001] - Blog Platform → DNS Resolution Verification #BP_DNS_0001\n* Objective: Verify DNS resolves correctly to Cloudflare Pages.\n* Setup: Configure DNS records in Cloudflare dashboard.\n* Test Steps:\n - TS1: Run `dig 52vibes.dev` → Expect CNAME or A record pointing to Cloudflare\n - TS2: Run `dig www.52vibes.dev` → Expect redirect record configured\n - TS3: Query from multiple geographic locations → Expect consistent resolution\n - TS4: Verify Cloudflare proxy status → Expect orange cloud enabled in dashboard\n* Boundary Cases:\n - BC1: Test immediately after DNS change → Document propagation time\n - BC2: Test from different ISPs → Expect consistent results after propagation\n\nTECH_REQ: [BP_CFP_0001] - Blog Platform → Cloudflare Pages Project Configuration #BP001\n* A Cloudflare Pages project SHALL be created and linked to the GitHub repository.\n* Build configuration SHALL specify:\n - Build command: `hugo –minify`\n - Build output directory: `public`\n - Root directory: `/` (repository root)\n - Hugo version environment variable: `HUGO_VERSION=0.139.0`\n* Production branch SHALL be set to `main`.\n* Preview deployments SHALL be enabled for pull requests.\n* The project name SHALL result in a `.pages.dev` URL that serves the site.\n References:\n + Cloudflare Pages Hugo Framework Guide\n\nSYSTEST: [BP_CFP_TEST_0001] - Blog Platform → Cloudflare Pages Build Verification #BP_CFP_0001\n* Objective: Verify Cloudflare Pages builds and deploys successfully.\n* Setup: Link GitHub repository to Cloudflare Pages project.\n* Test Steps:\n - TS1: Push commit to main branch → Expect build triggers automatically\n - TS2: Monitor build logs → Expect Hugo build completes without errors\n - TS3: Verify build output → Expect `public/` directory generated\n - TS4: Access `\u003cproject\u003e.pages.dev` → Expect site accessible\n - TS5: Verify HUGO_VERSION in build → Expect version 0.139.0 or higher\n* Failure Cases:\n - FC1: Invalid Hugo config → Expect build fails with clear error\n - FC2: Missing theme → Expect build fails, previous deployment remains live\n* Performance:\n - Measure build duration → Expect under 2 minutes for initial build\n - Measure deployment time → Expect under 1 minute after build\n\nTECH_REQ: [BP_CFP_0002] - Blog Platform → Environment Variables #BP001\n* The following environment variables SHALL be configured in Cloudflare Pages:\n - `HUGO_VERSION`: `0.139.0` (or latest stable)\n - `HUGO_ENVIRONMENT`: `production` (for production builds)\n* Environment variables SHALL be set in Cloudflare Pages project settings.\n* No sensitive credentials SHALL be stored in environment variables for this project.\n* References:\n + Cloudflare Pages Environment Variables\n\nSYSTEST: [BP_CFP_TEST_0002] - Blog Platform → Environment Variable Verification #BP_CFP_0002\n* Objective: Verify environment variables are correctly applied.\n* Setup: Configure environment variables in Cloudflare Pages dashboard.\n* Test Steps:\n - TS1: Trigger build → Inspect build logs for HUGO_VERSION\n - TS2: Verify Hugo version in output → Expect matches configured version\n - TS3: Check production environment → Expect HUGO_ENVIRONMENT=production\n* Verification:\n - Build log SHALL show "Hugo v0.139.0" or configured version\n\nTECH_REQ: [BP_HUGO_0001] - Blog Platform → Hugo Base URL Configuration #BP001\n* Hugo configuration SHALL set `baseURL` to `https://52vibes.dev/`.\n* Hugo configuration file SHALL be `hugo.toml` (TOML format preferred).\n* The blog section SHALL be configured to serve content from `/blog/` path.\n* Configuration SHALL include:\n - `languageCode`: `en-us`\n - `title`: `52 Vibes`\n - `enableRobotsTXT`: `true`\n - `enableGitInfo`: `true` (for lastmod dates)\n* References:\n + Hugo Configuration\n\nSYSTEST: [BP_HUGO_TEST_0001] - Blog Platform → Base URL and Path Verification #BP_HUGO_0001\n* Objective: Verify Hugo generates correct URLs and paths.\n* Setup: Build site locally with `hugo –minify`.\n* Test Steps:\n - TS1: Inspect generated HTML → Expect all URLs use `https://52vibes.dev/`\n - TS2: Verify blog index path → Expect accessible at `/blog/`\n - TS3: Check canonical URLs → Expect `\u003clink rel="canonical"\u003e` uses correct base\n - TS4: Verify internal links → Expect no broken internal links\n - TS5: Check sitemap.xml → Expect all URLs use production base URL\n* Local vs Production:\n - Local development MAY use `localhost:1313`\n - Production build MUST use `https://52vibes.dev/`\n\nTECH_REQ: [BP_SSL_0001] - Blog Platform → HTTPS and SSL Configuration #BP001\n* All traffic SHALL be served over HTTPS.\n* HTTP requests SHALL redirect to HTTPS (301 permanent redirect).\n* SSL certificate SHALL be automatically provisioned by Cloudflare.\n* SSL mode SHALL be set to "Full (strict)" in Cloudflare settings.\n* HSTS (HTTP Strict Transport Security) SHOULD be enabled.\n* References:\n + Cloudflare SSL/TLS\n\nSYSTEST: [BP_SSL_TEST_0001] - Blog Platform → HTTPS and Certificate Verification #BP_SSL_0001\n* Objective: Verify SSL/TLS is correctly configured.\n* Test Steps:\n - TS1: Request `http://52vibes.dev/blog` → Expect 301 redirect to HTTPS\n - TS2: Request `https://52vibes.dev/blog` → Expect HTTP 200\n - TS3: Inspect certificate → Expect valid, issued by Cloudflare\n - TS4: Check certificate expiry → Expect auto-renewal configured\n - TS5: Test with SSL Labs → Expect A or A+ rating\n* Security Headers:\n - Verify HSTS header present (if enabled)\n - Check for secure cookies (if any)\n* References:\n + SSL Labs Server Test\n\n### Core Architecture (BP002, BP003, BP004)\n\nTECH_REQ: [BP_SSR_0001] - Blog Platform → Server-Side Rendering Architecture #BP002\n* All page content SHALL be rendered at build time by Hugo (Static Site Generation).\n* HTML output SHALL contain complete content without requiring JavaScript hydration.\n* No client-side templating frameworks (React, Vue, etc.) SHALL be used.\n* Hugo templates SHALL use Go template syntax for content rendering.\n* Template directory structure SHALL follow Hugo conventions:\n - `layouts/_default/baseof.html` - base template\n - `layouts/_default/single.html` - single content pages\n - `layouts/_default/list.html` - list/index pages\n - `layouts/partials/` - reusable template components\n* References:\n + Hugo Templates\n\nSYSTEST: [BP_SSR_TEST_0001] - Blog Platform → Static Rendering Verification #BP_SSR_0001\n* Objective: Verify all content is statically rendered.\n* Test Steps:\n - TS1: Build site with `hugo –minify` → Inspect `public/` directory\n - TS2: Open any HTML file → Expect complete content in source\n - TS3: Disable JavaScript in browser → Load page → Expect all content visible\n - TS4: Use `curl` to fetch page → Expect complete HTML in response\n - TS5: Check for hydration scripts → Expect none present\n* Content Types:\n - Test blog post pages\n - Test index/list pages\n - Test static pages (About, etc.)\n\nTECH_REQ: [BP_NOJS_0001] - Blog Platform → JavaScript Budget and Constraints #BP002\n* Total JavaScript payload SHALL NOT exceed 2KB (minified, uncompressed).\n* JavaScript SHALL be used ONLY for:\n - Theme toggle persistence (localStorage) - ~500 bytes\n - Community page GitHub API fetch - ~1KB\n* No JavaScript frameworks or libraries SHALL be included.\n* All JavaScript SHALL be inline (no external JS files) or in a single bundled file.\n* JavaScript SHALL use vanilla ES6+ syntax (no transpilation required for modern browsers).\n* References:\n + JavaScript Module Best Practices\n\nSYSTEST: [BP_NOJS_TEST_0001] - Blog Platform → JavaScript Budget Verification #BP_NOJS_0001\n* Objective: Verify JavaScript stays within budget.\n* Test Steps:\n - TS1: Build production site → Locate all JavaScript in output\n - TS2: Measure total JS size → Expect ≤2KB minified\n - TS3: List all JS functionality → Expect only theme toggle + API fetch\n - TS4: Check for framework code → Expect none (React, Vue, jQuery, etc.)\n - TS5: Verify ES6+ syntax → Expect no transpilation artifacts\n* Tools:\n - Use browser DevTools Network tab\n - Use `wc -c` on minified JS files\n\nTECH_REQ: [BP_GRACE_0001] - Blog Platform → Graceful Degradation Strategy #BP002\n* When JavaScript is disabled:\n - Theme SHALL default to system preference via `prefers-color-scheme`\n - Theme toggle control SHALL remain visible but non-functional\n - Community page SHALL display fallback link to GitHub topics page\n* No "JavaScript required" messages SHALL be displayed.\n* No broken layouts or missing content SHALL occur without JavaScript.\n* All navigation SHALL remain fully functional without JavaScript.\n* References:\n + Progressive Enhancement\n\nSYSTEST: [BP_GRACE_TEST_0001] - Blog Platform → Graceful Degradation Verification #BP_GRACE_0001\n* Objective: Verify site functions correctly without JavaScript.\n* Setup: Disable JavaScript in browser settings.\n* Test Steps:\n - TS1: Load blog index → Expect all posts listed, readable\n - TS2: Navigate between pages → Expect all links work\n - TS3: Check theme → Expect matches system preference\n - TS4: View theme toggle → Expect visible (may be non-functional)\n - TS5: Load Community page → Expect fallback content/link displayed\n - TS6: Check for error messages → Expect none\n* Browsers:\n - Test in Chrome, Firefox with JS disabled\n - Test in lynx (inherently no JS)\n\nTECH_REQ: [BP_RESP_0001] - Blog Platform → Responsive Breakpoint System #BP003\n* CSS SHALL implement the following breakpoint system:\n - Mobile: `max-width: 767px`\n - Tablet: `min-width: 768px` and `max-width: 1023px`\n - Desktop: `min-width: 1024px`\n - Large Desktop: `min-width: 1440px` (optional enhancement)\n* Breakpoints SHALL be defined as CSS custom properties or SCSS variables.\n* Mobile-first approach SHALL be used (base styles for mobile, media queries for larger).\n* No horizontal scrolling SHALL occur at any viewport width ≥320px.\n* References:\n + CSS Media Queries\n\nSYSTEST: [BP_RESP_TEST_0001] - Blog Platform → Breakpoint Behavior Verification #BP_RESP_0001\n* Objective: Verify responsive behavior at all breakpoints.\n* Test Steps:\n - TS1: Set viewport to 320px width → Expect no horizontal scroll, content readable\n - TS2: Set viewport to 375px width → Expect mobile layout\n - TS3: Set viewport to 768px width → Expect tablet layout transition\n - TS4: Set viewport to 1024px width → Expect desktop layout\n - TS5: Set viewport to 1920px width → Expect full desktop layout\n - TS6: Resize viewport dynamically → Expect smooth transitions\n* Orientation:\n - Test mobile viewports in portrait and landscape\n* Content Types:\n - Test with long code blocks\n - Test with tables\n - Test with images\n\nTECH_REQ: [BP_RESP_0002] - Blog Platform → Fluid Typography and Spacing #BP003\n* Typography SHALL scale fluidly using CSS `clamp()` function.\n* Base font size range: `clamp(16px, 2.5vw, 18px)` for body text.\n* Heading sizes SHALL scale proportionally.\n* Spacing (margins, padding) SHALL use relative units (rem, em) or viewport units.\n* Line length SHALL be constrained to 65-75 characters for readability.\n* References:\n + CSS clamp()\n\nSYSTEST: [BP_RESP_TEST_0002] - Blog Platform → Typography Scaling Verification #BP_RESP_0002\n* Objective: Verify typography scales appropriately.\n* Test Steps:\n - TS1: Inspect body font size at 320px viewport → Expect ~16px\n - TS2: Inspect body font size at 1920px viewport → Expect ~18px\n - TS3: Measure line length in characters → Expect 65-75 characters max\n - TS4: Check heading hierarchy → Expect proportional scaling\n - TS5: Verify relative units in CSS → Expect rem/em usage\n* Readability:\n - Verify text is readable at all viewport sizes\n - Verify adequate spacing between elements\n\nTECH_REQ: [BP_PERF_0001] - Blog Platform → Asset Optimization Pipeline #BP004\n* Hugo asset pipeline SHALL be configured for optimization:\n - CSS: Minification enabled, unused CSS removal (if using SCSS)\n - HTML: Minification via `hugo –minify`\n - Images: WebP conversion with fallback, responsive srcset generation\n* Total page weight targets:\n - Blog index: ≤500KB\n - Blog post (without images): ≤300KB\n - Any page with images: ≤800KB\n* Asset fingerprinting SHALL be enabled for cache busting.\n* References:\n + Hugo Asset Minification\n + Hugo Image Processing\n\nSYSTEST: [BP_PERF_TEST_0001] - Blog Platform → Asset Optimization Verification #BP_PERF_0001\n* Objective: Verify assets are properly optimized.\n* Test Steps:\n - TS1: Build with `hugo –minify` → Verify minification applied\n - TS2: Inspect CSS output → Expect minified (no whitespace/comments)\n - TS3: Inspect HTML output → Expect minified\n - TS4: Check image formats → Expect WebP with fallbacks\n - TS5: Measure page weights → Verify within budget\n - TS6: Check asset URLs → Expect fingerprinted filenames\n* Tools:\n - Use browser DevTools Network tab for size measurements\n - Use `du -h` on output files\n\nTECH_REQ: [BP_PERF_0002] - Blog Platform → Core Web Vitals Optimization #BP004\n* Largest Contentful Paint (LCP) SHALL be under 2.5 seconds.\n* First Input Delay (FID) SHALL be under 100ms.\n* Cumulative Layout Shift (CLS) SHALL be under 0.1.\n* First Contentful Paint (FCP) SHOULD be under 1.5 seconds.\n* Implementation strategies:\n - Preload critical fonts\n - Inline critical CSS\n - Defer non-critical resources\n - Reserve space for dynamic content (prevent layout shifts)\n* References:\n + Core Web Vitals\n\nSYSTEST: [BP_PERF_TEST_0002] - Blog Platform → Core Web Vitals Measurement #BP_PERF_0002\n* Objective: Verify Core Web Vitals meet targets.\n* Test Steps:\n - TS1: Run Lighthouse on blog index → Expect Performance ≥95\n - TS2: Measure LCP → Expect \u003c2.5s\n - TS3: Measure FID → Expect \u003c100ms\n - TS4: Measure CLS → Expect \u003c0.1\n - TS5: Measure FCP → Expect \u003c1.5s\n - TS6: Run on multiple page types → Expect consistent scores\n* Testing Conditions:\n - Test with throttled connection (Slow 4G)\n - Test with CPU throttling (4x slowdown)\n* Tools:\n - Chrome DevTools Lighthouse\n - WebPageTest.org\n - PageSpeed Insights\n\nTECH_REQ: [BP_PERF_0003] - Blog Platform → Font Loading Strategy #BP004\n* Fonts SHALL be loaded from Google Fonts CDN.\n* Font loading SHALL use `font-display: swap` to prevent invisible text.\n* Font preconnect hints SHALL be included in `\u003chead\u003e`:\n - `\u003clink rel="preconnect" href="https://fonts.googleapis.com"\u003e`\n - `\u003clink rel="preconnect" href="https://fonts.gstatic.com" crossorigin\u003e`\n* Font families to load:\n - IBM Plex Sans: weights 400, 500, 600, 700\n - JetBrains Mono: weight 400\n* Font subsetting SHOULD be applied (latin subset only for initial load).\n* References:\n + Google Fonts CSS API\n + font-display\n\nSYSTEST: [BP_PERF_TEST_0003] - Blog Platform → Font Loading Verification #BP_PERF_0003\n* Objective: Verify fonts load efficiently without blocking render.\n* Test Steps:\n - TS1: Inspect `\u003chead\u003e` → Expect preconnect hints for Google Fonts\n - TS2: Check font-display → Expect `swap` in font declarations\n - TS3: Block Google Fonts → Expect fallback fonts display immediately\n - TS4: Measure font load time → Expect \u003c500ms on fast connection\n - TS5: Check for FOIT (Flash of Invisible Text) → Expect none\n - TS6: Check for FOUT (Flash of Unstyled Text) → Acceptable with swap\n* Network Tab:\n - Verify font files loaded from fonts.gstatic.com\n - Verify only required weights loaded\n\nTECH_REQ: [BP_DEPLOY_0001] - Blog Platform → Deployment Time Constraints #BP005\n* Content-only changes SHALL deploy within 5 minutes of push to main branch.\n* Full site rebuilds SHALL complete within 10 minutes.\n* Cloudflare Pages build SHALL NOT require manual intervention.\n* Build failures SHALL NOT affect live production site (atomic deployments).\n* Deployment notifications SHOULD be available via Cloudflare dashboard.\n* References:\n + Cloudflare Pages Deployments\n\nSYSTEST: [BP_DEPLOY_TEST_0001] - Blog Platform → Deployment Time Verification #BP_DEPLOY_0001\n* Objective: Verify deployment completes within time constraints.\n* Test Steps:\n - TS1: Push content-only change (markdown file) → Start timer\n - TS2: Monitor Cloudflare Pages deployment → Record completion time\n - TS3: Verify deployed content → Expect change visible\n - TS4: Calculate total time → Expect ≤5 minutes\n* Failure Recovery:\n - Push invalid change → Verify build fails\n - Verify live site unchanged → Previous version still served\n* Metrics:\n - Document average build times over 10 deployments\n\n### CLI Browser Compatibility (BP006)\n\nTECH_REQ: [BP_CLI_0001] - Blog Platform → Semantic HTML for CLI Rendering #BP006\n* HTML structure SHALL prioritize semantic elements that render well in text browsers.\n* Required semantic elements:\n - `\u003cheader\u003e` for site header\n - `\u003cnav\u003e` for navigation with `\u003cul\u003e` list structure\n - `\u003cmain\u003e` for primary content\n - `\u003carticle\u003e` for blog posts\n - `\u003csection\u003e` for content sections with headings\n - `\u003cfooter\u003e` for site footer\n* Links SHALL use descriptive text (no "click here").\n* Images SHALL include meaningful `alt` text for text-only display.\n* References:\n + HTML Semantic Elements\n\nSYSTEST: [BP_CLI_TEST_0001] - Blog Platform → Lynx Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in lynx browser.\n* Setup: Install lynx text browser.\n* Test Steps:\n - TS1: `lynx https://52vibes.dev/blog` → Expect page loads, title visible\n - TS2: Navigate to blog post → Expect content fully readable\n - TS3: Follow navigation links → Expect all work correctly\n - TS4: Check TOC anchor links → Expect navigate to sections\n - TS5: View post with code blocks → Expect code readable\n - TS6: Check for broken elements → Expect none\n* Content Verification:\n - Verify all text content visible\n - Verify links clearly labeled\n - Verify image alt text displayed\n\nSYSTEST: [BP_CLI_TEST_0002] - Blog Platform → w3m Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in w3m browser.\n* Setup: Install w3m text browser.\n* Test Steps:\n - TS1: `w3m https://52vibes.dev/blog` → Expect page loads\n - TS2: Navigate to Weekly Index → Expect table renders readably\n - TS3: Verify table alignment → Expect columns aligned\n - TS4: Follow navigation links → Expect all work correctly\n - TS5: Test forms (if any) → Expect usable\n* Table Testing:\n - Weekly Index table with 52 weeks → Must be readable\n - Tables in blog posts → Must render with structure\n\nTECH_REQ: [BP_CLI_0002] - Blog Platform → Table Rendering Strategy #BP006\n* Tables SHALL use standard HTML `\u003ctable\u003e` elements with proper structure.\n* Required table elements:\n - `\u003cthead\u003e` with `\u003cth\u003e` headers for accessibility\n - `\u003ctbody\u003e` for data rows\n - `scope` attributes on header cells\n* Tables SHALL NOT use CSS grid/flexbox to simulate tables.\n* Complex tables SHOULD include `\u003ccaption\u003e` for context.\n* Very wide tables MAY use horizontal scroll container on mobile (CSS only).\n* For CLI browsers, tables SHALL degrade to readable text columns.\n* References:\n + HTML Table Accessibility\n\nSYSTEST: [BP_CLI_TEST_0003] - Blog Platform → Table Accessibility Verification #BP_CLI_0002\n* Objective: Verify tables are accessible and CLI-friendly.\n* Test Steps:\n - TS1: Inspect Weekly Index table HTML → Expect `\u003cthead\u003e`, `\u003ctbody\u003e`, `\u003cth\u003e`\n - TS2: Check `scope` attributes → Expect on header cells\n - TS3: Test in screen reader → Expect headers announced\n - TS4: Test in w3m → Expect table structure preserved\n - TS5: Test in lynx → Expect readable (may linearize)\n* Mobile:\n - Test table at 320px viewport → Verify readable without breaking layout\n\n### Visual Design System (BP007, BP008, BP009, BP010, BP011)\n\nTECH_REQ: [BP_TMUX_0001] - Blog Platform → Tmux-Inspired Layout Structure #BP007\n* Page layout SHALL implement a tmux-inspired terminal aesthetic:\n - Top status bar: Fixed height, full width, contains week numbers\n - Main content pane: Bordered frame containing page content\n - Bottom navigation bar: Fixed height, full width, contains nav links\n* CSS borders SHALL create the framed appearance (no ASCII characters).\n* Border style SHALL be `solid 1px` using theme colors.\n* Content pane SHOULD have subtle inner padding (1-2rem).\n* Layout SHALL remain consistent across all page types.\n* References:\n + tmux Manual (for aesthetic reference)\n\nSYSTEST: [BP_TMUX_TEST_0001] - Blog Platform → Tmux Layout Verification #BP_TMUX_0001\n* Objective: Verify tmux-inspired visual design.\n* Test Steps:\n - TS1: Load any page → Verify top status bar present\n - TS2: Verify main content area → Expect bordered frame\n - TS3: Verify bottom navigation → Expect navigation bar present\n - TS4: Compare to tmux screenshot → Expect similar aesthetic\n - TS5: Test multiple pages → Expect consistent layout\n* Visual Elements:\n - Status bar contains week numbers (clickable for completed weeks)\n - Main pane has visible border\n - Navigation bar at bottom with links\n\nTECH_REQ: [BP_GRUVBOX_0001] - Blog Platform → Gruvbox Color Palette Implementation #BP008\n* Color system SHALL be based on Gruvbox color palette.\n* CSS custom properties SHALL define all colors:\n ```css\n /* Dark theme /\n –bg-dark: #1d2021;\n –bg-dark-soft: #282828;\n –fg-dark: #ebdbb2;\n –accent: #d65d0e;\n –green: #b8bb26;\n –red: #fb4934;\n –yellow: #fabd2f;\n –blue: #83a598;\n \n / Light theme /\n –bg-light: #fbf1c7;\n –bg-light-soft: #f2e5bc;\n –fg-light: #3c3836;\n ```\n All UI elements SHALL use these CSS custom properties (no hardcoded colors).\n* Accent color (#d65d0e orange) SHALL be used for interactive elements.\n* References:\n + Gruvbox GitHub\n\nSYSTEST: [BP_GRUVBOX_TEST_0001] - Blog Platform → Color Palette Verification #BP_GRUVBOX_0001\n* Objective: Verify Gruvbox colors are correctly implemented.\n* Test Steps:\n - TS1: Inspect CSS → Expect custom properties defined\n - TS2: Dark mode background → Sample color → Expect #1d2021 or similar\n - TS3: Light mode background → Sample color → Expect #fbf1c7 or similar\n - TS4: Dark mode text → Sample color → Expect #ebdbb2 or similar\n - TS5: Light mode text → Sample color → Expect #3c3836 or similar\n - TS6: Accent color (links, buttons) → Expect #d65d0e\n* Tools:\n - Use browser color picker DevTools\n - Verify CSS custom properties in computed styles\n\nTECH_REQ: [BP_THEME_0001] - Blog Platform → CSS Theme Switching Mechanism #BP008\n* Default theme SHALL be determined by `prefers-color-scheme` media query.\n* CSS SHALL use media query to apply theme-specific custom properties:\n ```css\n :root {\n /* Light theme defaults /\n }\n @media (prefers-color-scheme: dark) {\n :root {\n / Dark theme overrides /\n }\n }\n ```\n A `data-theme` attribute on `\u003chtml\u003e` element SHALL allow JavaScript override.\n* When `data-theme="dark"` or `data-theme="light"` is set, it SHALL override system preference.\n* Theme transition SHALL NOT cause layout shift (CLS).\n* References:\n + prefers-color-scheme\n\nSYSTEST: [BP_THEME_TEST_0001] - Blog Platform → Theme Switching Verification #BP_THEME_0001\n* Objective: Verify CSS theme switching works correctly.\n* Test Steps:\n - TS1: Set OS to dark mode → Load page → Expect dark theme\n - TS2: Set OS to light mode → Load page → Expect light theme\n - TS3: Set `data-theme="dark"` in DevTools → Expect dark theme override\n - TS4: Set `data-theme="light"` in DevTools → Expect light theme override\n - TS5: Toggle system preference → Expect theme updates (if no JS override)\n* No JavaScript:\n - Disable JS → Verify theme follows system preference\n\nTECH_REQ: [BP_TOGGLE_0001] - Blog Platform → Theme Toggle Implementation #BP009\n* A visible toggle control SHALL be placed in the page header or footer.\n* Toggle SHALL be implemented as a `\u003cbutton\u003e` element for accessibility.\n* Toggle SHALL have appropriate ARIA attributes:\n - `aria-label`: "Toggle dark/light theme"\n - `aria-pressed`: "true" or "false" based on state\n* Clicking toggle SHALL:\n 1. Set `data-theme` attribute on `\u003chtml\u003e`\n 2. Store preference in localStorage key `theme`\n 3. Update button visual state\n* JavaScript for toggle SHALL be under 500 bytes minified.\n* References:\n + ARIA button pattern\n\nSYSTEST: [BP_TOGGLE_TEST_0001] - Blog Platform → Theme Toggle Functionality #BP_TOGGLE_0001\n* Objective: Verify theme toggle works and persists preference.\n* Test Steps:\n - TS1: Locate toggle button → Expect visible in header/footer\n - TS2: Click toggle in dark mode → Expect switch to light\n - TS3: Click toggle in light mode → Expect switch to dark\n - TS4: Inspect localStorage → Expect `theme` key set\n - TS5: Refresh page → Expect preference persisted\n - TS6: Close browser, reopen → Expect preference persisted\n* Accessibility:\n - TS7: Inspect `aria-label` → Expect descriptive label\n - TS8: Tab to toggle → Expect focusable\n - TS9: Press Enter on focused toggle → Expect theme change\n - TS10: Check `aria-pressed` → Expect updates with state\n\nTECH_REQ: [BP_TOGGLE_0002] - Blog Platform → Theme Preference Persistence #BP009\n* Theme preference SHALL be stored in localStorage under key `theme`.\n* Valid values: `"dark"`, `"light"`, or absent (system preference).\n* On page load, JavaScript SHALL:\n 1. Check localStorage for `theme` value\n 2. If set, apply `data-theme` attribute\n 3. If not set, defer to CSS `prefers-color-scheme`\n* Theme restoration SHALL occur before first paint (inline script in `\u003chead\u003e`).\n* This prevents flash of wrong theme on page load.\n* References:\n + localStorage API\n\nSYSTEST: [BP_TOGGLE_TEST_0002] - Blog Platform → Theme Persistence Edge Cases #BP_TOGGLE_0002\n* Objective: Verify theme persistence handles edge cases.\n* Test Steps:\n - TS1: Clear localStorage → Load page → Expect system preference\n - TS2: Set theme → Load new page → Expect theme persists\n - TS3: Set theme → Hard refresh (Ctrl+Shift+R) → Expect theme persists\n - TS4: Set invalid localStorage value → Load page → Expect graceful fallback\n - TS5: localStorage unavailable → Load page → Expect system preference\n* Flash Prevention:\n - TS6: Set dark preference → Load page → Expect NO flash of light theme\n\nTECH_REQ: [BP_TYPO_0001] - Blog Platform → Typography System Implementation #BP010\n* Font family stack SHALL be defined in CSS custom properties:\n ```css\n –font-body: ‘IBM Plex Sans’, -apple-system, BlinkMacSystemFont, sans-serif;\n –font-mono: ‘JetBrains Mono’, ‘SF Mono’, ‘Menlo’, monospace;\n ```\n* Font sizes SHALL use a modular scale (ratio ~1.25):\n - `–font-size-sm`: 0.875rem (14px)\n - `–font-size-base`: 1rem (16px)\n - `–font-size-lg`: 1.125rem (18px)\n - `–font-size-xl`: 1.25rem (20px)\n - `–font-size-2xl`: 1.5rem (24px)\n - `–font-size-3xl`: 2rem (32px)\n* Line height for body text SHALL be 1.6-1.7 for readability.\n* References:\n + Modular Scale\n\nSYSTEST: [BP_TYPO_TEST_0001] - Blog Platform → Typography Implementation Verification #BP_TYPO_0001\n* Objective: Verify correct fonts and sizes are applied.\n* Test Steps:\n - TS1: Inspect body text → Expect IBM Plex Sans\n - TS2: Inspect headings → Expect IBM Plex Sans\n - TS3: Inspect code blocks → Expect JetBrains Mono\n - TS4: Inspect inline code → Expect JetBrains Mono\n - TS5: Check body font size → Expect 16-18px\n - TS6: Check line height → Expect 1.6-1.7\n* Fallback:\n - Block Google Fonts → Expect system fonts render cleanly\n\nTECH_REQ: [BP_BORDER_0001] - Blog Platform → CSS Border System #BP011\n* All visual borders SHALL be implemented using CSS `border` properties.\n* ASCII box-drawing characters SHALL NOT be used for structural elements.\n* Border colors SHALL use CSS custom properties for theme compatibility.\n* Standard border definition:\n ```css\n –border-color: var(–fg-dark); /* or –fg-light /\n –border-width: 1px;\n –border-style: solid;\n ```\n Border radius SHALL be minimal or zero for terminal aesthetic.\n* References:\n + CSS Borders\n\nSYSTEST: [BP_BORDER_TEST_0001] - Blog Platform → Border Implementation Verification #BP_BORDER_0001\n* Objective: Verify CSS borders, not ASCII characters.\n* Test Steps:\n - TS1: Inspect page HTML source → Search for box-drawing Unicode (─│┌┐└┘)\n - TS2: Expect NOT found in structural elements\n - TS3: Inspect border elements via DevTools → Expect CSS border properties\n - TS4: Toggle theme → Expect borders visible in both themes\n - TS5: Test in CLI browser → Expect readable without borders\n* Unicode Check:\n - Search: U+2500-U+257F (Box Drawing block)\n - These MAY appear in content, but NOT for layout\n",“id”:“20260105125854”,“path”:"./notes/20260105125854/README.md",“project”:“52vibes”,“title”:“Week 1: Technical Requirements - Blog Platform (BP-TECH)”}`TOOL-CALL: mcp_note_update_note
{"new_content":"* **Unicode Check:**\n - Search: U+2500-U+257F (Box Drawing block)\n - These MAY appear in content, but NOT for layout\n\n### Navigation System (BP012, BP013, BP014, BP015, BP016)\n\nTECH_REQ: [BP_NAV_0001] - Blog Platform \u2192 Week Status Bar Implementation #BP012\n* Top status bar SHALL display week numbers 1-52.\n* Week numbers SHALL be generated by Hugo template from content data.\n* Implementation SHALL use Hugo's.Site.Pagesto determine completed weeks.\n* Completed ...TOOL:
{"message":"Updated note 20260105125854","success":true}AI: Continuing with URL structure (BP024-BP030) and SEO requirements (BP031-BP039).
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125854","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n\n### Infrastructure \u0026 Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform → Cloudflare DNS Configuration #BP001\n* The domain \52vibes.dev` SHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point `52vibes.dev` to the Cloudflare Pages deployment URL (`\u003cproject\u003e.pages.dev`).\n* Cloudflare proxy (orange cloud) SHALL be enabled for CDN and SSL termination.\n* DNS propagation SHALL complete within 24 hours of configuration.\n* The `www` subdomain SHOULD redirect to the apex domain (`52vibes.dev`).\n* References:\n + Cloudflare Pages Custom Domains\n\nSYSTEST: [BP_DNS_TEST_0001] - Blog Platform → DNS Resolution Verification #BP_DNS_0001\n* Objective: Verify DNS resolves correctly to Cloudflare Pages.\n* Setup: Configure DNS records in Cloudflare dashboard.\n* Test Steps:\n - TS1: Run `dig 52vibes.dev` → Expect CNAME or A record pointing to Cloudflare\n - TS2: Run `dig www.52vibes.dev` → Expect redirect record configured\n - TS3: Query from multiple geographic locations → Expect consistent resolution\n - TS4: Verify Cloudflare proxy status → Expect orange cloud enabled in dashboard\n* Boundary Cases:\n - BC1: Test immediately after DNS change → Document propagation time\n - BC2: Test from different ISPs → Expect consistent results after propagation\n\nTECH_REQ: [BP_CFP_0001] - Blog Platform → Cloudflare Pages Project Configuration #BP001\n* A Cloudflare Pages project SHALL be created and linked to the GitHub repository.\n* Build configuration SHALL specify:\n - Build command: `hugo –minify`\n - Build output directory: `public`\n - Root directory: `/` (repository root)\n - Hugo version environment variable: `HUGO_VERSION=0.139.0`\n* Production branch SHALL be set to `main`.\n* Preview deployments SHALL be enabled for pull requests.\n* The project name SHALL result in a `.pages.dev` URL that serves the site.\n References:\n + Cloudflare Pages Hugo Framework Guide\n\nSYSTEST: [BP_CFP_TEST_0001] - Blog Platform → Cloudflare Pages Build Verification #BP_CFP_0001\n* Objective: Verify Cloudflare Pages builds and deploys successfully.\n* Setup: Link GitHub repository to Cloudflare Pages project.\n* Test Steps:\n - TS1: Push commit to main branch → Expect build triggers automatically\n - TS2: Monitor build logs → Expect Hugo build completes without errors\n - TS3: Verify build output → Expect `public/` directory generated\n - TS4: Access `\u003cproject\u003e.pages.dev` → Expect site accessible\n - TS5: Verify HUGO_VERSION in build → Expect version 0.139.0 or higher\n* Failure Cases:\n - FC1: Invalid Hugo config → Expect build fails with clear error\n - FC2: Missing theme → Expect build fails, previous deployment remains live\n* Performance:\n - Measure build duration → Expect under 2 minutes for initial build\n - Measure deployment time → Expect under 1 minute after build\n\nTECH_REQ: [BP_CFP_0002] - Blog Platform → Environment Variables #BP001\n* The following environment variables SHALL be configured in Cloudflare Pages:\n - `HUGO_VERSION`: `0.139.0` (or latest stable)\n - `HUGO_ENVIRONMENT`: `production` (for production builds)\n* Environment variables SHALL be set in Cloudflare Pages project settings.\n* No sensitive credentials SHALL be stored in environment variables for this project.\n* References:\n + Cloudflare Pages Environment Variables\n\nSYSTEST: [BP_CFP_TEST_0002] - Blog Platform → Environment Variable Verification #BP_CFP_0002\n* Objective: Verify environment variables are correctly applied.\n* Setup: Configure environment variables in Cloudflare Pages dashboard.\n* Test Steps:\n - TS1: Trigger build → Inspect build logs for HUGO_VERSION\n - TS2: Verify Hugo version in output → Expect matches configured version\n - TS3: Check production environment → Expect HUGO_ENVIRONMENT=production\n* Verification:\n - Build log SHALL show "Hugo v0.139.0" or configured version\n\nTECH_REQ: [BP_HUGO_0001] - Blog Platform → Hugo Base URL Configuration #BP001\n* Hugo configuration SHALL set `baseURL` to `https://52vibes.dev/`.\n* Hugo configuration file SHALL be `hugo.toml` (TOML format preferred).\n* The blog section SHALL be configured to serve content from `/blog/` path.\n* Configuration SHALL include:\n - `languageCode`: `en-us`\n - `title`: `52 Vibes`\n - `enableRobotsTXT`: `true`\n - `enableGitInfo`: `true` (for lastmod dates)\n* References:\n + Hugo Configuration\n\nSYSTEST: [BP_HUGO_TEST_0001] - Blog Platform → Base URL and Path Verification #BP_HUGO_0001\n* Objective: Verify Hugo generates correct URLs and paths.\n* Setup: Build site locally with `hugo –minify`.\n* Test Steps:\n - TS1: Inspect generated HTML → Expect all URLs use `https://52vibes.dev/`\n - TS2: Verify blog index path → Expect accessible at `/blog/`\n - TS3: Check canonical URLs → Expect `\u003clink rel="canonical"\u003e` uses correct base\n - TS4: Verify internal links → Expect no broken internal links\n - TS5: Check sitemap.xml → Expect all URLs use production base URL\n* Local vs Production:\n - Local development MAY use `localhost:1313`\n - Production build MUST use `https://52vibes.dev/`\n\nTECH_REQ: [BP_SSL_0001] - Blog Platform → HTTPS and SSL Configuration #BP001\n* All traffic SHALL be served over HTTPS.\n* HTTP requests SHALL redirect to HTTPS (301 permanent redirect).\n* SSL certificate SHALL be automatically provisioned by Cloudflare.\n* SSL mode SHALL be set to "Full (strict)" in Cloudflare settings.\n* HSTS (HTTP Strict Transport Security) SHOULD be enabled.\n* References:\n + Cloudflare SSL/TLS\n\nSYSTEST: [BP_SSL_TEST_0001] - Blog Platform → HTTPS and Certificate Verification #BP_SSL_0001\n* Objective: Verify SSL/TLS is correctly configured.\n* Test Steps:\n - TS1: Request `http://52vibes.dev/blog` → Expect 301 redirect to HTTPS\n - TS2: Request `https://52vibes.dev/blog` → Expect HTTP 200\n - TS3: Inspect certificate → Expect valid, issued by Cloudflare\n - TS4: Check certificate expiry → Expect auto-renewal configured\n - TS5: Test with SSL Labs → Expect A or A+ rating\n* Security Headers:\n - Verify HSTS header present (if enabled)\n - Check for secure cookies (if any)\n* References:\n + SSL Labs Server Test\n\n### Core Architecture (BP002, BP003, BP004)\n\nTECH_REQ: [BP_SSR_0001] - Blog Platform → Server-Side Rendering Architecture #BP002\n* All page content SHALL be rendered at build time by Hugo (Static Site Generation).\n* HTML output SHALL contain complete content without requiring JavaScript hydration.\n* No client-side templating frameworks (React, Vue, etc.) SHALL be used.\n* Hugo templates SHALL use Go template syntax for content rendering.\n* Template directory structure SHALL follow Hugo conventions:\n - `layouts/_default/baseof.html` - base template\n - `layouts/_default/single.html` - single content pages\n - `layouts/_default/list.html` - list/index pages\n - `layouts/partials/` - reusable template components\n* References:\n + Hugo Templates\n\nSYSTEST: [BP_SSR_TEST_0001] - Blog Platform → Static Rendering Verification #BP_SSR_0001\n* Objective: Verify all content is statically rendered.\n* Test Steps:\n - TS1: Build site with `hugo –minify` → Inspect `public/` directory\n - TS2: Open any HTML file → Expect complete content in source\n - TS3: Disable JavaScript in browser → Load page → Expect all content visible\n - TS4: Use `curl` to fetch page → Expect complete HTML in response\n - TS5: Check for hydration scripts → Expect none present\n* Content Types:\n - Test blog post pages\n - Test index/list pages\n - Test static pages (About, etc.)\n\nTECH_REQ: [BP_NOJS_0001] - Blog Platform → JavaScript Budget and Constraints #BP002\n* Total JavaScript payload SHALL NOT exceed 2KB (minified, uncompressed).\n* JavaScript SHALL be used ONLY for:\n - Theme toggle persistence (localStorage) - ~500 bytes\n - Community page GitHub API fetch - ~1KB\n* No JavaScript frameworks or libraries SHALL be included.\n* All JavaScript SHALL be inline (no external JS files) or in a single bundled file.\n* JavaScript SHALL use vanilla ES6+ syntax (no transpilation required for modern browsers).\n* References:\n + JavaScript Module Best Practices\n\nSYSTEST: [BP_NOJS_TEST_0001] - Blog Platform → JavaScript Budget Verification #BP_NOJS_0001\n* Objective: Verify JavaScript stays within budget.\n* Test Steps:\n - TS1: Build production site → Locate all JavaScript in output\n - TS2: Measure total JS size → Expect ≤2KB minified\n - TS3: List all JS functionality → Expect only theme toggle + API fetch\n - TS4: Check for framework code → Expect none (React, Vue, jQuery, etc.)\n - TS5: Verify ES6+ syntax → Expect no transpilation artifacts\n* Tools:\n - Use browser DevTools Network tab\n - Use `wc -c` on minified JS files\n\nTECH_REQ: [BP_GRACE_0001] - Blog Platform → Graceful Degradation Strategy #BP002\n* When JavaScript is disabled:\n - Theme SHALL default to system preference via `prefers-color-scheme`\n - Theme toggle control SHALL remain visible but non-functional\n - Community page SHALL display fallback link to GitHub topics page\n* No "JavaScript required" messages SHALL be displayed.\n* No broken layouts or missing content SHALL occur without JavaScript.\n* All navigation SHALL remain fully functional without JavaScript.\n* References:\n + Progressive Enhancement\n\nSYSTEST: [BP_GRACE_TEST_0001] - Blog Platform → Graceful Degradation Verification #BP_GRACE_0001\n* Objective: Verify site functions correctly without JavaScript.\n* Setup: Disable JavaScript in browser settings.\n* Test Steps:\n - TS1: Load blog index → Expect all posts listed, readable\n - TS2: Navigate between pages → Expect all links work\n - TS3: Check theme → Expect matches system preference\n - TS4: View theme toggle → Expect visible (may be non-functional)\n - TS5: Load Community page → Expect fallback content/link displayed\n - TS6: Check for error messages → Expect none\n* Browsers:\n - Test in Chrome, Firefox with JS disabled\n - Test in lynx (inherently no JS)\n\nTECH_REQ: [BP_RESP_0001] - Blog Platform → Responsive Breakpoint System #BP003\n* CSS SHALL implement the following breakpoint system:\n - Mobile: `max-width: 767px`\n - Tablet: `min-width: 768px` and `max-width: 1023px`\n - Desktop: `min-width: 1024px`\n - Large Desktop: `min-width: 1440px` (optional enhancement)\n* Breakpoints SHALL be defined as CSS custom properties or SCSS variables.\n* Mobile-first approach SHALL be used (base styles for mobile, media queries for larger).\n* No horizontal scrolling SHALL occur at any viewport width ≥320px.\n* References:\n + CSS Media Queries\n\nSYSTEST: [BP_RESP_TEST_0001] - Blog Platform → Breakpoint Behavior Verification #BP_RESP_0001\n* Objective: Verify responsive behavior at all breakpoints.\n* Test Steps:\n - TS1: Set viewport to 320px width → Expect no horizontal scroll, content readable\n - TS2: Set viewport to 375px width → Expect mobile layout\n - TS3: Set viewport to 768px width → Expect tablet layout transition\n - TS4: Set viewport to 1024px width → Expect desktop layout\n - TS5: Set viewport to 1920px width → Expect full desktop layout\n - TS6: Resize viewport dynamically → Expect smooth transitions\n* Orientation:\n - Test mobile viewports in portrait and landscape\n* Content Types:\n - Test with long code blocks\n - Test with tables\n - Test with images\n\nTECH_REQ: [BP_RESP_0002] - Blog Platform → Fluid Typography and Spacing #BP003\n* Typography SHALL scale fluidly using CSS `clamp()` function.\n* Base font size range: `clamp(16px, 2.5vw, 18px)` for body text.\n* Heading sizes SHALL scale proportionally.\n* Spacing (margins, padding) SHALL use relative units (rem, em) or viewport units.\n* Line length SHALL be constrained to 65-75 characters for readability.\n* References:\n + CSS clamp()\n\nSYSTEST: [BP_RESP_TEST_0002] - Blog Platform → Typography Scaling Verification #BP_RESP_0002\n* Objective: Verify typography scales appropriately.\n* Test Steps:\n - TS1: Inspect body font size at 320px viewport → Expect ~16px\n - TS2: Inspect body font size at 1920px viewport → Expect ~18px\n - TS3: Measure line length in characters → Expect 65-75 characters max\n - TS4: Check heading hierarchy → Expect proportional scaling\n - TS5: Verify relative units in CSS → Expect rem/em usage\n* Readability:\n - Verify text is readable at all viewport sizes\n - Verify adequate spacing between elements\n\nTECH_REQ: [BP_PERF_0001] - Blog Platform → Asset Optimization Pipeline #BP004\n* Hugo asset pipeline SHALL be configured for optimization:\n - CSS: Minification enabled, unused CSS removal (if using SCSS)\n - HTML: Minification via `hugo –minify`\n - Images: WebP conversion with fallback, responsive srcset generation\n* Total page weight targets:\n - Blog index: ≤500KB\n - Blog post (without images): ≤300KB\n - Any page with images: ≤800KB\n* Asset fingerprinting SHALL be enabled for cache busting.\n* References:\n + Hugo Asset Minification\n + Hugo Image Processing\n\nSYSTEST: [BP_PERF_TEST_0001] - Blog Platform → Asset Optimization Verification #BP_PERF_0001\n* Objective: Verify assets are properly optimized.\n* Test Steps:\n - TS1: Build with `hugo –minify` → Verify minification applied\n - TS2: Inspect CSS output → Expect minified (no whitespace/comments)\n - TS3: Inspect HTML output → Expect minified\n - TS4: Check image formats → Expect WebP with fallbacks\n - TS5: Measure page weights → Verify within budget\n - TS6: Check asset URLs → Expect fingerprinted filenames\n* Tools:\n - Use browser DevTools Network tab for size measurements\n - Use `du -h` on output files\n\nTECH_REQ: [BP_PERF_0002] - Blog Platform → Core Web Vitals Optimization #BP004\n* Largest Contentful Paint (LCP) SHALL be under 2.5 seconds.\n* First Input Delay (FID) SHALL be under 100ms.\n* Cumulative Layout Shift (CLS) SHALL be under 0.1.\n* First Contentful Paint (FCP) SHOULD be under 1.5 seconds.\n* Implementation strategies:\n - Preload critical fonts\n - Inline critical CSS\n - Defer non-critical resources\n - Reserve space for dynamic content (prevent layout shifts)\n* References:\n + Core Web Vitals\n\nSYSTEST: [BP_PERF_TEST_0002] - Blog Platform → Core Web Vitals Measurement #BP_PERF_0002\n* Objective: Verify Core Web Vitals meet targets.\n* Test Steps:\n - TS1: Run Lighthouse on blog index → Expect Performance ≥95\n - TS2: Measure LCP → Expect \u003c2.5s\n - TS3: Measure FID → Expect \u003c100ms\n - TS4: Measure CLS → Expect \u003c0.1\n - TS5: Measure FCP → Expect \u003c1.5s\n - TS6: Run on multiple page types → Expect consistent scores\n* Testing Conditions:\n - Test with throttled connection (Slow 4G)\n - Test with CPU throttling (4x slowdown)\n* Tools:\n - Chrome DevTools Lighthouse\n - WebPageTest.org\n - PageSpeed Insights\n\nTECH_REQ: [BP_PERF_0003] - Blog Platform → Font Loading Strategy #BP004\n* Fonts SHALL be loaded from Google Fonts CDN.\n* Font loading SHALL use `font-display: swap` to prevent invisible text.\n* Font preconnect hints SHALL be included in `\u003chead\u003e`:\n - `\u003clink rel="preconnect" href="https://fonts.googleapis.com"\u003e`\n - `\u003clink rel="preconnect" href="https://fonts.gstatic.com" crossorigin\u003e`\n* Font families to load:\n - IBM Plex Sans: weights 400, 500, 600, 700\n - JetBrains Mono: weight 400\n* Font subsetting SHOULD be applied (latin subset only for initial load).\n* References:\n + Google Fonts CSS API\n + font-display\n\nSYSTEST: [BP_PERF_TEST_0003] - Blog Platform → Font Loading Verification #BP_PERF_0003\n* Objective: Verify fonts load efficiently without blocking render.\n* Test Steps:\n - TS1: Inspect `\u003chead\u003e` → Expect preconnect hints for Google Fonts\n - TS2: Check font-display → Expect `swap` in font declarations\n - TS3: Block Google Fonts → Expect fallback fonts display immediately\n - TS4: Measure font load time → Expect \u003c500ms on fast connection\n - TS5: Check for FOIT (Flash of Invisible Text) → Expect none\n - TS6: Check for FOUT (Flash of Unstyled Text) → Acceptable with swap\n* Network Tab:\n - Verify font files loaded from fonts.gstatic.com\n - Verify only required weights loaded\n\nTECH_REQ: [BP_DEPLOY_0001] - Blog Platform → Deployment Time Constraints #BP005\n* Content-only changes SHALL deploy within 5 minutes of push to main branch.\n* Full site rebuilds SHALL complete within 10 minutes.\n* Cloudflare Pages build SHALL NOT require manual intervention.\n* Build failures SHALL NOT affect live production site (atomic deployments).\n* Deployment notifications SHOULD be available via Cloudflare dashboard.\n* References:\n + Cloudflare Pages Deployments\n\nSYSTEST: [BP_DEPLOY_TEST_0001] - Blog Platform → Deployment Time Verification #BP_DEPLOY_0001\n* Objective: Verify deployment completes within time constraints.\n* Test Steps:\n - TS1: Push content-only change (markdown file) → Start timer\n - TS2: Monitor Cloudflare Pages deployment → Record completion time\n - TS3: Verify deployed content → Expect change visible\n - TS4: Calculate total time → Expect ≤5 minutes\n* Failure Recovery:\n - Push invalid change → Verify build fails\n - Verify live site unchanged → Previous version still served\n* Metrics:\n - Document average build times over 10 deployments\n\n### CLI Browser Compatibility (BP006)\n\nTECH_REQ: [BP_CLI_0001] - Blog Platform → Semantic HTML for CLI Rendering #BP006\n* HTML structure SHALL prioritize semantic elements that render well in text browsers.\n* Required semantic elements:\n - `\u003cheader\u003e` for site header\n - `\u003cnav\u003e` for navigation with `\u003cul\u003e` list structure\n - `\u003cmain\u003e` for primary content\n - `\u003carticle\u003e` for blog posts\n - `\u003csection\u003e` for content sections with headings\n - `\u003cfooter\u003e` for site footer\n* Links SHALL use descriptive text (no "click here").\n* Images SHALL include meaningful `alt` text for text-only display.\n* References:\n + HTML Semantic Elements\n\nSYSTEST: [BP_CLI_TEST_0001] - Blog Platform → Lynx Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in lynx browser.\n* Setup: Install lynx text browser.\n* Test Steps:\n - TS1: `lynx https://52vibes.dev/blog` → Expect page loads, title visible\n - TS2: Navigate to blog post → Expect content fully readable\n - TS3: Follow navigation links → Expect all work correctly\n - TS4: Check TOC anchor links → Expect navigate to sections\n - TS5: View post with code blocks → Expect code readable\n - TS6: Check for broken elements → Expect none\n* Content Verification:\n - Verify all text content visible\n - Verify links clearly labeled\n - Verify image alt text displayed\n\nSYSTEST: [BP_CLI_TEST_0002] - Blog Platform → w3m Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in w3m browser.\n* Setup: Install w3m text browser.\n* Test Steps:\n - TS1: `w3m https://52vibes.dev/blog` → Expect page loads\n - TS2: Navigate to Weekly Index → Expect table renders readably\n - TS3: Verify table alignment → Expect columns aligned\n - TS4: Follow navigation links → Expect all work correctly\n - TS5: Test forms (if any) → Expect usable\n* Table Testing:\n - Weekly Index table with 52 weeks → Must be readable\n - Tables in blog posts → Must render with structure\n\nTECH_REQ: [BP_CLI_0002] - Blog Platform → Table Rendering Strategy #BP006\n* Tables SHALL use standard HTML `\u003ctable\u003e` elements with proper structure.\n* Required table elements:\n - `\u003cthead\u003e` with `\u003cth\u003e` headers for accessibility\n - `\u003ctbody\u003e` for data rows\n - `scope` attributes on header cells\n* Tables SHALL NOT use CSS grid/flexbox to simulate tables.\n* Complex tables SHOULD include `\u003ccaption\u003e` for context.\n* Very wide tables MAY use horizontal scroll container on mobile (CSS only).\n* For CLI browsers, tables SHALL degrade to readable text columns.\n* References:\n + HTML Table Accessibility\n\nSYSTEST: [BP_CLI_TEST_0003] - Blog Platform → Table Accessibility Verification #BP_CLI_0002\n* Objective: Verify tables are accessible and CLI-friendly.\n* Test Steps:\n - TS1: Inspect Weekly Index table HTML → Expect `\u003cthead\u003e`, `\u003ctbody\u003e`, `\u003cth\u003e`\n - TS2: Check `scope` attributes → Expect on header cells\n - TS3: Test in screen reader → Expect headers announced\n - TS4: Test in w3m → Expect table structure preserved\n - TS5: Test in lynx → Expect readable (may linearize)\n* Mobile:\n - Test table at 320px viewport → Verify readable without breaking layout\n\n### Visual Design System (BP007, BP008, BP009, BP010, BP011)\n\nTECH_REQ: [BP_TMUX_0001] - Blog Platform → Tmux-Inspired Layout Structure #BP007\n* Page layout SHALL implement a tmux-inspired terminal aesthetic:\n - Top status bar: Fixed height, full width, contains week numbers\n - Main content pane: Bordered frame containing page content\n - Bottom navigation bar: Fixed height, full width, contains nav links\n* CSS borders SHALL create the framed appearance (no ASCII characters).\n* Border style SHALL be `solid 1px` using theme colors.\n* Content pane SHOULD have subtle inner padding (1-2rem).\n* Layout SHALL remain consistent across all page types.\n* References:\n + tmux Manual (for aesthetic reference)\n\nSYSTEST: [BP_TMUX_TEST_0001] - Blog Platform → Tmux Layout Verification #BP_TMUX_0001\n* Objective: Verify tmux-inspired visual design.\n* Test Steps:\n - TS1: Load any page → Verify top status bar present\n - TS2: Verify main content area → Expect bordered frame\n - TS3: Verify bottom navigation → Expect navigation bar present\n - TS4: Compare to tmux screenshot → Expect similar aesthetic\n - TS5: Test multiple pages → Expect consistent layout\n* Visual Elements:\n - Status bar contains week numbers (clickable for completed weeks)\n - Main pane has visible border\n - Navigation bar at bottom with links\n\nTECH_REQ: [BP_GRUVBOX_0001] - Blog Platform → Gruvbox Color Palette Implementation #BP008\n* Color system SHALL be based on Gruvbox color palette.\n* CSS custom properties SHALL define all colors:\n ```css\n /* Dark theme /\n –bg-dark: #1d2021;\n –bg-dark-soft: #282828;\n –fg-dark: #ebdbb2;\n –accent: #d65d0e;\n –green: #b8bb26;\n –red: #fb4934;\n –yellow: #fabd2f;\n –blue: #83a598;\n \n / Light theme /\n –bg-light: #fbf1c7;\n –bg-light-soft: #f2e5bc;\n –fg-light: #3c3836;\n ```\n All UI elements SHALL use these CSS custom properties (no hardcoded colors).\n* Accent color (#d65d0e orange) SHALL be used for interactive elements.\n* References:\n + Gruvbox GitHub\n\nSYSTEST: [BP_GRUVBOX_TEST_0001] - Blog Platform → Color Palette Verification #BP_GRUVBOX_0001\n* Objective: Verify Gruvbox colors are correctly implemented.\n* Test Steps:\n - TS1: Inspect CSS → Expect custom properties defined\n - TS2: Dark mode background → Sample color → Expect #1d2021 or similar\n - TS3: Light mode background → Sample color → Expect #fbf1c7 or similar\n - TS4: Dark mode text → Sample color → Expect #ebdbb2 or similar\n - TS5: Light mode text → Sample color → Expect #3c3836 or similar\n - TS6: Accent color (links, buttons) → Expect #d65d0e\n* Tools:\n - Use browser color picker DevTools\n - Verify CSS custom properties in computed styles\n\nTECH_REQ: [BP_THEME_0001] - Blog Platform → CSS Theme Switching Mechanism #BP008\n* Default theme SHALL be determined by `prefers-color-scheme` media query.\n* CSS SHALL use media query to apply theme-specific custom properties:\n ```css\n :root {\n /* Light theme defaults /\n }\n @media (prefers-color-scheme: dark) {\n :root {\n / Dark theme overrides /\n }\n }\n ```\n A `data-theme` attribute on `\u003chtml\u003e` element SHALL allow JavaScript override.\n* When `data-theme="dark"` or `data-theme="light"` is set, it SHALL override system preference.\n* Theme transition SHALL NOT cause layout shift (CLS).\n* References:\n + prefers-color-scheme\n\nSYSTEST: [BP_THEME_TEST_0001] - Blog Platform → Theme Switching Verification #BP_THEME_0001\n* Objective: Verify CSS theme switching works correctly.\n* Test Steps:\n - TS1: Set OS to dark mode → Load page → Expect dark theme\n - TS2: Set OS to light mode → Load page → Expect light theme\n - TS3: Set `data-theme="dark"` in DevTools → Expect dark theme override\n - TS4: Set `data-theme="light"` in DevTools → Expect light theme override\n - TS5: Toggle system preference → Expect theme updates (if no JS override)\n* No JavaScript:\n - Disable JS → Verify theme follows system preference\n\nTECH_REQ: [BP_TOGGLE_0001] - Blog Platform → Theme Toggle Implementation #BP009\n* A visible toggle control SHALL be placed in the page header or footer.\n* Toggle SHALL be implemented as a `\u003cbutton\u003e` element for accessibility.\n* Toggle SHALL have appropriate ARIA attributes:\n - `aria-label`: "Toggle dark/light theme"\n - `aria-pressed`: "true" or "false" based on state\n* Clicking toggle SHALL:\n 1. Set `data-theme` attribute on `\u003chtml\u003e`\n 2. Store preference in localStorage key `theme`\n 3. Update button visual state\n* JavaScript for toggle SHALL be under 500 bytes minified.\n* References:\n + ARIA button pattern\n\nSYSTEST: [BP_TOGGLE_TEST_0001] - Blog Platform → Theme Toggle Functionality #BP_TOGGLE_0001\n* Objective: Verify theme toggle works and persists preference.\n* Test Steps:\n - TS1: Locate toggle button → Expect visible in header/footer\n - TS2: Click toggle in dark mode → Expect switch to light\n - TS3: Click toggle in light mode → Expect switch to dark\n - TS4: Inspect localStorage → Expect `theme` key set\n - TS5: Refresh page → Expect preference persisted\n - TS6: Close browser, reopen → Expect preference persisted\n* Accessibility:\n - TS7: Inspect `aria-label` → Expect descriptive label\n - TS8: Tab to toggle → Expect focusable\n - TS9: Press Enter on focused toggle → Expect theme change\n - TS10: Check `aria-pressed` → Expect updates with state\n\nTECH_REQ: [BP_TOGGLE_0002] - Blog Platform → Theme Preference Persistence #BP009\n* Theme preference SHALL be stored in localStorage under key `theme`.\n* Valid values: `"dark"`, `"light"`, or absent (system preference).\n* On page load, JavaScript SHALL:\n 1. Check localStorage for `theme` value\n 2. If set, apply `data-theme` attribute\n 3. If not set, defer to CSS `prefers-color-scheme`\n* Theme restoration SHALL occur before first paint (inline script in `\u003chead\u003e`).\n* This prevents flash of wrong theme on page load.\n* References:\n + localStorage API\n\nSYSTEST: [BP_TOGGLE_TEST_0002] - Blog Platform → Theme Persistence Edge Cases #BP_TOGGLE_0002\n* Objective: Verify theme persistence handles edge cases.\n* Test Steps:\n - TS1: Clear localStorage → Load page → Expect system preference\n - TS2: Set theme → Load new page → Expect theme persists\n - TS3: Set theme → Hard refresh (Ctrl+Shift+R) → Expect theme persists\n - TS4: Set invalid localStorage value → Load page → Expect graceful fallback\n - TS5: localStorage unavailable → Load page → Expect system preference\n* Flash Prevention:\n - TS6: Set dark preference → Load page → Expect NO flash of light theme\n\nTECH_REQ: [BP_TYPO_0001] - Blog Platform → Typography System Implementation #BP010\n* Font family stack SHALL be defined in CSS custom properties:\n ```css\n –font-body: ‘IBM Plex Sans’, -apple-system, BlinkMacSystemFont, sans-serif;\n –font-mono: ‘JetBrains Mono’, ‘SF Mono’, ‘Menlo’, monospace;\n ```\n* Font sizes SHALL use a modular scale (ratio ~1.25):\n - `–font-size-sm`: 0.875rem (14px)\n - `–font-size-base`: 1rem (16px)\n - `–font-size-lg`: 1.125rem (18px)\n - `–font-size-xl`: 1.25rem (20px)\n - `–font-size-2xl`: 1.5rem (24px)\n - `–font-size-3xl`: 2rem (32px)\n* Line height for body text SHALL be 1.6-1.7 for readability.\n* References:\n + Modular Scale\n\nSYSTEST: [BP_TYPO_TEST_0001] - Blog Platform → Typography Implementation Verification #BP_TYPO_0001\n* Objective: Verify correct fonts and sizes are applied.\n* Test Steps:\n - TS1: Inspect body text → Expect IBM Plex Sans\n - TS2: Inspect headings → Expect IBM Plex Sans\n - TS3: Inspect code blocks → Expect JetBrains Mono\n - TS4: Inspect inline code → Expect JetBrains Mono\n - TS5: Check body font size → Expect 16-18px\n - TS6: Check line height → Expect 1.6-1.7\n* Fallback:\n - Block Google Fonts → Expect system fonts render cleanly\n\nTECH_REQ: [BP_BORDER_0001] - Blog Platform → CSS Border System #BP011\n* All visual borders SHALL be implemented using CSS `border` properties.\n* ASCII box-drawing characters SHALL NOT be used for structural elements.\n* Border colors SHALL use CSS custom properties for theme compatibility.\n* Standard border definition:\n ```css\n –border-color: var(–fg-dark); /* or –fg-light /\n –border-width: 1px;\n –border-style: solid;\n ```\n Border radius SHALL be minimal or zero for terminal aesthetic.\n* References:\n + CSS Borders\n\nSYSTEST: [BP_BORDER_TEST_0001] - Blog Platform → Border Implementation Verification #BP_BORDER_0001\n* Objective: Verify CSS borders, not ASCII characters.\n* Test Steps:\n - TS1: Inspect page HTML source → Search for box-drawing Unicode (─│┌┐└┘)\n - TS2: Expect NOT found in structural elements\n - TS3: Inspect border elements via DevTools → Expect CSS border properties\n - TS4: Toggle theme → Expect borders visible in both themes\n - TS5: Test in CLI browser → Expect readable without borders\n* Unicode Check:\n - Search: U+2500-U+257F (Box Drawing block)\n - These MAY appear in content, but NOT for layout\n\n### Navigation System (BP012, BP013, BP014, BP015, BP016)\n\nTECH_REQ: [BP_NAV_0001] - Blog Platform → Week Status Bar Implementation #BP012\n* Top status bar SHALL display week numbers 1-52.\n* Week numbers SHALL be generated by Hugo template from content data.\n* Implementation SHALL use Hugo’s `.Site.Pages` to determine completed weeks.\n* Completed weeks SHALL render as `\u003ca\u003e` links to post URLs.\n* Incomplete weeks SHALL render as `\u003cspan\u003e` elements (not clickable).\n* Visual styling SHALL distinguish clickable vs non-clickable weeks.\n* Week numbers SHALL be displayed in a single horizontal row (with wrapping on mobile).\n* References:\n + Hugo Page Collections\n\nSYSTEST: [BP_NAV_TEST_0001] - Blog Platform → Week Status Bar Verification #BP_NAV_0001\n* Objective: Verify week status bar displays correctly.\n* Test Steps:\n - TS1: Load any page → Verify status bar at top\n - TS2: Count week numbers → Expect 52 visible\n - TS3: Identify completed weeks → Verify are `\u003ca\u003e` links\n - TS4: Identify incomplete weeks → Verify are NOT links\n - TS5: Click completed week → Expect navigates to post\n - TS6: Attempt click incomplete week → Expect no navigation\n* Visual:\n - Completed weeks: colored/underlined\n - Incomplete weeks: muted/no interaction indicator\n\nTECH_REQ: [BP_NAV_0002] - Blog Platform → Week Tooltip Implementation #BP013\n* Week number links SHALL include `title` attribute with post title.\n* Tooltip SHALL use native browser tooltip (no JavaScript).\n* Hugo template SHALL populate title from front matter.\n* Example: `\u003ca href="/blog/week-01-infrastructure/" title="Week 1: Infrastructure"\u003e1\u003c/a\u003e`\n* Incomplete weeks SHALL NOT have tooltips.\n* References:\n + HTML title attribute\n\nSYSTEST: [BP_NAV_TEST_0002] - Blog Platform → Week Tooltip Verification #BP_NAV_0002\n* Objective: Verify native tooltips on week links.\n* Test Steps:\n - TS1: Hover over completed week number → Expect tooltip appears\n - TS2: Verify tooltip content → Expect post title displayed\n - TS3: Hover over incomplete week → Expect NO tooltip\n - TS4: Inspect HTML → Expect `title` attribute on completed week links\n - TS5: Verify no JavaScript tooltip → Expect native browser behavior\n* Timing:\n - Tooltip appears after browser default delay (~500-1000ms)\n\nTECH_REQ: [BP_NAV_0003] - Blog Platform → Weeks Index Link #BP014\n* Status bar SHALL include "Weeks" label/link.\n* Link SHALL navigate to `/blog/weeks/` (Weekly Index page).\n* Implementation SHALL be standard `\u003ca\u003e` element.\n* Link SHALL be accessible in CLI browsers.\n* Position SHALL be consistent (e.g., left side of status bar).\n* References:\n + Hugo Internal Links\n\nSYSTEST: [BP_NAV_TEST_0003] - Blog Platform → Weeks Index Link Verification #BP_NAV_0003\n* Objective: Verify "Weeks" link in status bar.\n* Test Steps:\n - TS1: Locate "Weeks" in status bar → Expect visible\n - TS2: Click "Weeks" → Expect navigates to `/blog/weeks/`\n - TS3: Inspect HTML → Expect `\u003ca\u003e` element\n - TS4: Test in lynx → Expect link accessible and functional\n\nTECH_REQ: [BP_NAV_0004] - Blog Platform → Footer Navigation Bar #BP015\n* Footer navigation bar SHALL be present on all pages.\n* Required links:\n - About: `/about/`\n - Weekly Index: `/blog/weeks/`\n - Reports: `/blog/reports/`\n - RSS: `/index.xml` or `/blog/index.xml`\n - GitHub: `https://github.com/\u003cowner\u003e/\u003crepo\u003e` (external)\n* Links SHALL be implemented as `\u003ca\u003e` elements within `\u003cnav\u003e` and `\u003cfooter\u003e`.\n* Link order SHALL be consistent across all pages.\n* Hugo partial template SHALL render footer navigation.\n* References:\n + Hugo Partials\n\nSYSTEST: [BP_NAV_TEST_0004] - Blog Platform → Footer Navigation Verification #BP_NAV_0004\n* Objective: Verify footer navigation completeness.\n* Test Steps:\n - TS1: Load blog index → Verify footer nav present\n - TS2: Verify About link → Expect navigates to `/about/`\n - TS3: Verify Weekly Index link → Expect navigates to `/blog/weeks/`\n - TS4: Verify Reports link → Expect navigates to `/blog/reports/`\n - TS5: Verify RSS link → Expect valid RSS feed\n - TS6: Verify GitHub link → Expect opens GitHub repository\n - TS7: Test on About page → Expect same footer nav\n - TS8: Test on blog post → Expect same footer nav\n* External Links:\n - GitHub link SHOULD open in new tab (optional `target="_blank"`)\n\nTECH_REQ: [BP_NAV_0005] - Blog Platform → Descriptive Navigation Labels #BP016\n* All navigation links SHALL use descriptive text labels.\n* Icons MAY accompany labels but SHALL NOT replace them.\n* Prohibited patterns:\n - "Click here"\n - "Read more"\n - Icon-only links\n - Single character links (except week numbers in status bar)\n* Week numbers in status bar SHALL have title attribute for context.\n* External links SHOULD indicate they open externally.\n* References:\n + WCAG Link Purpose\n\nSYSTEST: [BP_NAV_TEST_0005] - Blog Platform → Navigation Labels Verification #BP_NAV_0005\n* Objective: Verify all navigation uses descriptive text.\n* Test Steps:\n - TS1: Inspect all navigation elements → Expect text labels\n - TS2: Search for "click here" → Expect NOT found\n - TS3: Search for "read more" → Expect NOT found\n - TS4: Check icon-only elements → Expect none in navigation\n - TS5: Test in lynx → Expect navigation understandable\n - TS6: Run accessibility audit → Expect no "link purpose" violations\n\n### Table of Contents (BP017, BP018)\n\nTECH_REQ: [BP_TOC_0001] - Blog Platform → Auto-Generated TOC Implementation #BP017\n* Table of Contents SHALL be auto-generated from post headings.\n* Hugo’s `.TableOfContents` function SHALL be used.\n* TOC SHALL include h2 and h3 headings.\n* Configuration in `hugo.toml`:\n ```toml\n [markup.tableOfContents]\n startLevel = 2\n endLevel = 3\n ordered = false\n ```\n* TOC SHALL be rendered as nested `\u003cul\u003e` lists.\n* Each TOC item SHALL link to corresponding heading anchor.\n* References:\n + Hugo Table of Contents\n\nSYSTEST: [BP_TOC_TEST_0001] - Blog Platform → TOC Generation Verification #BP_TOC_0001\n* Objective: Verify TOC is correctly generated.\n* Test Steps:\n - TS1: Create post with h2 and h3 headings → Build site\n - TS2: Verify TOC appears at top of post → Expect `\u003cul\u003e` structure\n - TS3: Count TOC items → Expect matches heading count\n - TS4: Click TOC item → Expect scrolls to section\n - TS5: Verify URL hash → Expect `#heading-id` in URL\n - TS6: Test with nested headings (h3 under h2) → Expect nested list\n* Edge Cases:\n - Post with no headings → TOC section empty or hidden\n - Post with only h1 headings → TOC should be empty\n\nTECH_REQ: [BP_TOC_0002] - Blog Platform → Heading Anchor IDs #BP017\n* All h2 and h3 headings SHALL have auto-generated IDs.\n* Hugo SHALL generate IDs using the `anchorize` function.\n* IDs SHALL be URL-safe (lowercase, hyphenated).\n* Duplicate heading text SHALL result in unique IDs (suffix numbers).\n* Example: "Getting Started" → id="getting-started"\n* References:\n + Hugo Heading Anchors\n\nSYSTEST: [BP_TOC_TEST_0002] - Blog Platform → Heading Anchor Verification #BP_TOC_0002\n* Objective: Verify heading anchors are correctly generated.\n* Test Steps:\n - TS1: Inspect h2 element → Expect `id` attribute present\n - TS2: Verify ID format → Expect lowercase, hyphenated\n - TS3: Test duplicate headings → Expect unique IDs (suffix)\n - TS4: Navigate to `#heading-id` URL → Expect scrolls to heading\n - TS5: Test with special characters → Expect sanitized ID\n\nTECH_REQ: [BP_STICKY_0001] - Blog Platform → CSS Sticky Section Indicator #BP018\n* Section indicator SHOULD be implemented using CSS `position: sticky`.\n* Indicator SHALL display current section name during scroll.\n* Implementation SHALL NOT require JavaScript.\n* CSS scroll-snap or IntersectionObserver-free approach SHALL be used.\n* This is a SHOULD requirement; implementation is optional.\n* If implemented, format: "§ Reading: [Section Name]"\n* References:\n + CSS position: sticky\n\nSYSTEST: [BP_STICKY_TEST_0001] - Blog Platform → Sticky Section Indicator Verification #BP_STICKY_0001\n* Objective: Verify sticky section indicator (if implemented).\n* Test Steps (if implemented):\n - TS1: Navigate to long post (5+ sections) → Locate indicator\n - TS2: Scroll through sections → Expect indicator updates\n - TS3: Verify CSS position → Expect `sticky`\n - TS4: Disable JavaScript → Expect indicator still works\n - TS5: Verify format → Expect "§ Reading: [Section Name]"\n* Note: SHOULD requirement; document if not implemented\n\n### Content Pages (BP019, BP020, BP021, BP022, BP023)\n\nTECH_REQ: [BP_ABOUT_0001] - Blog Platform → About Page Implementation #BP019\n* About page SHALL be created at `content/about/_index.md`.\n* Page SHALL use Hugo `page` layout.\n* Required content sections:\n - Project description (52vibes purpose)\n - Author information\n - Contact/contribution information\n* URL SHALL be `/about/`.\n* Page SHALL use same layout/styling as blog pages.\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_ABOUT_TEST_0001] - Blog Platform → About Page Verification #BP_ABOUT_0001\n* Objective: Verify About page content and accessibility.\n* Test Steps:\n - TS1: Navigate to `/about/` → Expect HTTP 200\n - TS2: Verify project description → Expect meaningful content\n - TS3: Verify author information → Expect name/details\n - TS4: Verify layout matches blog → Expect consistent design\n - TS5: Test in CLI browser → Expect content readable\n* Content Quality:\n - Description explains 52vibes project\n - Author section has appropriate detail\n\nTECH_REQ: [BP_WEEKLY_0001] - Blog Platform → Weekly Index Page Implementation #BP020\n* Weekly Index page SHALL be created at `content/blog/weeks/_index.md`.\n* Page SHALL display table of all 52 weeks.\n* Table columns: Week #, Status, Title, Date Published.\n* Hugo template SHALL iterate `.Site.Pages` to build table.\n* Status values: Completed (linked), In Progress (labeled), Upcoming (muted).\n* Table SHALL use proper HTML table structure (`\u003ctable\u003e`, `\u003cthead\u003e`, `\u003ctbody\u003e`).\n* References:\n + Hugo Range\n\nSYSTEST: [BP_WEEKLY_TEST_0001] - Blog Platform → Weekly Index Verification #BP_WEEKLY_0001\n* Objective: Verify Weekly Index displays all 52 weeks.\n* Test Steps:\n - TS1: Navigate to `/blog/weeks/` → Expect page loads\n - TS2: Count table rows → Expect 52 weeks\n - TS3: Verify completed weeks → Expect linked with title\n - TS4: Verify upcoming weeks → Expect not linked, muted styling\n - TS5: Click completed week → Expect navigates to post\n - TS6: Test in w3m → Expect table renders readably\n* Dynamic Content:\n - Verify table updates when new weeks published\n\nTECH_REQ: [BP_REPORTS_0001] - Blog Platform → Reports Section Implementation #BP021\n* Reports section SHALL be at `content/blog/reports/_index.md`.\n* Hugo template SHALL list all report posts (monthly, quarterly).\n* Reports SHALL be tagged or categorized for filtering.\n* Empty state SHALL display friendly message.\n* Report listing SHALL include: title, type (monthly/quarterly), date.\n* References:\n + Hugo Taxonomies\n\nSYSTEST: [BP_REPORTS_TEST_0001] - Blog Platform → Reports Section Verification #BP_REPORTS_0001\n* Objective: Verify Reports section displays correctly.\n* Test Steps:\n - TS1: Navigate to `/blog/reports/` → Expect page loads\n - TS2: Verify report listings → When reports exist\n - TS3: Verify empty state → When no reports, friendly message\n - TS4: Click report → Expect navigates to full report\n - TS5: Verify type indicator → Monthly vs Quarterly distinguishable\n\nTECH_REQ: [BP_COMMUNITY_0001] - Blog Platform → Community Page Implementation #BP022\n* Community page SHALL be at `content/community/_index.md`.\n* Page SHALL contain:\n - Static introduction/description\n - Dynamic repository list (JavaScript-populated)\n - Fallback content when API unavailable\n* JavaScript SHALL fetch from GitHub Search API:\n - Endpoint: `https://api.github.com/search/repositories?q=topic:52vibes`\n* API fetch SHALL be deferred (non-blocking page load).\n* References:\n + GitHub Search API\n\nSYSTEST: [BP_COMMUNITY_TEST_0001] - Blog Platform → Community Page Verification #BP_COMMUNITY_0001\n* Objective: Verify Community page functionality.\n* Test Steps:\n - TS1: Navigate to `/community/` → Expect page loads\n - TS2: Wait for API response → Expect repos displayed (if any)\n - TS3: Verify loading indicator → During fetch\n - TS4: Block API (DevTools) → Expect fallback displayed\n - TS5: Disable JavaScript → Expect fallback link visible\n* API Integration:\n - Verify correct endpoint called\n - Verify topic filter applied\n\nTECH_REQ: [BP_BLOGIDX_0001] - Blog Platform → Blog Index Implementation #BP023\n* Blog index SHALL be at `content/blog/_index.md`.\n* Hugo list template SHALL display all published posts.\n* Each listing SHALL show: title, date, summary/description.\n* Posts SHALL be ordered by date (newest first).\n* Hugo configuration: `[params] mainSections = ["blog"]`.\n* Pagination SHOULD be implemented if posts exceed 10.\n* References:\n + Hugo List Templates\n\nSYSTEST: [BP_BLOGIDX_TEST_0001] - Blog Platform → Blog Index Verification #BP_BLOGIDX_0001\n* Objective: Verify blog index lists all posts.\n* Test Steps:\n - TS1: Navigate to `/blog/` → Expect page loads\n - TS2: Verify all published posts listed → Count matches\n - TS3: Verify each listing → Title, date, summary present\n - TS4: Verify ordering → Newest first\n - TS5: Click post title → Expect navigates to full post\n - TS6: Verify in CLI browser → List readable\n",“id”:“20260105125854”,“path”:"./notes/20260105125854/README.md",“project”:“52vibes”,“title”:“Week 1: Technical Requirements - Blog Platform (BP-TECH)”}`TOOL-CALL: mcp_note_update_note
{"new_content":" - TS6: Verify in CLI browser \u2192 List readable\n\n### URL Structure and Post Features (BP024, BP025, BP026, BP027, BP028, BP029, BP030)\n\nTECH_REQ: [BP_URL_0001] - Blog Platform \u2192 Weekly Post URL Pattern #BP024\n* Weekly posts SHALL use URL pattern:/blog/week-XX-/ \n* Week number SHALL be zero-padded (01-52).\n* Slug SHALL be derived from title (lowercase, hyphenated).\n* Hugo front matter SHALL define:\n ```yaml\n slug: \"week-01-infrastructure\"\n ```\n* A...TOOL:
{"message":"Updated note 20260105125854","success":true}AI: Continuing with accessibility (BP040-BP045), content authoring (BP046-BP049), and remaining requirements.
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125854","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n\n### Infrastructure \u0026 Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform → Cloudflare DNS Configuration #BP001\n* The domain \52vibes.dev` SHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point `52vibes.dev` to the Cloudflare Pages deployment URL (`\u003cproject\u003e.pages.dev`).\n* Cloudflare proxy (orange cloud) SHALL be enabled for CDN and SSL termination.\n* DNS propagation SHALL complete within 24 hours of configuration.\n* The `www` subdomain SHOULD redirect to the apex domain (`52vibes.dev`).\n* References:\n + Cloudflare Pages Custom Domains\n\nSYSTEST: [BP_DNS_TEST_0001] - Blog Platform → DNS Resolution Verification #BP_DNS_0001\n* Objective: Verify DNS resolves correctly to Cloudflare Pages.\n* Setup: Configure DNS records in Cloudflare dashboard.\n* Test Steps:\n - TS1: Run `dig 52vibes.dev` → Expect CNAME or A record pointing to Cloudflare\n - TS2: Run `dig www.52vibes.dev` → Expect redirect record configured\n - TS3: Query from multiple geographic locations → Expect consistent resolution\n - TS4: Verify Cloudflare proxy status → Expect orange cloud enabled in dashboard\n* Boundary Cases:\n - BC1: Test immediately after DNS change → Document propagation time\n - BC2: Test from different ISPs → Expect consistent results after propagation\n\nTECH_REQ: [BP_CFP_0001] - Blog Platform → Cloudflare Pages Project Configuration #BP001\n* A Cloudflare Pages project SHALL be created and linked to the GitHub repository.\n* Build configuration SHALL specify:\n - Build command: `hugo –minify`\n - Build output directory: `public`\n - Root directory: `/` (repository root)\n - Hugo version environment variable: `HUGO_VERSION=0.139.0`\n* Production branch SHALL be set to `main`.\n* Preview deployments SHALL be enabled for pull requests.\n* The project name SHALL result in a `.pages.dev` URL that serves the site.\n References:\n + Cloudflare Pages Hugo Framework Guide\n\nSYSTEST: [BP_CFP_TEST_0001] - Blog Platform → Cloudflare Pages Build Verification #BP_CFP_0001\n* Objective: Verify Cloudflare Pages builds and deploys successfully.\n* Setup: Link GitHub repository to Cloudflare Pages project.\n* Test Steps:\n - TS1: Push commit to main branch → Expect build triggers automatically\n - TS2: Monitor build logs → Expect Hugo build completes without errors\n - TS3: Verify build output → Expect `public/` directory generated\n - TS4: Access `\u003cproject\u003e.pages.dev` → Expect site accessible\n - TS5: Verify HUGO_VERSION in build → Expect version 0.139.0 or higher\n* Failure Cases:\n - FC1: Invalid Hugo config → Expect build fails with clear error\n - FC2: Missing theme → Expect build fails, previous deployment remains live\n* Performance:\n - Measure build duration → Expect under 2 minutes for initial build\n - Measure deployment time → Expect under 1 minute after build\n\nTECH_REQ: [BP_CFP_0002] - Blog Platform → Environment Variables #BP001\n* The following environment variables SHALL be configured in Cloudflare Pages:\n - `HUGO_VERSION`: `0.139.0` (or latest stable)\n - `HUGO_ENVIRONMENT`: `production` (for production builds)\n* Environment variables SHALL be set in Cloudflare Pages project settings.\n* No sensitive credentials SHALL be stored in environment variables for this project.\n* References:\n + Cloudflare Pages Environment Variables\n\nSYSTEST: [BP_CFP_TEST_0002] - Blog Platform → Environment Variable Verification #BP_CFP_0002\n* Objective: Verify environment variables are correctly applied.\n* Setup: Configure environment variables in Cloudflare Pages dashboard.\n* Test Steps:\n - TS1: Trigger build → Inspect build logs for HUGO_VERSION\n - TS2: Verify Hugo version in output → Expect matches configured version\n - TS3: Check production environment → Expect HUGO_ENVIRONMENT=production\n* Verification:\n - Build log SHALL show "Hugo v0.139.0" or configured version\n\nTECH_REQ: [BP_HUGO_0001] - Blog Platform → Hugo Base URL Configuration #BP001\n* Hugo configuration SHALL set `baseURL` to `https://52vibes.dev/`.\n* Hugo configuration file SHALL be `hugo.toml` (TOML format preferred).\n* The blog section SHALL be configured to serve content from `/blog/` path.\n* Configuration SHALL include:\n - `languageCode`: `en-us`\n - `title`: `52 Vibes`\n - `enableRobotsTXT`: `true`\n - `enableGitInfo`: `true` (for lastmod dates)\n* References:\n + Hugo Configuration\n\nSYSTEST: [BP_HUGO_TEST_0001] - Blog Platform → Base URL and Path Verification #BP_HUGO_0001\n* Objective: Verify Hugo generates correct URLs and paths.\n* Setup: Build site locally with `hugo –minify`.\n* Test Steps:\n - TS1: Inspect generated HTML → Expect all URLs use `https://52vibes.dev/`\n - TS2: Verify blog index path → Expect accessible at `/blog/`\n - TS3: Check canonical URLs → Expect `\u003clink rel="canonical"\u003e` uses correct base\n - TS4: Verify internal links → Expect no broken internal links\n - TS5: Check sitemap.xml → Expect all URLs use production base URL\n* Local vs Production:\n - Local development MAY use `localhost:1313`\n - Production build MUST use `https://52vibes.dev/`\n\nTECH_REQ: [BP_SSL_0001] - Blog Platform → HTTPS and SSL Configuration #BP001\n* All traffic SHALL be served over HTTPS.\n* HTTP requests SHALL redirect to HTTPS (301 permanent redirect).\n* SSL certificate SHALL be automatically provisioned by Cloudflare.\n* SSL mode SHALL be set to "Full (strict)" in Cloudflare settings.\n* HSTS (HTTP Strict Transport Security) SHOULD be enabled.\n* References:\n + Cloudflare SSL/TLS\n\nSYSTEST: [BP_SSL_TEST_0001] - Blog Platform → HTTPS and Certificate Verification #BP_SSL_0001\n* Objective: Verify SSL/TLS is correctly configured.\n* Test Steps:\n - TS1: Request `http://52vibes.dev/blog` → Expect 301 redirect to HTTPS\n - TS2: Request `https://52vibes.dev/blog` → Expect HTTP 200\n - TS3: Inspect certificate → Expect valid, issued by Cloudflare\n - TS4: Check certificate expiry → Expect auto-renewal configured\n - TS5: Test with SSL Labs → Expect A or A+ rating\n* Security Headers:\n - Verify HSTS header present (if enabled)\n - Check for secure cookies (if any)\n* References:\n + SSL Labs Server Test\n\n### Core Architecture (BP002, BP003, BP004)\n\nTECH_REQ: [BP_SSR_0001] - Blog Platform → Server-Side Rendering Architecture #BP002\n* All page content SHALL be rendered at build time by Hugo (Static Site Generation).\n* HTML output SHALL contain complete content without requiring JavaScript hydration.\n* No client-side templating frameworks (React, Vue, etc.) SHALL be used.\n* Hugo templates SHALL use Go template syntax for content rendering.\n* Template directory structure SHALL follow Hugo conventions:\n - `layouts/_default/baseof.html` - base template\n - `layouts/_default/single.html` - single content pages\n - `layouts/_default/list.html` - list/index pages\n - `layouts/partials/` - reusable template components\n* References:\n + Hugo Templates\n\nSYSTEST: [BP_SSR_TEST_0001] - Blog Platform → Static Rendering Verification #BP_SSR_0001\n* Objective: Verify all content is statically rendered.\n* Test Steps:\n - TS1: Build site with `hugo –minify` → Inspect `public/` directory\n - TS2: Open any HTML file → Expect complete content in source\n - TS3: Disable JavaScript in browser → Load page → Expect all content visible\n - TS4: Use `curl` to fetch page → Expect complete HTML in response\n - TS5: Check for hydration scripts → Expect none present\n* Content Types:\n - Test blog post pages\n - Test index/list pages\n - Test static pages (About, etc.)\n\nTECH_REQ: [BP_NOJS_0001] - Blog Platform → JavaScript Budget and Constraints #BP002\n* Total JavaScript payload SHALL NOT exceed 2KB (minified, uncompressed).\n* JavaScript SHALL be used ONLY for:\n - Theme toggle persistence (localStorage) - ~500 bytes\n - Community page GitHub API fetch - ~1KB\n* No JavaScript frameworks or libraries SHALL be included.\n* All JavaScript SHALL be inline (no external JS files) or in a single bundled file.\n* JavaScript SHALL use vanilla ES6+ syntax (no transpilation required for modern browsers).\n* References:\n + JavaScript Module Best Practices\n\nSYSTEST: [BP_NOJS_TEST_0001] - Blog Platform → JavaScript Budget Verification #BP_NOJS_0001\n* Objective: Verify JavaScript stays within budget.\n* Test Steps:\n - TS1: Build production site → Locate all JavaScript in output\n - TS2: Measure total JS size → Expect ≤2KB minified\n - TS3: List all JS functionality → Expect only theme toggle + API fetch\n - TS4: Check for framework code → Expect none (React, Vue, jQuery, etc.)\n - TS5: Verify ES6+ syntax → Expect no transpilation artifacts\n* Tools:\n - Use browser DevTools Network tab\n - Use `wc -c` on minified JS files\n\nTECH_REQ: [BP_GRACE_0001] - Blog Platform → Graceful Degradation Strategy #BP002\n* When JavaScript is disabled:\n - Theme SHALL default to system preference via `prefers-color-scheme`\n - Theme toggle control SHALL remain visible but non-functional\n - Community page SHALL display fallback link to GitHub topics page\n* No "JavaScript required" messages SHALL be displayed.\n* No broken layouts or missing content SHALL occur without JavaScript.\n* All navigation SHALL remain fully functional without JavaScript.\n* References:\n + Progressive Enhancement\n\nSYSTEST: [BP_GRACE_TEST_0001] - Blog Platform → Graceful Degradation Verification #BP_GRACE_0001\n* Objective: Verify site functions correctly without JavaScript.\n* Setup: Disable JavaScript in browser settings.\n* Test Steps:\n - TS1: Load blog index → Expect all posts listed, readable\n - TS2: Navigate between pages → Expect all links work\n - TS3: Check theme → Expect matches system preference\n - TS4: View theme toggle → Expect visible (may be non-functional)\n - TS5: Load Community page → Expect fallback content/link displayed\n - TS6: Check for error messages → Expect none\n* Browsers:\n - Test in Chrome, Firefox with JS disabled\n - Test in lynx (inherently no JS)\n\nTECH_REQ: [BP_RESP_0001] - Blog Platform → Responsive Breakpoint System #BP003\n* CSS SHALL implement the following breakpoint system:\n - Mobile: `max-width: 767px`\n - Tablet: `min-width: 768px` and `max-width: 1023px`\n - Desktop: `min-width: 1024px`\n - Large Desktop: `min-width: 1440px` (optional enhancement)\n* Breakpoints SHALL be defined as CSS custom properties or SCSS variables.\n* Mobile-first approach SHALL be used (base styles for mobile, media queries for larger).\n* No horizontal scrolling SHALL occur at any viewport width ≥320px.\n* References:\n + CSS Media Queries\n\nSYSTEST: [BP_RESP_TEST_0001] - Blog Platform → Breakpoint Behavior Verification #BP_RESP_0001\n* Objective: Verify responsive behavior at all breakpoints.\n* Test Steps:\n - TS1: Set viewport to 320px width → Expect no horizontal scroll, content readable\n - TS2: Set viewport to 375px width → Expect mobile layout\n - TS3: Set viewport to 768px width → Expect tablet layout transition\n - TS4: Set viewport to 1024px width → Expect desktop layout\n - TS5: Set viewport to 1920px width → Expect full desktop layout\n - TS6: Resize viewport dynamically → Expect smooth transitions\n* Orientation:\n - Test mobile viewports in portrait and landscape\n* Content Types:\n - Test with long code blocks\n - Test with tables\n - Test with images\n\nTECH_REQ: [BP_RESP_0002] - Blog Platform → Fluid Typography and Spacing #BP003\n* Typography SHALL scale fluidly using CSS `clamp()` function.\n* Base font size range: `clamp(16px, 2.5vw, 18px)` for body text.\n* Heading sizes SHALL scale proportionally.\n* Spacing (margins, padding) SHALL use relative units (rem, em) or viewport units.\n* Line length SHALL be constrained to 65-75 characters for readability.\n* References:\n + CSS clamp()\n\nSYSTEST: [BP_RESP_TEST_0002] - Blog Platform → Typography Scaling Verification #BP_RESP_0002\n* Objective: Verify typography scales appropriately.\n* Test Steps:\n - TS1: Inspect body font size at 320px viewport → Expect ~16px\n - TS2: Inspect body font size at 1920px viewport → Expect ~18px\n - TS3: Measure line length in characters → Expect 65-75 characters max\n - TS4: Check heading hierarchy → Expect proportional scaling\n - TS5: Verify relative units in CSS → Expect rem/em usage\n* Readability:\n - Verify text is readable at all viewport sizes\n - Verify adequate spacing between elements\n\nTECH_REQ: [BP_PERF_0001] - Blog Platform → Asset Optimization Pipeline #BP004\n* Hugo asset pipeline SHALL be configured for optimization:\n - CSS: Minification enabled, unused CSS removal (if using SCSS)\n - HTML: Minification via `hugo –minify`\n - Images: WebP conversion with fallback, responsive srcset generation\n* Total page weight targets:\n - Blog index: ≤500KB\n - Blog post (without images): ≤300KB\n - Any page with images: ≤800KB\n* Asset fingerprinting SHALL be enabled for cache busting.\n* References:\n + Hugo Asset Minification\n + Hugo Image Processing\n\nSYSTEST: [BP_PERF_TEST_0001] - Blog Platform → Asset Optimization Verification #BP_PERF_0001\n* Objective: Verify assets are properly optimized.\n* Test Steps:\n - TS1: Build with `hugo –minify` → Verify minification applied\n - TS2: Inspect CSS output → Expect minified (no whitespace/comments)\n - TS3: Inspect HTML output → Expect minified\n - TS4: Check image formats → Expect WebP with fallbacks\n - TS5: Measure page weights → Verify within budget\n - TS6: Check asset URLs → Expect fingerprinted filenames\n* Tools:\n - Use browser DevTools Network tab for size measurements\n - Use `du -h` on output files\n\nTECH_REQ: [BP_PERF_0002] - Blog Platform → Core Web Vitals Optimization #BP004\n* Largest Contentful Paint (LCP) SHALL be under 2.5 seconds.\n* First Input Delay (FID) SHALL be under 100ms.\n* Cumulative Layout Shift (CLS) SHALL be under 0.1.\n* First Contentful Paint (FCP) SHOULD be under 1.5 seconds.\n* Implementation strategies:\n - Preload critical fonts\n - Inline critical CSS\n - Defer non-critical resources\n - Reserve space for dynamic content (prevent layout shifts)\n* References:\n + Core Web Vitals\n\nSYSTEST: [BP_PERF_TEST_0002] - Blog Platform → Core Web Vitals Measurement #BP_PERF_0002\n* Objective: Verify Core Web Vitals meet targets.\n* Test Steps:\n - TS1: Run Lighthouse on blog index → Expect Performance ≥95\n - TS2: Measure LCP → Expect \u003c2.5s\n - TS3: Measure FID → Expect \u003c100ms\n - TS4: Measure CLS → Expect \u003c0.1\n - TS5: Measure FCP → Expect \u003c1.5s\n - TS6: Run on multiple page types → Expect consistent scores\n* Testing Conditions:\n - Test with throttled connection (Slow 4G)\n - Test with CPU throttling (4x slowdown)\n* Tools:\n - Chrome DevTools Lighthouse\n - WebPageTest.org\n - PageSpeed Insights\n\nTECH_REQ: [BP_PERF_0003] - Blog Platform → Font Loading Strategy #BP004\n* Fonts SHALL be loaded from Google Fonts CDN.\n* Font loading SHALL use `font-display: swap` to prevent invisible text.\n* Font preconnect hints SHALL be included in `\u003chead\u003e`:\n - `\u003clink rel="preconnect" href="https://fonts.googleapis.com"\u003e`\n - `\u003clink rel="preconnect" href="https://fonts.gstatic.com" crossorigin\u003e`\n* Font families to load:\n - IBM Plex Sans: weights 400, 500, 600, 700\n - JetBrains Mono: weight 400\n* Font subsetting SHOULD be applied (latin subset only for initial load).\n* References:\n + Google Fonts CSS API\n + font-display\n\nSYSTEST: [BP_PERF_TEST_0003] - Blog Platform → Font Loading Verification #BP_PERF_0003\n* Objective: Verify fonts load efficiently without blocking render.\n* Test Steps:\n - TS1: Inspect `\u003chead\u003e` → Expect preconnect hints for Google Fonts\n - TS2: Check font-display → Expect `swap` in font declarations\n - TS3: Block Google Fonts → Expect fallback fonts display immediately\n - TS4: Measure font load time → Expect \u003c500ms on fast connection\n - TS5: Check for FOIT (Flash of Invisible Text) → Expect none\n - TS6: Check for FOUT (Flash of Unstyled Text) → Acceptable with swap\n* Network Tab:\n - Verify font files loaded from fonts.gstatic.com\n - Verify only required weights loaded\n\nTECH_REQ: [BP_DEPLOY_0001] - Blog Platform → Deployment Time Constraints #BP005\n* Content-only changes SHALL deploy within 5 minutes of push to main branch.\n* Full site rebuilds SHALL complete within 10 minutes.\n* Cloudflare Pages build SHALL NOT require manual intervention.\n* Build failures SHALL NOT affect live production site (atomic deployments).\n* Deployment notifications SHOULD be available via Cloudflare dashboard.\n* References:\n + Cloudflare Pages Deployments\n\nSYSTEST: [BP_DEPLOY_TEST_0001] - Blog Platform → Deployment Time Verification #BP_DEPLOY_0001\n* Objective: Verify deployment completes within time constraints.\n* Test Steps:\n - TS1: Push content-only change (markdown file) → Start timer\n - TS2: Monitor Cloudflare Pages deployment → Record completion time\n - TS3: Verify deployed content → Expect change visible\n - TS4: Calculate total time → Expect ≤5 minutes\n* Failure Recovery:\n - Push invalid change → Verify build fails\n - Verify live site unchanged → Previous version still served\n* Metrics:\n - Document average build times over 10 deployments\n\n### CLI Browser Compatibility (BP006)\n\nTECH_REQ: [BP_CLI_0001] - Blog Platform → Semantic HTML for CLI Rendering #BP006\n* HTML structure SHALL prioritize semantic elements that render well in text browsers.\n* Required semantic elements:\n - `\u003cheader\u003e` for site header\n - `\u003cnav\u003e` for navigation with `\u003cul\u003e` list structure\n - `\u003cmain\u003e` for primary content\n - `\u003carticle\u003e` for blog posts\n - `\u003csection\u003e` for content sections with headings\n - `\u003cfooter\u003e` for site footer\n* Links SHALL use descriptive text (no "click here").\n* Images SHALL include meaningful `alt` text for text-only display.\n* References:\n + HTML Semantic Elements\n\nSYSTEST: [BP_CLI_TEST_0001] - Blog Platform → Lynx Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in lynx browser.\n* Setup: Install lynx text browser.\n* Test Steps:\n - TS1: `lynx https://52vibes.dev/blog` → Expect page loads, title visible\n - TS2: Navigate to blog post → Expect content fully readable\n - TS3: Follow navigation links → Expect all work correctly\n - TS4: Check TOC anchor links → Expect navigate to sections\n - TS5: View post with code blocks → Expect code readable\n - TS6: Check for broken elements → Expect none\n* Content Verification:\n - Verify all text content visible\n - Verify links clearly labeled\n - Verify image alt text displayed\n\nSYSTEST: [BP_CLI_TEST_0002] - Blog Platform → w3m Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in w3m browser.\n* Setup: Install w3m text browser.\n* Test Steps:\n - TS1: `w3m https://52vibes.dev/blog` → Expect page loads\n - TS2: Navigate to Weekly Index → Expect table renders readably\n - TS3: Verify table alignment → Expect columns aligned\n - TS4: Follow navigation links → Expect all work correctly\n - TS5: Test forms (if any) → Expect usable\n* Table Testing:\n - Weekly Index table with 52 weeks → Must be readable\n - Tables in blog posts → Must render with structure\n\nTECH_REQ: [BP_CLI_0002] - Blog Platform → Table Rendering Strategy #BP006\n* Tables SHALL use standard HTML `\u003ctable\u003e` elements with proper structure.\n* Required table elements:\n - `\u003cthead\u003e` with `\u003cth\u003e` headers for accessibility\n - `\u003ctbody\u003e` for data rows\n - `scope` attributes on header cells\n* Tables SHALL NOT use CSS grid/flexbox to simulate tables.\n* Complex tables SHOULD include `\u003ccaption\u003e` for context.\n* Very wide tables MAY use horizontal scroll container on mobile (CSS only).\n* For CLI browsers, tables SHALL degrade to readable text columns.\n* References:\n + HTML Table Accessibility\n\nSYSTEST: [BP_CLI_TEST_0003] - Blog Platform → Table Accessibility Verification #BP_CLI_0002\n* Objective: Verify tables are accessible and CLI-friendly.\n* Test Steps:\n - TS1: Inspect Weekly Index table HTML → Expect `\u003cthead\u003e`, `\u003ctbody\u003e`, `\u003cth\u003e`\n - TS2: Check `scope` attributes → Expect on header cells\n - TS3: Test in screen reader → Expect headers announced\n - TS4: Test in w3m → Expect table structure preserved\n - TS5: Test in lynx → Expect readable (may linearize)\n* Mobile:\n - Test table at 320px viewport → Verify readable without breaking layout\n\n### Visual Design System (BP007, BP008, BP009, BP010, BP011)\n\nTECH_REQ: [BP_TMUX_0001] - Blog Platform → Tmux-Inspired Layout Structure #BP007\n* Page layout SHALL implement a tmux-inspired terminal aesthetic:\n - Top status bar: Fixed height, full width, contains week numbers\n - Main content pane: Bordered frame containing page content\n - Bottom navigation bar: Fixed height, full width, contains nav links\n* CSS borders SHALL create the framed appearance (no ASCII characters).\n* Border style SHALL be `solid 1px` using theme colors.\n* Content pane SHOULD have subtle inner padding (1-2rem).\n* Layout SHALL remain consistent across all page types.\n* References:\n + tmux Manual (for aesthetic reference)\n\nSYSTEST: [BP_TMUX_TEST_0001] - Blog Platform → Tmux Layout Verification #BP_TMUX_0001\n* Objective: Verify tmux-inspired visual design.\n* Test Steps:\n - TS1: Load any page → Verify top status bar present\n - TS2: Verify main content area → Expect bordered frame\n - TS3: Verify bottom navigation → Expect navigation bar present\n - TS4: Compare to tmux screenshot → Expect similar aesthetic\n - TS5: Test multiple pages → Expect consistent layout\n* Visual Elements:\n - Status bar contains week numbers (clickable for completed weeks)\n - Main pane has visible border\n - Navigation bar at bottom with links\n\nTECH_REQ: [BP_GRUVBOX_0001] - Blog Platform → Gruvbox Color Palette Implementation #BP008\n* Color system SHALL be based on Gruvbox color palette.\n* CSS custom properties SHALL define all colors:\n ```css\n /* Dark theme /\n –bg-dark: #1d2021;\n –bg-dark-soft: #282828;\n –fg-dark: #ebdbb2;\n –accent: #d65d0e;\n –green: #b8bb26;\n –red: #fb4934;\n –yellow: #fabd2f;\n –blue: #83a598;\n \n / Light theme /\n –bg-light: #fbf1c7;\n –bg-light-soft: #f2e5bc;\n –fg-light: #3c3836;\n ```\n All UI elements SHALL use these CSS custom properties (no hardcoded colors).\n* Accent color (#d65d0e orange) SHALL be used for interactive elements.\n* References:\n + Gruvbox GitHub\n\nSYSTEST: [BP_GRUVBOX_TEST_0001] - Blog Platform → Color Palette Verification #BP_GRUVBOX_0001\n* Objective: Verify Gruvbox colors are correctly implemented.\n* Test Steps:\n - TS1: Inspect CSS → Expect custom properties defined\n - TS2: Dark mode background → Sample color → Expect #1d2021 or similar\n - TS3: Light mode background → Sample color → Expect #fbf1c7 or similar\n - TS4: Dark mode text → Sample color → Expect #ebdbb2 or similar\n - TS5: Light mode text → Sample color → Expect #3c3836 or similar\n - TS6: Accent color (links, buttons) → Expect #d65d0e\n* Tools:\n - Use browser color picker DevTools\n - Verify CSS custom properties in computed styles\n\nTECH_REQ: [BP_THEME_0001] - Blog Platform → CSS Theme Switching Mechanism #BP008\n* Default theme SHALL be determined by `prefers-color-scheme` media query.\n* CSS SHALL use media query to apply theme-specific custom properties:\n ```css\n :root {\n /* Light theme defaults /\n }\n @media (prefers-color-scheme: dark) {\n :root {\n / Dark theme overrides /\n }\n }\n ```\n A `data-theme` attribute on `\u003chtml\u003e` element SHALL allow JavaScript override.\n* When `data-theme="dark"` or `data-theme="light"` is set, it SHALL override system preference.\n* Theme transition SHALL NOT cause layout shift (CLS).\n* References:\n + prefers-color-scheme\n\nSYSTEST: [BP_THEME_TEST_0001] - Blog Platform → Theme Switching Verification #BP_THEME_0001\n* Objective: Verify CSS theme switching works correctly.\n* Test Steps:\n - TS1: Set OS to dark mode → Load page → Expect dark theme\n - TS2: Set OS to light mode → Load page → Expect light theme\n - TS3: Set `data-theme="dark"` in DevTools → Expect dark theme override\n - TS4: Set `data-theme="light"` in DevTools → Expect light theme override\n - TS5: Toggle system preference → Expect theme updates (if no JS override)\n* No JavaScript:\n - Disable JS → Verify theme follows system preference\n\nTECH_REQ: [BP_TOGGLE_0001] - Blog Platform → Theme Toggle Implementation #BP009\n* A visible toggle control SHALL be placed in the page header or footer.\n* Toggle SHALL be implemented as a `\u003cbutton\u003e` element for accessibility.\n* Toggle SHALL have appropriate ARIA attributes:\n - `aria-label`: "Toggle dark/light theme"\n - `aria-pressed`: "true" or "false" based on state\n* Clicking toggle SHALL:\n 1. Set `data-theme` attribute on `\u003chtml\u003e`\n 2. Store preference in localStorage key `theme`\n 3. Update button visual state\n* JavaScript for toggle SHALL be under 500 bytes minified.\n* References:\n + ARIA button pattern\n\nSYSTEST: [BP_TOGGLE_TEST_0001] - Blog Platform → Theme Toggle Functionality #BP_TOGGLE_0001\n* Objective: Verify theme toggle works and persists preference.\n* Test Steps:\n - TS1: Locate toggle button → Expect visible in header/footer\n - TS2: Click toggle in dark mode → Expect switch to light\n - TS3: Click toggle in light mode → Expect switch to dark\n - TS4: Inspect localStorage → Expect `theme` key set\n - TS5: Refresh page → Expect preference persisted\n - TS6: Close browser, reopen → Expect preference persisted\n* Accessibility:\n - TS7: Inspect `aria-label` → Expect descriptive label\n - TS8: Tab to toggle → Expect focusable\n - TS9: Press Enter on focused toggle → Expect theme change\n - TS10: Check `aria-pressed` → Expect updates with state\n\nTECH_REQ: [BP_TOGGLE_0002] - Blog Platform → Theme Preference Persistence #BP009\n* Theme preference SHALL be stored in localStorage under key `theme`.\n* Valid values: `"dark"`, `"light"`, or absent (system preference).\n* On page load, JavaScript SHALL:\n 1. Check localStorage for `theme` value\n 2. If set, apply `data-theme` attribute\n 3. If not set, defer to CSS `prefers-color-scheme`\n* Theme restoration SHALL occur before first paint (inline script in `\u003chead\u003e`).\n* This prevents flash of wrong theme on page load.\n* References:\n + localStorage API\n\nSYSTEST: [BP_TOGGLE_TEST_0002] - Blog Platform → Theme Persistence Edge Cases #BP_TOGGLE_0002\n* Objective: Verify theme persistence handles edge cases.\n* Test Steps:\n - TS1: Clear localStorage → Load page → Expect system preference\n - TS2: Set theme → Load new page → Expect theme persists\n - TS3: Set theme → Hard refresh (Ctrl+Shift+R) → Expect theme persists\n - TS4: Set invalid localStorage value → Load page → Expect graceful fallback\n - TS5: localStorage unavailable → Load page → Expect system preference\n* Flash Prevention:\n - TS6: Set dark preference → Load page → Expect NO flash of light theme\n\nTECH_REQ: [BP_TYPO_0001] - Blog Platform → Typography System Implementation #BP010\n* Font family stack SHALL be defined in CSS custom properties:\n ```css\n –font-body: ‘IBM Plex Sans’, -apple-system, BlinkMacSystemFont, sans-serif;\n –font-mono: ‘JetBrains Mono’, ‘SF Mono’, ‘Menlo’, monospace;\n ```\n* Font sizes SHALL use a modular scale (ratio ~1.25):\n - `–font-size-sm`: 0.875rem (14px)\n - `–font-size-base`: 1rem (16px)\n - `–font-size-lg`: 1.125rem (18px)\n - `–font-size-xl`: 1.25rem (20px)\n - `–font-size-2xl`: 1.5rem (24px)\n - `–font-size-3xl`: 2rem (32px)\n* Line height for body text SHALL be 1.6-1.7 for readability.\n* References:\n + Modular Scale\n\nSYSTEST: [BP_TYPO_TEST_0001] - Blog Platform → Typography Implementation Verification #BP_TYPO_0001\n* Objective: Verify correct fonts and sizes are applied.\n* Test Steps:\n - TS1: Inspect body text → Expect IBM Plex Sans\n - TS2: Inspect headings → Expect IBM Plex Sans\n - TS3: Inspect code blocks → Expect JetBrains Mono\n - TS4: Inspect inline code → Expect JetBrains Mono\n - TS5: Check body font size → Expect 16-18px\n - TS6: Check line height → Expect 1.6-1.7\n* Fallback:\n - Block Google Fonts → Expect system fonts render cleanly\n\nTECH_REQ: [BP_BORDER_0001] - Blog Platform → CSS Border System #BP011\n* All visual borders SHALL be implemented using CSS `border` properties.\n* ASCII box-drawing characters SHALL NOT be used for structural elements.\n* Border colors SHALL use CSS custom properties for theme compatibility.\n* Standard border definition:\n ```css\n –border-color: var(–fg-dark); /* or –fg-light /\n –border-width: 1px;\n –border-style: solid;\n ```\n Border radius SHALL be minimal or zero for terminal aesthetic.\n* References:\n + CSS Borders\n\nSYSTEST: [BP_BORDER_TEST_0001] - Blog Platform → Border Implementation Verification #BP_BORDER_0001\n* Objective: Verify CSS borders, not ASCII characters.\n* Test Steps:\n - TS1: Inspect page HTML source → Search for box-drawing Unicode (─│┌┐└┘)\n - TS2: Expect NOT found in structural elements\n - TS3: Inspect border elements via DevTools → Expect CSS border properties\n - TS4: Toggle theme → Expect borders visible in both themes\n - TS5: Test in CLI browser → Expect readable without borders\n* Unicode Check:\n - Search: U+2500-U+257F (Box Drawing block)\n - These MAY appear in content, but NOT for layout\n\n### Navigation System (BP012, BP013, BP014, BP015, BP016)\n\nTECH_REQ: [BP_NAV_0001] - Blog Platform → Week Status Bar Implementation #BP012\n* Top status bar SHALL display week numbers 1-52.\n* Week numbers SHALL be generated by Hugo template from content data.\n* Implementation SHALL use Hugo’s `.Site.Pages` to determine completed weeks.\n* Completed weeks SHALL render as `\u003ca\u003e` links to post URLs.\n* Incomplete weeks SHALL render as `\u003cspan\u003e` elements (not clickable).\n* Visual styling SHALL distinguish clickable vs non-clickable weeks.\n* Week numbers SHALL be displayed in a single horizontal row (with wrapping on mobile).\n* References:\n + Hugo Page Collections\n\nSYSTEST: [BP_NAV_TEST_0001] - Blog Platform → Week Status Bar Verification #BP_NAV_0001\n* Objective: Verify week status bar displays correctly.\n* Test Steps:\n - TS1: Load any page → Verify status bar at top\n - TS2: Count week numbers → Expect 52 visible\n - TS3: Identify completed weeks → Verify are `\u003ca\u003e` links\n - TS4: Identify incomplete weeks → Verify are NOT links\n - TS5: Click completed week → Expect navigates to post\n - TS6: Attempt click incomplete week → Expect no navigation\n* Visual:\n - Completed weeks: colored/underlined\n - Incomplete weeks: muted/no interaction indicator\n\nTECH_REQ: [BP_NAV_0002] - Blog Platform → Week Tooltip Implementation #BP013\n* Week number links SHALL include `title` attribute with post title.\n* Tooltip SHALL use native browser tooltip (no JavaScript).\n* Hugo template SHALL populate title from front matter.\n* Example: `\u003ca href="/blog/week-01-infrastructure/" title="Week 1: Infrastructure"\u003e1\u003c/a\u003e`\n* Incomplete weeks SHALL NOT have tooltips.\n* References:\n + HTML title attribute\n\nSYSTEST: [BP_NAV_TEST_0002] - Blog Platform → Week Tooltip Verification #BP_NAV_0002\n* Objective: Verify native tooltips on week links.\n* Test Steps:\n - TS1: Hover over completed week number → Expect tooltip appears\n - TS2: Verify tooltip content → Expect post title displayed\n - TS3: Hover over incomplete week → Expect NO tooltip\n - TS4: Inspect HTML → Expect `title` attribute on completed week links\n - TS5: Verify no JavaScript tooltip → Expect native browser behavior\n* Timing:\n - Tooltip appears after browser default delay (~500-1000ms)\n\nTECH_REQ: [BP_NAV_0003] - Blog Platform → Weeks Index Link #BP014\n* Status bar SHALL include "Weeks" label/link.\n* Link SHALL navigate to `/blog/weeks/` (Weekly Index page).\n* Implementation SHALL be standard `\u003ca\u003e` element.\n* Link SHALL be accessible in CLI browsers.\n* Position SHALL be consistent (e.g., left side of status bar).\n* References:\n + Hugo Internal Links\n\nSYSTEST: [BP_NAV_TEST_0003] - Blog Platform → Weeks Index Link Verification #BP_NAV_0003\n* Objective: Verify "Weeks" link in status bar.\n* Test Steps:\n - TS1: Locate "Weeks" in status bar → Expect visible\n - TS2: Click "Weeks" → Expect navigates to `/blog/weeks/`\n - TS3: Inspect HTML → Expect `\u003ca\u003e` element\n - TS4: Test in lynx → Expect link accessible and functional\n\nTECH_REQ: [BP_NAV_0004] - Blog Platform → Footer Navigation Bar #BP015\n* Footer navigation bar SHALL be present on all pages.\n* Required links:\n - About: `/about/`\n - Weekly Index: `/blog/weeks/`\n - Reports: `/blog/reports/`\n - RSS: `/index.xml` or `/blog/index.xml`\n - GitHub: `https://github.com/\u003cowner\u003e/\u003crepo\u003e` (external)\n* Links SHALL be implemented as `\u003ca\u003e` elements within `\u003cnav\u003e` and `\u003cfooter\u003e`.\n* Link order SHALL be consistent across all pages.\n* Hugo partial template SHALL render footer navigation.\n* References:\n + Hugo Partials\n\nSYSTEST: [BP_NAV_TEST_0004] - Blog Platform → Footer Navigation Verification #BP_NAV_0004\n* Objective: Verify footer navigation completeness.\n* Test Steps:\n - TS1: Load blog index → Verify footer nav present\n - TS2: Verify About link → Expect navigates to `/about/`\n - TS3: Verify Weekly Index link → Expect navigates to `/blog/weeks/`\n - TS4: Verify Reports link → Expect navigates to `/blog/reports/`\n - TS5: Verify RSS link → Expect valid RSS feed\n - TS6: Verify GitHub link → Expect opens GitHub repository\n - TS7: Test on About page → Expect same footer nav\n - TS8: Test on blog post → Expect same footer nav\n* External Links:\n - GitHub link SHOULD open in new tab (optional `target="_blank"`)\n\nTECH_REQ: [BP_NAV_0005] - Blog Platform → Descriptive Navigation Labels #BP016\n* All navigation links SHALL use descriptive text labels.\n* Icons MAY accompany labels but SHALL NOT replace them.\n* Prohibited patterns:\n - "Click here"\n - "Read more"\n - Icon-only links\n - Single character links (except week numbers in status bar)\n* Week numbers in status bar SHALL have title attribute for context.\n* External links SHOULD indicate they open externally.\n* References:\n + WCAG Link Purpose\n\nSYSTEST: [BP_NAV_TEST_0005] - Blog Platform → Navigation Labels Verification #BP_NAV_0005\n* Objective: Verify all navigation uses descriptive text.\n* Test Steps:\n - TS1: Inspect all navigation elements → Expect text labels\n - TS2: Search for "click here" → Expect NOT found\n - TS3: Search for "read more" → Expect NOT found\n - TS4: Check icon-only elements → Expect none in navigation\n - TS5: Test in lynx → Expect navigation understandable\n - TS6: Run accessibility audit → Expect no "link purpose" violations\n\n### Table of Contents (BP017, BP018)\n\nTECH_REQ: [BP_TOC_0001] - Blog Platform → Auto-Generated TOC Implementation #BP017\n* Table of Contents SHALL be auto-generated from post headings.\n* Hugo’s `.TableOfContents` function SHALL be used.\n* TOC SHALL include h2 and h3 headings.\n* Configuration in `hugo.toml`:\n ```toml\n [markup.tableOfContents]\n startLevel = 2\n endLevel = 3\n ordered = false\n ```\n* TOC SHALL be rendered as nested `\u003cul\u003e` lists.\n* Each TOC item SHALL link to corresponding heading anchor.\n* References:\n + Hugo Table of Contents\n\nSYSTEST: [BP_TOC_TEST_0001] - Blog Platform → TOC Generation Verification #BP_TOC_0001\n* Objective: Verify TOC is correctly generated.\n* Test Steps:\n - TS1: Create post with h2 and h3 headings → Build site\n - TS2: Verify TOC appears at top of post → Expect `\u003cul\u003e` structure\n - TS3: Count TOC items → Expect matches heading count\n - TS4: Click TOC item → Expect scrolls to section\n - TS5: Verify URL hash → Expect `#heading-id` in URL\n - TS6: Test with nested headings (h3 under h2) → Expect nested list\n* Edge Cases:\n - Post with no headings → TOC section empty or hidden\n - Post with only h1 headings → TOC should be empty\n\nTECH_REQ: [BP_TOC_0002] - Blog Platform → Heading Anchor IDs #BP017\n* All h2 and h3 headings SHALL have auto-generated IDs.\n* Hugo SHALL generate IDs using the `anchorize` function.\n* IDs SHALL be URL-safe (lowercase, hyphenated).\n* Duplicate heading text SHALL result in unique IDs (suffix numbers).\n* Example: "Getting Started" → id="getting-started"\n* References:\n + Hugo Heading Anchors\n\nSYSTEST: [BP_TOC_TEST_0002] - Blog Platform → Heading Anchor Verification #BP_TOC_0002\n* Objective: Verify heading anchors are correctly generated.\n* Test Steps:\n - TS1: Inspect h2 element → Expect `id` attribute present\n - TS2: Verify ID format → Expect lowercase, hyphenated\n - TS3: Test duplicate headings → Expect unique IDs (suffix)\n - TS4: Navigate to `#heading-id` URL → Expect scrolls to heading\n - TS5: Test with special characters → Expect sanitized ID\n\nTECH_REQ: [BP_STICKY_0001] - Blog Platform → CSS Sticky Section Indicator #BP018\n* Section indicator SHOULD be implemented using CSS `position: sticky`.\n* Indicator SHALL display current section name during scroll.\n* Implementation SHALL NOT require JavaScript.\n* CSS scroll-snap or IntersectionObserver-free approach SHALL be used.\n* This is a SHOULD requirement; implementation is optional.\n* If implemented, format: "§ Reading: [Section Name]"\n* References:\n + CSS position: sticky\n\nSYSTEST: [BP_STICKY_TEST_0001] - Blog Platform → Sticky Section Indicator Verification #BP_STICKY_0001\n* Objective: Verify sticky section indicator (if implemented).\n* Test Steps (if implemented):\n - TS1: Navigate to long post (5+ sections) → Locate indicator\n - TS2: Scroll through sections → Expect indicator updates\n - TS3: Verify CSS position → Expect `sticky`\n - TS4: Disable JavaScript → Expect indicator still works\n - TS5: Verify format → Expect "§ Reading: [Section Name]"\n* Note: SHOULD requirement; document if not implemented\n\n### Content Pages (BP019, BP020, BP021, BP022, BP023)\n\nTECH_REQ: [BP_ABOUT_0001] - Blog Platform → About Page Implementation #BP019\n* About page SHALL be created at `content/about/_index.md`.\n* Page SHALL use Hugo `page` layout.\n* Required content sections:\n - Project description (52vibes purpose)\n - Author information\n - Contact/contribution information\n* URL SHALL be `/about/`.\n* Page SHALL use same layout/styling as blog pages.\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_ABOUT_TEST_0001] - Blog Platform → About Page Verification #BP_ABOUT_0001\n* Objective: Verify About page content and accessibility.\n* Test Steps:\n - TS1: Navigate to `/about/` → Expect HTTP 200\n - TS2: Verify project description → Expect meaningful content\n - TS3: Verify author information → Expect name/details\n - TS4: Verify layout matches blog → Expect consistent design\n - TS5: Test in CLI browser → Expect content readable\n* Content Quality:\n - Description explains 52vibes project\n - Author section has appropriate detail\n\nTECH_REQ: [BP_WEEKLY_0001] - Blog Platform → Weekly Index Page Implementation #BP020\n* Weekly Index page SHALL be created at `content/blog/weeks/_index.md`.\n* Page SHALL display table of all 52 weeks.\n* Table columns: Week #, Status, Title, Date Published.\n* Hugo template SHALL iterate `.Site.Pages` to build table.\n* Status values: Completed (linked), In Progress (labeled), Upcoming (muted).\n* Table SHALL use proper HTML table structure (`\u003ctable\u003e`, `\u003cthead\u003e`, `\u003ctbody\u003e`).\n* References:\n + Hugo Range\n\nSYSTEST: [BP_WEEKLY_TEST_0001] - Blog Platform → Weekly Index Verification #BP_WEEKLY_0001\n* Objective: Verify Weekly Index displays all 52 weeks.\n* Test Steps:\n - TS1: Navigate to `/blog/weeks/` → Expect page loads\n - TS2: Count table rows → Expect 52 weeks\n - TS3: Verify completed weeks → Expect linked with title\n - TS4: Verify upcoming weeks → Expect not linked, muted styling\n - TS5: Click completed week → Expect navigates to post\n - TS6: Test in w3m → Expect table renders readably\n* Dynamic Content:\n - Verify table updates when new weeks published\n\nTECH_REQ: [BP_REPORTS_0001] - Blog Platform → Reports Section Implementation #BP021\n* Reports section SHALL be at `content/blog/reports/_index.md`.\n* Hugo template SHALL list all report posts (monthly, quarterly).\n* Reports SHALL be tagged or categorized for filtering.\n* Empty state SHALL display friendly message.\n* Report listing SHALL include: title, type (monthly/quarterly), date.\n* References:\n + Hugo Taxonomies\n\nSYSTEST: [BP_REPORTS_TEST_0001] - Blog Platform → Reports Section Verification #BP_REPORTS_0001\n* Objective: Verify Reports section displays correctly.\n* Test Steps:\n - TS1: Navigate to `/blog/reports/` → Expect page loads\n - TS2: Verify report listings → When reports exist\n - TS3: Verify empty state → When no reports, friendly message\n - TS4: Click report → Expect navigates to full report\n - TS5: Verify type indicator → Monthly vs Quarterly distinguishable\n\nTECH_REQ: [BP_COMMUNITY_0001] - Blog Platform → Community Page Implementation #BP022\n* Community page SHALL be at `content/community/_index.md`.\n* Page SHALL contain:\n - Static introduction/description\n - Dynamic repository list (JavaScript-populated)\n - Fallback content when API unavailable\n* JavaScript SHALL fetch from GitHub Search API:\n - Endpoint: `https://api.github.com/search/repositories?q=topic:52vibes`\n* API fetch SHALL be deferred (non-blocking page load).\n* References:\n + GitHub Search API\n\nSYSTEST: [BP_COMMUNITY_TEST_0001] - Blog Platform → Community Page Verification #BP_COMMUNITY_0001\n* Objective: Verify Community page functionality.\n* Test Steps:\n - TS1: Navigate to `/community/` → Expect page loads\n - TS2: Wait for API response → Expect repos displayed (if any)\n - TS3: Verify loading indicator → During fetch\n - TS4: Block API (DevTools) → Expect fallback displayed\n - TS5: Disable JavaScript → Expect fallback link visible\n* API Integration:\n - Verify correct endpoint called\n - Verify topic filter applied\n\nTECH_REQ: [BP_BLOGIDX_0001] - Blog Platform → Blog Index Implementation #BP023\n* Blog index SHALL be at `content/blog/_index.md`.\n* Hugo list template SHALL display all published posts.\n* Each listing SHALL show: title, date, summary/description.\n* Posts SHALL be ordered by date (newest first).\n* Hugo configuration: `[params] mainSections = ["blog"]`.\n* Pagination SHOULD be implemented if posts exceed 10.\n* References:\n + Hugo List Templates\n\nSYSTEST: [BP_BLOGIDX_TEST_0001] - Blog Platform → Blog Index Verification #BP_BLOGIDX_0001\n* Objective: Verify blog index lists all posts.\n* Test Steps:\n - TS1: Navigate to `/blog/` → Expect page loads\n - TS2: Verify all published posts listed → Count matches\n - TS3: Verify each listing → Title, date, summary present\n - TS4: Verify ordering → Newest first\n - TS5: Click post title → Expect navigates to full post\n - TS6: Verify in CLI browser → List readable\n\n### URL Structure and Post Features (BP024, BP025, BP026, BP027, BP028, BP029, BP030)\n\nTECH_REQ: [BP_URL_0001] - Blog Platform → Weekly Post URL Pattern #BP024\n* Weekly posts SHALL use URL pattern: `/blog/week-XX-\u003cslug\u003e/`\n* Week number SHALL be zero-padded (01-52).\n* Slug SHALL be derived from title (lowercase, hyphenated).\n* Hugo front matter SHALL define:\n ```yaml\n slug: "week-01-infrastructure"\n ```\n* Alternatively, file naming: `content/blog/week-01-infrastructure/index.md`\n* References:\n + Hugo URL Management\n\nSYSTEST: [BP_URL_TEST_0001] - Blog Platform → Weekly Post URL Verification #BP_URL_0001\n* Objective: Verify weekly post URLs follow pattern.\n* Test Steps:\n - TS1: Create week 1 post → Verify URL is `/blog/week-01-\u003cslug\u003e/`\n - TS2: Verify zero-padding → Week 1 = 01, Week 10 = 10\n - TS3: Verify slug format → Lowercase, hyphenated\n - TS4: Test URL directly → Expect HTTP 200\n* Boundary:\n - Week 01, Week 10, Week 52 formatting\n\nTECH_REQ: [BP_URL_0002] - Blog Platform → Monthly Report URL Pattern #BP025\n* Monthly reports SHALL use URL pattern: `/blog/reports/YYYY-MM/`\n* Year: 4 digits, Month: 2 digits (zero-padded).\n* Content location: `content/blog/reports/2026-01/index.md`\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_URL_TEST_0002] - Blog Platform → Monthly Report URL Verification #BP_URL_0002\n* Objective: Verify monthly report URLs follow pattern.\n* Test Steps:\n - TS1: Create January 2026 report → Verify URL `/blog/reports/2026-01/`\n - TS2: Verify date format → YYYY-MM\n - TS3: Test URL directly → Expect HTTP 200\n* Boundary:\n - January (01), December (12), year transitions\n\nTECH_REQ: [BP_URL_0003] - Blog Platform → Quarterly Report URL Pattern #BP026\n* Quarterly reports SHALL use URL pattern: `/blog/reports/YYYY-qN/`\n* Year: 4 digits, Quarter: lowercase ‘q’ + 1-4.\n* Content location: `content/blog/reports/2026-q1/index.md`\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_URL_TEST_0003] - Blog Platform → Quarterly Report URL Verification #BP_URL_0003\n* Objective: Verify quarterly report URLs follow pattern.\n* Test Steps:\n - TS1: Create Q1 2026 report → Verify URL `/blog/reports/2026-q1/`\n - TS2: Verify quarter format → Lowercase ‘q’ + 1-4\n - TS3: Test all quarters → q1, q2, q3, q4\n* Case Sensitivity:\n - Must be lowercase ‘q’, not ‘Q’\n\nTECH_REQ: [BP_META_0001] - Blog Platform → Post Metadata Display #BP027\n* Post template SHALL display metadata section at top.\n* Required metadata fields:\n - Title (from front matter `title`)\n - Publication date (from `date`, formatted human-readable)\n - Reading time (calculated via Hugo, e.g., `{{ .ReadingTime }} min read`)\n - Quarter/theme (from front matter `quarter` and `theme`)\n* Hugo template SHALL calculate reading time automatically.\n* Format example: "Q1: Agentic Infrastructure • 5 min read • January 5, 2026"\n* References:\n + Hugo Variables\n\nSYSTEST: [BP_META_TEST_0001] - Blog Platform → Post Metadata Verification #BP_META_0001\n* Objective: Verify post metadata is displayed correctly.\n* Test Steps:\n - TS1: Navigate to blog post → Expect metadata section visible\n - TS2: Verify title → Matches front matter\n - TS3: Verify date → Human-readable format\n - TS4: Verify reading time → Reasonable for content length\n - TS5: Verify quarter/theme → Matches front matter\n* Consistency:\n - Check multiple posts for consistent metadata display\n\nTECH_REQ: [BP_POSTNAV_0001] - Blog Platform → Previous/Next Navigation #BP028\n* Post template SHALL include prev/next navigation links.\n* Hugo template SHALL use `.PrevInSection` and `.NextInSection`.\n* Links SHALL only appear when adjacent posts exist:\n - No "Previous" on first post\n - No "Next" on latest post\n* Link text SHALL include week number and/or title.\n* Navigation SHALL be positioned at end of post content.\n* References:\n + Hugo Page Methods\n\nSYSTEST: [BP_POSTNAV_TEST_0001] - Blog Platform → Post Navigation Verification #BP_POSTNAV_0001\n* Objective: Verify prev/next navigation works correctly.\n* Test Steps:\n - TS1: Navigate to middle week → Expect both prev and next links\n - TS2: Click Previous → Expect navigates to prior week\n - TS3: Click Next → Expect navigates to following week\n - TS4: Navigate to Week 1 → Expect NO previous link\n - TS5: Navigate to latest week → Expect NO next link\n* Edge Cases:\n - Single published week → No navigation links\n\nTECH_REQ: [BP_SESSION_0001] - Blog Platform → Session Log Links #BP029\n* Post template SHALL include link to session log.\n* Link SHALL point to GitHub Wiki page for that week.\n* URL pattern: `https://github.com/\u003cowner\u003e/\u003crepo\u003e/wiki/Week-XX-Session-Log`\n* Link SHALL be labeled clearly (e.g., "View Session Log").\n* Link position: After post content, before comments section.\n* Hugo front matter MAY override default wiki URL.\n* References:\n + GitHub Wiki URLs\n\nSYSTEST: [BP_SESSION_TEST_0001] - Blog Platform → Session Log Link Verification #BP_SESSION_0001\n* Objective: Verify session log links are correct.\n* Test Steps:\n - TS1: Navigate to blog post → Expect session log link visible\n - TS2: Verify link label → Expect descriptive text\n - TS3: Click link → Expect opens correct wiki page\n - TS4: Verify wiki content → Expect relates to that week\n* Link Validation:\n - Verify HTTP 200 response from wiki URL\n\nTECH_REQ: [BP_REPO_0001] - Blog Platform → Repository Links #BP030\n* Post template SHALL include link to repository/code.\n* Link SHALL point to GitHub repository or specific directory.\n* URL pattern: `https://github.com/\u003cowner\u003e/\u003crepo\u003e` or subdirectory.\n* Hugo front matter `repo_url` SHALL allow custom repository links.\n* Link SHALL be labeled clearly (e.g., "View Code", "GitHub Repository").\n* References:\n + Hugo Front Matter\n\nSYSTEST: [BP_REPO_TEST_0001] - Blog Platform → Repository Link Verification #BP_REPO_0001\n* Objective: Verify repository links are correct.\n* Test Steps:\n - TS1: Navigate to blog post → Expect repo link visible\n - TS2: Verify link label → Expect descriptive text\n - TS3: Click link → Expect opens correct GitHub repo\n - TS4: Verify repo content → Expect relates to week’s project\n* Link Validation:\n - Verify HTTP 200 response from repo URL\n\n### SEO and Discovery (BP031, BP032, BP033, BP034, BP035, BP036, BP037)\n\nTECH_REQ: [BP_RSS_0001] - Blog Platform → RSS Feed Implementation #BP031\n* Hugo SHALL generate RSS feed automatically.\n* Feed SHALL be accessible at `/blog/index.xml`.\n* Configuration in `hugo.toml`:\n ```toml\n [outputs]\n home = ["HTML", "RSS"]\n section = ["HTML", "RSS"]\n ```\n* Feed SHALL include: title, link, description, pubDate for each item.\n* Feed SHALL validate against RSS 2.0 specification.\n* References:\n + Hugo RSS Templates\n\nSYSTEST: [BP_RSS_TEST_0001] - Blog Platform → RSS Feed Verification #BP_RSS_0001\n* Objective: Verify RSS feed is valid and complete.\n* Test Steps:\n - TS1: Navigate to `/blog/index.xml` → Expect valid XML\n - TS2: Validate with W3C Feed Validator → Expect no errors\n - TS3: Verify items → Expect all published posts included\n - TS4: Test in RSS reader → Expect feed parseable\n - TS5: Check item fields → title, link, description, pubDate present\n* References:\n + W3C Feed Validator\n\nTECH_REQ: [BP_SEO_0001] - Blog Platform → Basic Meta Tags #BP032\n* All pages SHALL include `\u003ctitle\u003e` and `\u003cmeta name="description"\u003e` tags.\n* Hugo template SHALL generate from front matter or defaults.\n* Title pattern: `\u003cPage Title\u003e | 52 Vibes`\n* Description: From front matter `description` or auto-generated summary.\n* Meta tags SHALL be in `\u003chead\u003e` section.\n* References:\n + Hugo SEO\n\nSYSTEST: [BP_SEO_TEST_0001] - Blog Platform → Basic Meta Tags Verification #BP_SEO_0001\n* Objective: Verify SEO meta tags on all pages.\n* Test Steps:\n - TS1: View page source → Expect `\u003ctitle\u003e` tag\n - TS2: Verify title format → Expect pattern `\u003cPage\u003e | 52 Vibes`\n - TS3: Check description meta → Expect relevant content\n - TS4: Test multiple page types → Expect consistent structure\n* Uniqueness:\n - Each page SHOULD have unique title and description\n\nTECH_REQ: [BP_OG_0001] - Blog Platform → Open Graph Meta Tags #BP033\n* All pages SHALL include Open Graph meta tags.\n* Required tags:\n - `og:title`: Page title\n - `og:description`: Page description\n - `og:image`: Social card image URL\n - `og:url`: Canonical page URL\n - `og:type`: "article" for posts, "website" for others\n* Hugo internal template MAY be used: `{{ template "_internal/opengraph.html" . }}`\n* References:\n + Open Graph Protocol\n\nSYSTEST: [BP_OG_TEST_0001] - Blog Platform → Open Graph Verification #BP_OG_0001\n* Objective: Verify Open Graph tags for social sharing.\n* Test Steps:\n - TS1: View page source → Expect `og:title` meta tag\n - TS2: Verify `og:description` → Expect content\n - TS3: Verify `og:image` → Expect valid URL\n - TS4: Verify `og:url` → Expect canonical URL\n - TS5: Verify `og:type` → "article" for posts\n - TS6: Test with Facebook Debugger → Expect preview renders\n* References:\n + Facebook Sharing Debugger\n\nTECH_REQ: [BP_TWITTER_0001] - Blog Platform → Twitter Card Meta Tags #BP034\n* All pages SHALL include Twitter Card meta tags.\n* Required tags:\n - `twitter:card`: "summary_large_image"\n - `twitter:title`: Page title\n - `twitter:description`: Page description\n - `twitter:image`: Social card image URL\n* Hugo internal template MAY be used: `{{ template "_internal/twitter_cards.html" . }}`\n* References:\n + Twitter Cards\n\nSYSTEST: [BP_TWITTER_TEST_0001] - Blog Platform → Twitter Card Verification #BP_TWITTER_0001\n* Objective: Verify Twitter Card tags.\n* Test Steps:\n - TS1: View page source → Expect `twitter:card` meta tag\n - TS2: Verify card type → "summary_large_image"\n - TS3: Verify `twitter:title` → Expect content\n - TS4: Verify `twitter:description` → Expect content\n - TS5: Verify `twitter:image` → Expect valid URL\n* Image:\n - Verify image dimensions meet Twitter requirements (min 300x157)\n\nTECH_REQ: [BP_SITEMAP_0001] - Blog Platform → XML Sitemap #BP035\n* Hugo SHALL generate sitemap automatically.\n* Sitemap SHALL be at `/sitemap.xml`.\n* Configuration in `hugo.toml`:\n ```toml\n [sitemap]\n changeFreq = "weekly"\n priority = 0.5\n ```\n* Sitemap SHALL include all public pages.\n* `\u003clastmod\u003e` dates SHALL be populated from Git info or front matter.\n* References:\n + Hugo Sitemap\n\nSYSTEST: [BP_SITEMAP_TEST_0001] - Blog Platform → Sitemap Verification #BP_SITEMAP_0001\n* Objective: Verify sitemap is valid and complete.\n* Test Steps:\n - TS1: Navigate to `/sitemap.xml` → Expect valid XML\n - TS2: Validate structure → Expect valid sitemap schema\n - TS3: Count URLs → Expect matches page count\n - TS4: Verify `\u003clastmod\u003e` → Expect dates present\n - TS5: Submit to validator → Expect no errors\n* References:\n + Sitemap Validator\n\nTECH_REQ: [BP_JSONLD_0001] - Blog Platform → JSON-LD Structured Data #BP036\n* Blog posts SHALL include JSON-LD structured data.\n* Schema type: `Article` (or `BlogPosting`).\n* Required fields:\n - `headline`: Post title\n - `datePublished`: ISO 8601 date\n - `dateModified`: ISO 8601 date\n - `author`: Author information\n - `publisher`: Site information\n* JSON-LD SHALL be in `\u003cscript type="application/ld+json"\u003e` tag.\n* References:\n + Schema.org Article\n + Google Structured Data\n\nSYSTEST: [BP_JSONLD_TEST_0001] - Blog Platform → JSON-LD Verification #BP_JSONLD_0001\n* Objective: Verify JSON-LD structured data.\n* Test Steps:\n - TS1: View page source → Expect `\u003cscript type="application/ld+json"\u003e`\n - TS2: Parse JSON → Expect valid JSON\n - TS3: Verify @type → Expect "Article" or "BlogPosting"\n - TS4: Verify headline → Expect post title\n - TS5: Verify datePublished → Expect ISO 8601 format\n - TS6: Test with Google Rich Results → Expect validation passes\n* References:\n + Google Rich Results Test\n\nTECH_REQ: [BP_SOCIAL_0001] - Blog Platform → Social Card Image Generation #BP037\n* Social card images SHALL be generated at build time using Hugo.\n* Hugo image processing SHALL create cards from template.\n* Image dimensions: 1200x630 pixels (recommended for social).\n* Card content: Week number, post title, quarter theme.\n* Card design: Gruvbox colors, consistent branding.\n* Output location: Same directory as post or `/images/cards/`.\n* References:\n + Hugo Image Processing\n\nSYSTEST: [BP_SOCIAL_TEST_0001] - Blog Platform → Social Card Image Verification #BP_SOCIAL_0001\n* Objective: Verify social card images are generated correctly.\n* Test Steps:\n - TS1: Build site → Check for card images in output\n - TS2: Verify dimensions → Expect ~1200x630\n - TS3: Verify content → Week number, title visible\n - TS4: Verify `og:image` points to card → Expect valid URL\n - TS5: Load image URL directly → Expect image displays\n* Visual:\n - Cards use Gruvbox colors\n - Text is readable\n\n### Engagement (BP038, BP039)\n\nTECH_REQ: [BP_DISCUSS_0001] - Blog Platform → GitHub Discussion Links #BP038\n* Post template SHALL include link to GitHub Discussions.\n* Link SHALL point to specific discussion thread for that post.\n* URL pattern: `https://github.com/\u003cowner\u003e/\u003crepo\u003e/discussions/\u003cid\u003e`\n* Hugo front matter `discussion_id` SHALL specify thread ID.\n* Link label: "Join Discussion" or "Comments on GitHub".\n* References:\n + GitHub Discussions\n\nSYSTEST: [BP_DISCUSS_TEST_0001] - Blog Platform → Discussion Link Verification #BP_DISCUSS_0001\n* Objective: Verify discussion links are correct.\n* Test Steps:\n - TS1: Navigate to blog post → Expect discussion link visible\n - TS2: Verify link label → Expect descriptive text\n - TS3: Click link → Expect opens specific discussion thread\n - TS4: Verify NOT generic discussions page → Expect specific thread\n\nTECH_REQ: [BP_DISCUSS_0002] - Blog Platform → Discussion Deep Linking #BP039\n* Discussion links SHALL navigate to specific threads, not index.\n* Each post SHALL have dedicated discussion thread.\n* Thread creation MAY be manual or automated via GitHub Actions.\n* Link URL SHALL include discussion ID or number.\n* References:\n + GitHub Discussions API\n\nSYSTEST: [BP_DISCUSS_TEST_0002] - Blog Platform → Deep Link Verification #BP_DISCUSS_0002\n* Objective: Verify discussion links go to specific threads.\n* Test Steps:\n - TS1: Click discussion link → Verify URL contains discussion ID\n - TS2: Verify page content → Expect discussion about that post\n - TS3: Test multiple posts → Each has unique discussion\n",“id”:“20260105125854”,“path”:"./notes/20260105125854/README.md",“project”:“52vibes”,“title”:“Week 1: Technical Requirements - Blog Platform (BP-TECH)”}`TOOL-CALL: mcp_note_update_note
{"new_content":" - TS3: Test multiple posts \u2192 Each has unique discussion\n\n### Accessibility (BP040, BP041, BP042, BP043, BP044, BP045)\n\nTECH_REQ: [BP_A11Y_0001] - Blog Platform \u2192 Semantic HTML Structure #BP040\n* Document structure SHALL use semantic HTML5 elements.\n* Required landmark elements:\n -for site header\n -TOOL:
{"message":"Updated note 20260105125854","success":true}AI: Completed Blog Platform technical requirements. Now adding crush-export (CX-TECH) requirements.
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125856","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - crush-export (CX-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** crush-export Tool \n**Product ID:** CX \n**Technical Spec ID:** CX-TECH \n**Description:** Technical architecture and implementation requirements for the Go CLI tool that extracts Crush AI session data from SQLite and generates wiki-ready markdown.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Language | Go 1.21+ | Cross-platform, single binary, SQLite support |\n| SQLite Library | modernc.org/sqlite | Pure Go, no CGO required |\n| CLI Framework | Standard library (flag) | Minimal dependencies, simple interface |\n| Output Format | GitHub-Flavored Markdown | Wiki compatibility, collapsible sections |\n\n---\n\n## Technical Requirements\n","id":"20260105125856","path":"./notes/20260105125856/README.md","project":"52vibes","title":"Week 1: Technical Requirements - crush-export (CX-TECH)"}
BREAK: 2026-01-05 07:58:32 - 2026-01-05 08:06:35 (8 min 3 sec)
USER: The keyword must be “TECHREQ” not “TECH_REQ”
AI: You’re right. I need to fix the keyword from “TECH_REQ” to “TECHREQ” throughout. Let me correct the BP-TECH zettel and use the correct format going forward.
TOOL-CALL: mcp_note_get_note
{"note_id":"20260105125854","project":"52vibes"}TOOL:
{"content":"# Week 1: Technical Requirements - Blog Platform (BP-TECH)\n\n\n\n\n## Product Overview\n\n**Product Name:** Blog Platform \n**Product ID:** BP \n**Technical Spec ID:** BP-TECH \n**Description:** Technical architecture and implementation requirements for the static blog site built with Hugo, deployed to Cloudflare Pages.\n\n---\n\n## Technical Decisions\n\n| Decision Area | Choice | Rationale |\n|---------------|--------|-----------|\n| Static Site Generator | Hugo v0.139+ (extended) | Latest features, SCSS support, image processing |\n| Hosting Platform | Cloudflare Pages | Native Hugo support, global CDN, free tier |\n| Theme System | CSS custom properties + prefers-color-scheme | Minimal JS, instant theme switching |\n| Font Loading | Google Fonts with font-display: swap | CDN reliability, performance optimization |\n| Social Cards | Hugo image processing (build-time) | No runtime cost, static assets |\n| Community API Caching | localStorage (5-min TTL) | Cross-session persistence, reduced API calls |\n| CLI Browser Support | Semantic HTML + progressive enhancement | Works in lynx (strict) and w3m (tables) |\n| Accessibility | WCAG 2.2 Level AA (target AAA) | Inclusive design standard |\n\n---\n\n## Technical Requirements\n\n### Infrastructure \u0026 Deployment (BP001, BP005)\n\nTECH_REQ: [BP_DNS_0001] - Blog Platform → Cloudflare DNS Configuration #BP001\n* The domain \52vibes.dev` SHALL be configured with Cloudflare DNS.\n* A CNAME record SHALL point `52vibes.dev` to the Cloudflare Pages deployment URL (`\u003cproject\u003e.pages.dev`).\n* Cloudflare proxy (orange cloud) SHALL be enabled for CDN and SSL termination.\n* DNS propagation SHALL complete within 24 hours of configuration.\n* The `www` subdomain SHOULD redirect to the apex domain (`52vibes.dev`).\n* References:\n + Cloudflare Pages Custom Domains\n\nSYSTEST: [BP_DNS_TEST_0001] - Blog Platform → DNS Resolution Verification #BP_DNS_0001\n* Objective: Verify DNS resolves correctly to Cloudflare Pages.\n* Setup: Configure DNS records in Cloudflare dashboard.\n* Test Steps:\n - TS1: Run `dig 52vibes.dev` → Expect CNAME or A record pointing to Cloudflare\n - TS2: Run `dig www.52vibes.dev` → Expect redirect record configured\n - TS3: Query from multiple geographic locations → Expect consistent resolution\n - TS4: Verify Cloudflare proxy status → Expect orange cloud enabled in dashboard\n* Boundary Cases:\n - BC1: Test immediately after DNS change → Document propagation time\n - BC2: Test from different ISPs → Expect consistent results after propagation\n\nTECH_REQ: [BP_CFP_0001] - Blog Platform → Cloudflare Pages Project Configuration #BP001\n* A Cloudflare Pages project SHALL be created and linked to the GitHub repository.\n* Build configuration SHALL specify:\n - Build command: `hugo –minify`\n - Build output directory: `public`\n - Root directory: `/` (repository root)\n - Hugo version environment variable: `HUGO_VERSION=0.139.0`\n* Production branch SHALL be set to `main`.\n* Preview deployments SHALL be enabled for pull requests.\n* The project name SHALL result in a `.pages.dev` URL that serves the site.\n References:\n + Cloudflare Pages Hugo Framework Guide\n\nSYSTEST: [BP_CFP_TEST_0001] - Blog Platform → Cloudflare Pages Build Verification #BP_CFP_0001\n* Objective: Verify Cloudflare Pages builds and deploys successfully.\n* Setup: Link GitHub repository to Cloudflare Pages project.\n* Test Steps:\n - TS1: Push commit to main branch → Expect build triggers automatically\n - TS2: Monitor build logs → Expect Hugo build completes without errors\n - TS3: Verify build output → Expect `public/` directory generated\n - TS4: Access `\u003cproject\u003e.pages.dev` → Expect site accessible\n - TS5: Verify HUGO_VERSION in build → Expect version 0.139.0 or higher\n* Failure Cases:\n - FC1: Invalid Hugo config → Expect build fails with clear error\n - FC2: Missing theme → Expect build fails, previous deployment remains live\n* Performance:\n - Measure build duration → Expect under 2 minutes for initial build\n - Measure deployment time → Expect under 1 minute after build\n\nTECH_REQ: [BP_CFP_0002] - Blog Platform → Environment Variables #BP001\n* The following environment variables SHALL be configured in Cloudflare Pages:\n - `HUGO_VERSION`: `0.139.0` (or latest stable)\n - `HUGO_ENVIRONMENT`: `production` (for production builds)\n* Environment variables SHALL be set in Cloudflare Pages project settings.\n* No sensitive credentials SHALL be stored in environment variables for this project.\n* References:\n + Cloudflare Pages Environment Variables\n\nSYSTEST: [BP_CFP_TEST_0002] - Blog Platform → Environment Variable Verification #BP_CFP_0002\n* Objective: Verify environment variables are correctly applied.\n* Setup: Configure environment variables in Cloudflare Pages dashboard.\n* Test Steps:\n - TS1: Trigger build → Inspect build logs for HUGO_VERSION\n - TS2: Verify Hugo version in output → Expect matches configured version\n - TS3: Check production environment → Expect HUGO_ENVIRONMENT=production\n* Verification:\n - Build log SHALL show "Hugo v0.139.0" or configured version\n\nTECH_REQ: [BP_HUGO_0001] - Blog Platform → Hugo Base URL Configuration #BP001\n* Hugo configuration SHALL set `baseURL` to `https://52vibes.dev/`.\n* Hugo configuration file SHALL be `hugo.toml` (TOML format preferred).\n* The blog section SHALL be configured to serve content from `/blog/` path.\n* Configuration SHALL include:\n - `languageCode`: `en-us`\n - `title`: `52 Vibes`\n - `enableRobotsTXT`: `true`\n - `enableGitInfo`: `true` (for lastmod dates)\n* References:\n + Hugo Configuration\n\nSYSTEST: [BP_HUGO_TEST_0001] - Blog Platform → Base URL and Path Verification #BP_HUGO_0001\n* Objective: Verify Hugo generates correct URLs and paths.\n* Setup: Build site locally with `hugo –minify`.\n* Test Steps:\n - TS1: Inspect generated HTML → Expect all URLs use `https://52vibes.dev/`\n - TS2: Verify blog index path → Expect accessible at `/blog/`\n - TS3: Check canonical URLs → Expect `\u003clink rel="canonical"\u003e` uses correct base\n - TS4: Verify internal links → Expect no broken internal links\n - TS5: Check sitemap.xml → Expect all URLs use production base URL\n* Local vs Production:\n - Local development MAY use `localhost:1313`\n - Production build MUST use `https://52vibes.dev/`\n\nTECH_REQ: [BP_SSL_0001] - Blog Platform → HTTPS and SSL Configuration #BP001\n* All traffic SHALL be served over HTTPS.\n* HTTP requests SHALL redirect to HTTPS (301 permanent redirect).\n* SSL certificate SHALL be automatically provisioned by Cloudflare.\n* SSL mode SHALL be set to "Full (strict)" in Cloudflare settings.\n* HSTS (HTTP Strict Transport Security) SHOULD be enabled.\n* References:\n + Cloudflare SSL/TLS\n\nSYSTEST: [BP_SSL_TEST_0001] - Blog Platform → HTTPS and Certificate Verification #BP_SSL_0001\n* Objective: Verify SSL/TLS is correctly configured.\n* Test Steps:\n - TS1: Request `http://52vibes.dev/blog` → Expect 301 redirect to HTTPS\n - TS2: Request `https://52vibes.dev/blog` → Expect HTTP 200\n - TS3: Inspect certificate → Expect valid, issued by Cloudflare\n - TS4: Check certificate expiry → Expect auto-renewal configured\n - TS5: Test with SSL Labs → Expect A or A+ rating\n* Security Headers:\n - Verify HSTS header present (if enabled)\n - Check for secure cookies (if any)\n* References:\n + SSL Labs Server Test\n\n### Core Architecture (BP002, BP003, BP004)\n\nTECH_REQ: [BP_SSR_0001] - Blog Platform → Server-Side Rendering Architecture #BP002\n* All page content SHALL be rendered at build time by Hugo (Static Site Generation).\n* HTML output SHALL contain complete content without requiring JavaScript hydration.\n* No client-side templating frameworks (React, Vue, etc.) SHALL be used.\n* Hugo templates SHALL use Go template syntax for content rendering.\n* Template directory structure SHALL follow Hugo conventions:\n - `layouts/_default/baseof.html` - base template\n - `layouts/_default/single.html` - single content pages\n - `layouts/_default/list.html` - list/index pages\n - `layouts/partials/` - reusable template components\n* References:\n + Hugo Templates\n\nSYSTEST: [BP_SSR_TEST_0001] - Blog Platform → Static Rendering Verification #BP_SSR_0001\n* Objective: Verify all content is statically rendered.\n* Test Steps:\n - TS1: Build site with `hugo –minify` → Inspect `public/` directory\n - TS2: Open any HTML file → Expect complete content in source\n - TS3: Disable JavaScript in browser → Load page → Expect all content visible\n - TS4: Use `curl` to fetch page → Expect complete HTML in response\n - TS5: Check for hydration scripts → Expect none present\n* Content Types:\n - Test blog post pages\n - Test index/list pages\n - Test static pages (About, etc.)\n\nTECH_REQ: [BP_NOJS_0001] - Blog Platform → JavaScript Budget and Constraints #BP002\n* Total JavaScript payload SHALL NOT exceed 2KB (minified, uncompressed).\n* JavaScript SHALL be used ONLY for:\n - Theme toggle persistence (localStorage) - ~500 bytes\n - Community page GitHub API fetch - ~1KB\n* No JavaScript frameworks or libraries SHALL be included.\n* All JavaScript SHALL be inline (no external JS files) or in a single bundled file.\n* JavaScript SHALL use vanilla ES6+ syntax (no transpilation required for modern browsers).\n* References:\n + JavaScript Module Best Practices\n\nSYSTEST: [BP_NOJS_TEST_0001] - Blog Platform → JavaScript Budget Verification #BP_NOJS_0001\n* Objective: Verify JavaScript stays within budget.\n* Test Steps:\n - TS1: Build production site → Locate all JavaScript in output\n - TS2: Measure total JS size → Expect ≤2KB minified\n - TS3: List all JS functionality → Expect only theme toggle + API fetch\n - TS4: Check for framework code → Expect none (React, Vue, jQuery, etc.)\n - TS5: Verify ES6+ syntax → Expect no transpilation artifacts\n* Tools:\n - Use browser DevTools Network tab\n - Use `wc -c` on minified JS files\n\nTECH_REQ: [BP_GRACE_0001] - Blog Platform → Graceful Degradation Strategy #BP002\n* When JavaScript is disabled:\n - Theme SHALL default to system preference via `prefers-color-scheme`\n - Theme toggle control SHALL remain visible but non-functional\n - Community page SHALL display fallback link to GitHub topics page\n* No "JavaScript required" messages SHALL be displayed.\n* No broken layouts or missing content SHALL occur without JavaScript.\n* All navigation SHALL remain fully functional without JavaScript.\n* References:\n + Progressive Enhancement\n\nSYSTEST: [BP_GRACE_TEST_0001] - Blog Platform → Graceful Degradation Verification #BP_GRACE_0001\n* Objective: Verify site functions correctly without JavaScript.\n* Setup: Disable JavaScript in browser settings.\n* Test Steps:\n - TS1: Load blog index → Expect all posts listed, readable\n - TS2: Navigate between pages → Expect all links work\n - TS3: Check theme → Expect matches system preference\n - TS4: View theme toggle → Expect visible (may be non-functional)\n - TS5: Load Community page → Expect fallback content/link displayed\n - TS6: Check for error messages → Expect none\n* Browsers:\n - Test in Chrome, Firefox with JS disabled\n - Test in lynx (inherently no JS)\n\nTECH_REQ: [BP_RESP_0001] - Blog Platform → Responsive Breakpoint System #BP003\n* CSS SHALL implement the following breakpoint system:\n - Mobile: `max-width: 767px`\n - Tablet: `min-width: 768px` and `max-width: 1023px`\n - Desktop: `min-width: 1024px`\n - Large Desktop: `min-width: 1440px` (optional enhancement)\n* Breakpoints SHALL be defined as CSS custom properties or SCSS variables.\n* Mobile-first approach SHALL be used (base styles for mobile, media queries for larger).\n* No horizontal scrolling SHALL occur at any viewport width ≥320px.\n* References:\n + CSS Media Queries\n\nSYSTEST: [BP_RESP_TEST_0001] - Blog Platform → Breakpoint Behavior Verification #BP_RESP_0001\n* Objective: Verify responsive behavior at all breakpoints.\n* Test Steps:\n - TS1: Set viewport to 320px width → Expect no horizontal scroll, content readable\n - TS2: Set viewport to 375px width → Expect mobile layout\n - TS3: Set viewport to 768px width → Expect tablet layout transition\n - TS4: Set viewport to 1024px width → Expect desktop layout\n - TS5: Set viewport to 1920px width → Expect full desktop layout\n - TS6: Resize viewport dynamically → Expect smooth transitions\n* Orientation:\n - Test mobile viewports in portrait and landscape\n* Content Types:\n - Test with long code blocks\n - Test with tables\n - Test with images\n\nTECH_REQ: [BP_RESP_0002] - Blog Platform → Fluid Typography and Spacing #BP003\n* Typography SHALL scale fluidly using CSS `clamp()` function.\n* Base font size range: `clamp(16px, 2.5vw, 18px)` for body text.\n* Heading sizes SHALL scale proportionally.\n* Spacing (margins, padding) SHALL use relative units (rem, em) or viewport units.\n* Line length SHALL be constrained to 65-75 characters for readability.\n* References:\n + CSS clamp()\n\nSYSTEST: [BP_RESP_TEST_0002] - Blog Platform → Typography Scaling Verification #BP_RESP_0002\n* Objective: Verify typography scales appropriately.\n* Test Steps:\n - TS1: Inspect body font size at 320px viewport → Expect ~16px\n - TS2: Inspect body font size at 1920px viewport → Expect ~18px\n - TS3: Measure line length in characters → Expect 65-75 characters max\n - TS4: Check heading hierarchy → Expect proportional scaling\n - TS5: Verify relative units in CSS → Expect rem/em usage\n* Readability:\n - Verify text is readable at all viewport sizes\n - Verify adequate spacing between elements\n\nTECH_REQ: [BP_PERF_0001] - Blog Platform → Asset Optimization Pipeline #BP004\n* Hugo asset pipeline SHALL be configured for optimization:\n - CSS: Minification enabled, unused CSS removal (if using SCSS)\n - HTML: Minification via `hugo –minify`\n - Images: WebP conversion with fallback, responsive srcset generation\n* Total page weight targets:\n - Blog index: ≤500KB\n - Blog post (without images): ≤300KB\n - Any page with images: ≤800KB\n* Asset fingerprinting SHALL be enabled for cache busting.\n* References:\n + Hugo Asset Minification\n + Hugo Image Processing\n\nSYSTEST: [BP_PERF_TEST_0001] - Blog Platform → Asset Optimization Verification #BP_PERF_0001\n* Objective: Verify assets are properly optimized.\n* Test Steps:\n - TS1: Build with `hugo –minify` → Verify minification applied\n - TS2: Inspect CSS output → Expect minified (no whitespace/comments)\n - TS3: Inspect HTML output → Expect minified\n - TS4: Check image formats → Expect WebP with fallbacks\n - TS5: Measure page weights → Verify within budget\n - TS6: Check asset URLs → Expect fingerprinted filenames\n* Tools:\n - Use browser DevTools Network tab for size measurements\n - Use `du -h` on output files\n\nTECH_REQ: [BP_PERF_0002] - Blog Platform → Core Web Vitals Optimization #BP004\n* Largest Contentful Paint (LCP) SHALL be under 2.5 seconds.\n* First Input Delay (FID) SHALL be under 100ms.\n* Cumulative Layout Shift (CLS) SHALL be under 0.1.\n* First Contentful Paint (FCP) SHOULD be under 1.5 seconds.\n* Implementation strategies:\n - Preload critical fonts\n - Inline critical CSS\n - Defer non-critical resources\n - Reserve space for dynamic content (prevent layout shifts)\n* References:\n + Core Web Vitals\n\nSYSTEST: [BP_PERF_TEST_0002] - Blog Platform → Core Web Vitals Measurement #BP_PERF_0002\n* Objective: Verify Core Web Vitals meet targets.\n* Test Steps:\n - TS1: Run Lighthouse on blog index → Expect Performance ≥95\n - TS2: Measure LCP → Expect \u003c2.5s\n - TS3: Measure FID → Expect \u003c100ms\n - TS4: Measure CLS → Expect \u003c0.1\n - TS5: Measure FCP → Expect \u003c1.5s\n - TS6: Run on multiple page types → Expect consistent scores\n* Testing Conditions:\n - Test with throttled connection (Slow 4G)\n - Test with CPU throttling (4x slowdown)\n* Tools:\n - Chrome DevTools Lighthouse\n - WebPageTest.org\n - PageSpeed Insights\n\nTECH_REQ: [BP_PERF_0003] - Blog Platform → Font Loading Strategy #BP004\n* Fonts SHALL be loaded from Google Fonts CDN.\n* Font loading SHALL use `font-display: swap` to prevent invisible text.\n* Font preconnect hints SHALL be included in `\u003chead\u003e`:\n - `\u003clink rel="preconnect" href="https://fonts.googleapis.com"\u003e`\n - `\u003clink rel="preconnect" href="https://fonts.gstatic.com" crossorigin\u003e`\n* Font families to load:\n - IBM Plex Sans: weights 400, 500, 600, 700\n - JetBrains Mono: weight 400\n* Font subsetting SHOULD be applied (latin subset only for initial load).\n* References:\n + Google Fonts CSS API\n + font-display\n\nSYSTEST: [BP_PERF_TEST_0003] - Blog Platform → Font Loading Verification #BP_PERF_0003\n* Objective: Verify fonts load efficiently without blocking render.\n* Test Steps:\n - TS1: Inspect `\u003chead\u003e` → Expect preconnect hints for Google Fonts\n - TS2: Check font-display → Expect `swap` in font declarations\n - TS3: Block Google Fonts → Expect fallback fonts display immediately\n - TS4: Measure font load time → Expect \u003c500ms on fast connection\n - TS5: Check for FOIT (Flash of Invisible Text) → Expect none\n - TS6: Check for FOUT (Flash of Unstyled Text) → Acceptable with swap\n* Network Tab:\n - Verify font files loaded from fonts.gstatic.com\n - Verify only required weights loaded\n\nTECH_REQ: [BP_DEPLOY_0001] - Blog Platform → Deployment Time Constraints #BP005\n* Content-only changes SHALL deploy within 5 minutes of push to main branch.\n* Full site rebuilds SHALL complete within 10 minutes.\n* Cloudflare Pages build SHALL NOT require manual intervention.\n* Build failures SHALL NOT affect live production site (atomic deployments).\n* Deployment notifications SHOULD be available via Cloudflare dashboard.\n* References:\n + Cloudflare Pages Deployments\n\nSYSTEST: [BP_DEPLOY_TEST_0001] - Blog Platform → Deployment Time Verification #BP_DEPLOY_0001\n* Objective: Verify deployment completes within time constraints.\n* Test Steps:\n - TS1: Push content-only change (markdown file) → Start timer\n - TS2: Monitor Cloudflare Pages deployment → Record completion time\n - TS3: Verify deployed content → Expect change visible\n - TS4: Calculate total time → Expect ≤5 minutes\n* Failure Recovery:\n - Push invalid change → Verify build fails\n - Verify live site unchanged → Previous version still served\n* Metrics:\n - Document average build times over 10 deployments\n\n### CLI Browser Compatibility (BP006)\n\nTECH_REQ: [BP_CLI_0001] - Blog Platform → Semantic HTML for CLI Rendering #BP006\n* HTML structure SHALL prioritize semantic elements that render well in text browsers.\n* Required semantic elements:\n - `\u003cheader\u003e` for site header\n - `\u003cnav\u003e` for navigation with `\u003cul\u003e` list structure\n - `\u003cmain\u003e` for primary content\n - `\u003carticle\u003e` for blog posts\n - `\u003csection\u003e` for content sections with headings\n - `\u003cfooter\u003e` for site footer\n* Links SHALL use descriptive text (no "click here").\n* Images SHALL include meaningful `alt` text for text-only display.\n* References:\n + HTML Semantic Elements\n\nSYSTEST: [BP_CLI_TEST_0001] - Blog Platform → Lynx Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in lynx browser.\n* Setup: Install lynx text browser.\n* Test Steps:\n - TS1: `lynx https://52vibes.dev/blog` → Expect page loads, title visible\n - TS2: Navigate to blog post → Expect content fully readable\n - TS3: Follow navigation links → Expect all work correctly\n - TS4: Check TOC anchor links → Expect navigate to sections\n - TS5: View post with code blocks → Expect code readable\n - TS6: Check for broken elements → Expect none\n* Content Verification:\n - Verify all text content visible\n - Verify links clearly labeled\n - Verify image alt text displayed\n\nSYSTEST: [BP_CLI_TEST_0002] - Blog Platform → w3m Rendering Verification #BP_CLI_0001\n* Objective: Verify site renders correctly in w3m browser.\n* Setup: Install w3m text browser.\n* Test Steps:\n - TS1: `w3m https://52vibes.dev/blog` → Expect page loads\n - TS2: Navigate to Weekly Index → Expect table renders readably\n - TS3: Verify table alignment → Expect columns aligned\n - TS4: Follow navigation links → Expect all work correctly\n - TS5: Test forms (if any) → Expect usable\n* Table Testing:\n - Weekly Index table with 52 weeks → Must be readable\n - Tables in blog posts → Must render with structure\n\nTECH_REQ: [BP_CLI_0002] - Blog Platform → Table Rendering Strategy #BP006\n* Tables SHALL use standard HTML `\u003ctable\u003e` elements with proper structure.\n* Required table elements:\n - `\u003cthead\u003e` with `\u003cth\u003e` headers for accessibility\n - `\u003ctbody\u003e` for data rows\n - `scope` attributes on header cells\n* Tables SHALL NOT use CSS grid/flexbox to simulate tables.\n* Complex tables SHOULD include `\u003ccaption\u003e` for context.\n* Very wide tables MAY use horizontal scroll container on mobile (CSS only).\n* For CLI browsers, tables SHALL degrade to readable text columns.\n* References:\n + HTML Table Accessibility\n\nSYSTEST: [BP_CLI_TEST_0003] - Blog Platform → Table Accessibility Verification #BP_CLI_0002\n* Objective: Verify tables are accessible and CLI-friendly.\n* Test Steps:\n - TS1: Inspect Weekly Index table HTML → Expect `\u003cthead\u003e`, `\u003ctbody\u003e`, `\u003cth\u003e`\n - TS2: Check `scope` attributes → Expect on header cells\n - TS3: Test in screen reader → Expect headers announced\n - TS4: Test in w3m → Expect table structure preserved\n - TS5: Test in lynx → Expect readable (may linearize)\n* Mobile:\n - Test table at 320px viewport → Verify readable without breaking layout\n\n### Visual Design System (BP007, BP008, BP009, BP010, BP011)\n\nTECH_REQ: [BP_TMUX_0001] - Blog Platform → Tmux-Inspired Layout Structure #BP007\n* Page layout SHALL implement a tmux-inspired terminal aesthetic:\n - Top status bar: Fixed height, full width, contains week numbers\n - Main content pane: Bordered frame containing page content\n - Bottom navigation bar: Fixed height, full width, contains nav links\n* CSS borders SHALL create the framed appearance (no ASCII characters).\n* Border style SHALL be `solid 1px` using theme colors.\n* Content pane SHOULD have subtle inner padding (1-2rem).\n* Layout SHALL remain consistent across all page types.\n* References:\n + tmux Manual (for aesthetic reference)\n\nSYSTEST: [BP_TMUX_TEST_0001] - Blog Platform → Tmux Layout Verification #BP_TMUX_0001\n* Objective: Verify tmux-inspired visual design.\n* Test Steps:\n - TS1: Load any page → Verify top status bar present\n - TS2: Verify main content area → Expect bordered frame\n - TS3: Verify bottom navigation → Expect navigation bar present\n - TS4: Compare to tmux screenshot → Expect similar aesthetic\n - TS5: Test multiple pages → Expect consistent layout\n* Visual Elements:\n - Status bar contains week numbers (clickable for completed weeks)\n - Main pane has visible border\n - Navigation bar at bottom with links\n\nTECH_REQ: [BP_GRUVBOX_0001] - Blog Platform → Gruvbox Color Palette Implementation #BP008\n* Color system SHALL be based on Gruvbox color palette.\n* CSS custom properties SHALL define all colors:\n ```css\n /* Dark theme /\n –bg-dark: #1d2021;\n –bg-dark-soft: #282828;\n –fg-dark: #ebdbb2;\n –accent: #d65d0e;\n –green: #b8bb26;\n –red: #fb4934;\n –yellow: #fabd2f;\n –blue: #83a598;\n \n / Light theme /\n –bg-light: #fbf1c7;\n –bg-light-soft: #f2e5bc;\n –fg-light: #3c3836;\n ```\n All UI elements SHALL use these CSS custom properties (no hardcoded colors).\n* Accent color (#d65d0e orange) SHALL be used for interactive elements.\n* References:\n + Gruvbox GitHub\n\nSYSTEST: [BP_GRUVBOX_TEST_0001] - Blog Platform → Color Palette Verification #BP_GRUVBOX_0001\n* Objective: Verify Gruvbox colors are correctly implemented.\n* Test Steps:\n - TS1: Inspect CSS → Expect custom properties defined\n - TS2: Dark mode background → Sample color → Expect #1d2021 or similar\n - TS3: Light mode background → Sample color → Expect #fbf1c7 or similar\n - TS4: Dark mode text → Sample color → Expect #ebdbb2 or similar\n - TS5: Light mode text → Sample color → Expect #3c3836 or similar\n - TS6: Accent color (links, buttons) → Expect #d65d0e\n* Tools:\n - Use browser color picker DevTools\n - Verify CSS custom properties in computed styles\n\nTECH_REQ: [BP_THEME_0001] - Blog Platform → CSS Theme Switching Mechanism #BP008\n* Default theme SHALL be determined by `prefers-color-scheme` media query.\n* CSS SHALL use media query to apply theme-specific custom properties:\n ```css\n :root {\n /* Light theme defaults /\n }\n @media (prefers-color-scheme: dark) {\n :root {\n / Dark theme overrides /\n }\n }\n ```\n A `data-theme` attribute on `\u003chtml\u003e` element SHALL allow JavaScript override.\n* When `data-theme="dark"` or `data-theme="light"` is set, it SHALL override system preference.\n* Theme transition SHALL NOT cause layout shift (CLS).\n* References:\n + prefers-color-scheme\n\nSYSTEST: [BP_THEME_TEST_0001] - Blog Platform → Theme Switching Verification #BP_THEME_0001\n* Objective: Verify CSS theme switching works correctly.\n* Test Steps:\n - TS1: Set OS to dark mode → Load page → Expect dark theme\n - TS2: Set OS to light mode → Load page → Expect light theme\n - TS3: Set `data-theme="dark"` in DevTools → Expect dark theme override\n - TS4: Set `data-theme="light"` in DevTools → Expect light theme override\n - TS5: Toggle system preference → Expect theme updates (if no JS override)\n* No JavaScript:\n - Disable JS → Verify theme follows system preference\n\nTECH_REQ: [BP_TOGGLE_0001] - Blog Platform → Theme Toggle Implementation #BP009\n* A visible toggle control SHALL be placed in the page header or footer.\n* Toggle SHALL be implemented as a `\u003cbutton\u003e` element for accessibility.\n* Toggle SHALL have appropriate ARIA attributes:\n - `aria-label`: "Toggle dark/light theme"\n - `aria-pressed`: "true" or "false" based on state\n* Clicking toggle SHALL:\n 1. Set `data-theme` attribute on `\u003chtml\u003e`\n 2. Store preference in localStorage key `theme`\n 3. Update button visual state\n* JavaScript for toggle SHALL be under 500 bytes minified.\n* References:\n + ARIA button pattern\n\nSYSTEST: [BP_TOGGLE_TEST_0001] - Blog Platform → Theme Toggle Functionality #BP_TOGGLE_0001\n* Objective: Verify theme toggle works and persists preference.\n* Test Steps:\n - TS1: Locate toggle button → Expect visible in header/footer\n - TS2: Click toggle in dark mode → Expect switch to light\n - TS3: Click toggle in light mode → Expect switch to dark\n - TS4: Inspect localStorage → Expect `theme` key set\n - TS5: Refresh page → Expect preference persisted\n - TS6: Close browser, reopen → Expect preference persisted\n* Accessibility:\n - TS7: Inspect `aria-label` → Expect descriptive label\n - TS8: Tab to toggle → Expect focusable\n - TS9: Press Enter on focused toggle → Expect theme change\n - TS10: Check `aria-pressed` → Expect updates with state\n\nTECH_REQ: [BP_TOGGLE_0002] - Blog Platform → Theme Preference Persistence #BP009\n* Theme preference SHALL be stored in localStorage under key `theme`.\n* Valid values: `"dark"`, `"light"`, or absent (system preference).\n* On page load, JavaScript SHALL:\n 1. Check localStorage for `theme` value\n 2. If set, apply `data-theme` attribute\n 3. If not set, defer to CSS `prefers-color-scheme`\n* Theme restoration SHALL occur before first paint (inline script in `\u003chead\u003e`).\n* This prevents flash of wrong theme on page load.\n* References:\n + localStorage API\n\nSYSTEST: [BP_TOGGLE_TEST_0002] - Blog Platform → Theme Persistence Edge Cases #BP_TOGGLE_0002\n* Objective: Verify theme persistence handles edge cases.\n* Test Steps:\n - TS1: Clear localStorage → Load page → Expect system preference\n - TS2: Set theme → Load new page → Expect theme persists\n - TS3: Set theme → Hard refresh (Ctrl+Shift+R) → Expect theme persists\n - TS4: Set invalid localStorage value → Load page → Expect graceful fallback\n - TS5: localStorage unavailable → Load page → Expect system preference\n* Flash Prevention:\n - TS6: Set dark preference → Load page → Expect NO flash of light theme\n\nTECH_REQ: [BP_TYPO_0001] - Blog Platform → Typography System Implementation #BP010\n* Font family stack SHALL be defined in CSS custom properties:\n ```css\n –font-body: ‘IBM Plex Sans’, -apple-system, BlinkMacSystemFont, sans-serif;\n –font-mono: ‘JetBrains Mono’, ‘SF Mono’, ‘Menlo’, monospace;\n ```\n* Font sizes SHALL use a modular scale (ratio ~1.25):\n - `–font-size-sm`: 0.875rem (14px)\n - `–font-size-base`: 1rem (16px)\n - `–font-size-lg`: 1.125rem (18px)\n - `–font-size-xl`: 1.25rem (20px)\n - `–font-size-2xl`: 1.5rem (24px)\n - `–font-size-3xl`: 2rem (32px)\n* Line height for body text SHALL be 1.6-1.7 for readability.\n* References:\n + Modular Scale\n\nSYSTEST: [BP_TYPO_TEST_0001] - Blog Platform → Typography Implementation Verification #BP_TYPO_0001\n* Objective: Verify correct fonts and sizes are applied.\n* Test Steps:\n - TS1: Inspect body text → Expect IBM Plex Sans\n - TS2: Inspect headings → Expect IBM Plex Sans\n - TS3: Inspect code blocks → Expect JetBrains Mono\n - TS4: Inspect inline code → Expect JetBrains Mono\n - TS5: Check body font size → Expect 16-18px\n - TS6: Check line height → Expect 1.6-1.7\n* Fallback:\n - Block Google Fonts → Expect system fonts render cleanly\n\nTECH_REQ: [BP_BORDER_0001] - Blog Platform → CSS Border System #BP011\n* All visual borders SHALL be implemented using CSS `border` properties.\n* ASCII box-drawing characters SHALL NOT be used for structural elements.\n* Border colors SHALL use CSS custom properties for theme compatibility.\n* Standard border definition:\n ```css\n –border-color: var(–fg-dark); /* or –fg-light /\n –border-width: 1px;\n –border-style: solid;\n ```\n Border radius SHALL be minimal or zero for terminal aesthetic.\n* References:\n + CSS Borders\n\nSYSTEST: [BP_BORDER_TEST_0001] - Blog Platform → Border Implementation Verification #BP_BORDER_0001\n* Objective: Verify CSS borders, not ASCII characters.\n* Test Steps:\n - TS1: Inspect page HTML source → Search for box-drawing Unicode (─│┌┐└┘)\n - TS2: Expect NOT found in structural elements\n - TS3: Inspect border elements via DevTools → Expect CSS border properties\n - TS4: Toggle theme → Expect borders visible in both themes\n - TS5: Test in CLI browser → Expect readable without borders\n* Unicode Check:\n - Search: U+2500-U+257F (Box Drawing block)\n - These MAY appear in content, but NOT for layout\n\n### Navigation System (BP012, BP013, BP014, BP015, BP016)\n\nTECH_REQ: [BP_NAV_0001] - Blog Platform → Week Status Bar Implementation #BP012\n* Top status bar SHALL display week numbers 1-52.\n* Week numbers SHALL be generated by Hugo template from content data.\n* Implementation SHALL use Hugo’s `.Site.Pages` to determine completed weeks.\n* Completed weeks SHALL render as `\u003ca\u003e` links to post URLs.\n* Incomplete weeks SHALL render as `\u003cspan\u003e` elements (not clickable).\n* Visual styling SHALL distinguish clickable vs non-clickable weeks.\n* Week numbers SHALL be displayed in a single horizontal row (with wrapping on mobile).\n* References:\n + Hugo Page Collections\n\nSYSTEST: [BP_NAV_TEST_0001] - Blog Platform → Week Status Bar Verification #BP_NAV_0001\n* Objective: Verify week status bar displays correctly.\n* Test Steps:\n - TS1: Load any page → Verify status bar at top\n - TS2: Count week numbers → Expect 52 visible\n - TS3: Identify completed weeks → Verify are `\u003ca\u003e` links\n - TS4: Identify incomplete weeks → Verify are NOT links\n - TS5: Click completed week → Expect navigates to post\n - TS6: Attempt click incomplete week → Expect no navigation\n* Visual:\n - Completed weeks: colored/underlined\n - Incomplete weeks: muted/no interaction indicator\n\nTECH_REQ: [BP_NAV_0002] - Blog Platform → Week Tooltip Implementation #BP013\n* Week number links SHALL include `title` attribute with post title.\n* Tooltip SHALL use native browser tooltip (no JavaScript).\n* Hugo template SHALL populate title from front matter.\n* Example: `\u003ca href="/blog/week-01-infrastructure/" title="Week 1: Infrastructure"\u003e1\u003c/a\u003e`\n* Incomplete weeks SHALL NOT have tooltips.\n* References:\n + HTML title attribute\n\nSYSTEST: [BP_NAV_TEST_0002] - Blog Platform → Week Tooltip Verification #BP_NAV_0002\n* Objective: Verify native tooltips on week links.\n* Test Steps:\n - TS1: Hover over completed week number → Expect tooltip appears\n - TS2: Verify tooltip content → Expect post title displayed\n - TS3: Hover over incomplete week → Expect NO tooltip\n - TS4: Inspect HTML → Expect `title` attribute on completed week links\n - TS5: Verify no JavaScript tooltip → Expect native browser behavior\n* Timing:\n - Tooltip appears after browser default delay (~500-1000ms)\n\nTECH_REQ: [BP_NAV_0003] - Blog Platform → Weeks Index Link #BP014\n* Status bar SHALL include "Weeks" label/link.\n* Link SHALL navigate to `/blog/weeks/` (Weekly Index page).\n* Implementation SHALL be standard `\u003ca\u003e` element.\n* Link SHALL be accessible in CLI browsers.\n* Position SHALL be consistent (e.g., left side of status bar).\n* References:\n + Hugo Internal Links\n\nSYSTEST: [BP_NAV_TEST_0003] - Blog Platform → Weeks Index Link Verification #BP_NAV_0003\n* Objective: Verify "Weeks" link in status bar.\n* Test Steps:\n - TS1: Locate "Weeks" in status bar → Expect visible\n - TS2: Click "Weeks" → Expect navigates to `/blog/weeks/`\n - TS3: Inspect HTML → Expect `\u003ca\u003e` element\n - TS4: Test in lynx → Expect link accessible and functional\n\nTECH_REQ: [BP_NAV_0004] - Blog Platform → Footer Navigation Bar #BP015\n* Footer navigation bar SHALL be present on all pages.\n* Required links:\n - About: `/about/`\n - Weekly Index: `/blog/weeks/`\n - Reports: `/blog/reports/`\n - RSS: `/index.xml` or `/blog/index.xml`\n - GitHub: `https://github.com/\u003cowner\u003e/\u003crepo\u003e` (external)\n* Links SHALL be implemented as `\u003ca\u003e` elements within `\u003cnav\u003e` and `\u003cfooter\u003e`.\n* Link order SHALL be consistent across all pages.\n* Hugo partial template SHALL render footer navigation.\n* References:\n + Hugo Partials\n\nSYSTEST: [BP_NAV_TEST_0004] - Blog Platform → Footer Navigation Verification #BP_NAV_0004\n* Objective: Verify footer navigation completeness.\n* Test Steps:\n - TS1: Load blog index → Verify footer nav present\n - TS2: Verify About link → Expect navigates to `/about/`\n - TS3: Verify Weekly Index link → Expect navigates to `/blog/weeks/`\n - TS4: Verify Reports link → Expect navigates to `/blog/reports/`\n - TS5: Verify RSS link → Expect valid RSS feed\n - TS6: Verify GitHub link → Expect opens GitHub repository\n - TS7: Test on About page → Expect same footer nav\n - TS8: Test on blog post → Expect same footer nav\n* External Links:\n - GitHub link SHOULD open in new tab (optional `target="_blank"`)\n\nTECH_REQ: [BP_NAV_0005] - Blog Platform → Descriptive Navigation Labels #BP016\n* All navigation links SHALL use descriptive text labels.\n* Icons MAY accompany labels but SHALL NOT replace them.\n* Prohibited patterns:\n - "Click here"\n - "Read more"\n - Icon-only links\n - Single character links (except week numbers in status bar)\n* Week numbers in status bar SHALL have title attribute for context.\n* External links SHOULD indicate they open externally.\n* References:\n + WCAG Link Purpose\n\nSYSTEST: [BP_NAV_TEST_0005] - Blog Platform → Navigation Labels Verification #BP_NAV_0005\n* Objective: Verify all navigation uses descriptive text.\n* Test Steps:\n - TS1: Inspect all navigation elements → Expect text labels\n - TS2: Search for "click here" → Expect NOT found\n - TS3: Search for "read more" → Expect NOT found\n - TS4: Check icon-only elements → Expect none in navigation\n - TS5: Test in lynx → Expect navigation understandable\n - TS6: Run accessibility audit → Expect no "link purpose" violations\n\n### Table of Contents (BP017, BP018)\n\nTECH_REQ: [BP_TOC_0001] - Blog Platform → Auto-Generated TOC Implementation #BP017\n* Table of Contents SHALL be auto-generated from post headings.\n* Hugo’s `.TableOfContents` function SHALL be used.\n* TOC SHALL include h2 and h3 headings.\n* Configuration in `hugo.toml`:\n ```toml\n [markup.tableOfContents]\n startLevel = 2\n endLevel = 3\n ordered = false\n ```\n* TOC SHALL be rendered as nested `\u003cul\u003e` lists.\n* Each TOC item SHALL link to corresponding heading anchor.\n* References:\n + Hugo Table of Contents\n\nSYSTEST: [BP_TOC_TEST_0001] - Blog Platform → TOC Generation Verification #BP_TOC_0001\n* Objective: Verify TOC is correctly generated.\n* Test Steps:\n - TS1: Create post with h2 and h3 headings → Build site\n - TS2: Verify TOC appears at top of post → Expect `\u003cul\u003e` structure\n - TS3: Count TOC items → Expect matches heading count\n - TS4: Click TOC item → Expect scrolls to section\n - TS5: Verify URL hash → Expect `#heading-id` in URL\n - TS6: Test with nested headings (h3 under h2) → Expect nested list\n* Edge Cases:\n - Post with no headings → TOC section empty or hidden\n - Post with only h1 headings → TOC should be empty\n\nTECH_REQ: [BP_TOC_0002] - Blog Platform → Heading Anchor IDs #BP017\n* All h2 and h3 headings SHALL have auto-generated IDs.\n* Hugo SHALL generate IDs using the `anchorize` function.\n* IDs SHALL be URL-safe (lowercase, hyphenated).\n* Duplicate heading text SHALL result in unique IDs (suffix numbers).\n* Example: "Getting Started" → id="getting-started"\n* References:\n + Hugo Heading Anchors\n\nSYSTEST: [BP_TOC_TEST_0002] - Blog Platform → Heading Anchor Verification #BP_TOC_0002\n* Objective: Verify heading anchors are correctly generated.\n* Test Steps:\n - TS1: Inspect h2 element → Expect `id` attribute present\n - TS2: Verify ID format → Expect lowercase, hyphenated\n - TS3: Test duplicate headings → Expect unique IDs (suffix)\n - TS4: Navigate to `#heading-id` URL → Expect scrolls to heading\n - TS5: Test with special characters → Expect sanitized ID\n\nTECH_REQ: [BP_STICKY_0001] - Blog Platform → CSS Sticky Section Indicator #BP018\n* Section indicator SHOULD be implemented using CSS `position: sticky`.\n* Indicator SHALL display current section name during scroll.\n* Implementation SHALL NOT require JavaScript.\n* CSS scroll-snap or IntersectionObserver-free approach SHALL be used.\n* This is a SHOULD requirement; implementation is optional.\n* If implemented, format: "§ Reading: [Section Name]"\n* References:\n + CSS position: sticky\n\nSYSTEST: [BP_STICKY_TEST_0001] - Blog Platform → Sticky Section Indicator Verification #BP_STICKY_0001\n* Objective: Verify sticky section indicator (if implemented).\n* Test Steps (if implemented):\n - TS1: Navigate to long post (5+ sections) → Locate indicator\n - TS2: Scroll through sections → Expect indicator updates\n - TS3: Verify CSS position → Expect `sticky`\n - TS4: Disable JavaScript → Expect indicator still works\n - TS5: Verify format → Expect "§ Reading: [Section Name]"\n* Note: SHOULD requirement; document if not implemented\n\n### Content Pages (BP019, BP020, BP021, BP022, BP023)\n\nTECH_REQ: [BP_ABOUT_0001] - Blog Platform → About Page Implementation #BP019\n* About page SHALL be created at `content/about/_index.md`.\n* Page SHALL use Hugo `page` layout.\n* Required content sections:\n - Project description (52vibes purpose)\n - Author information\n - Contact/contribution information\n* URL SHALL be `/about/`.\n* Page SHALL use same layout/styling as blog pages.\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_ABOUT_TEST_0001] - Blog Platform → About Page Verification #BP_ABOUT_0001\n* Objective: Verify About page content and accessibility.\n* Test Steps:\n - TS1: Navigate to `/about/` → Expect HTTP 200\n - TS2: Verify project description → Expect meaningful content\n - TS3: Verify author information → Expect name/details\n - TS4: Verify layout matches blog → Expect consistent design\n - TS5: Test in CLI browser → Expect content readable\n* Content Quality:\n - Description explains 52vibes project\n - Author section has appropriate detail\n\nTECH_REQ: [BP_WEEKLY_0001] - Blog Platform → Weekly Index Page Implementation #BP020\n* Weekly Index page SHALL be created at `content/blog/weeks/_index.md`.\n* Page SHALL display table of all 52 weeks.\n* Table columns: Week #, Status, Title, Date Published.\n* Hugo template SHALL iterate `.Site.Pages` to build table.\n* Status values: Completed (linked), In Progress (labeled), Upcoming (muted).\n* Table SHALL use proper HTML table structure (`\u003ctable\u003e`, `\u003cthead\u003e`, `\u003ctbody\u003e`).\n* References:\n + Hugo Range\n\nSYSTEST: [BP_WEEKLY_TEST_0001] - Blog Platform → Weekly Index Verification #BP_WEEKLY_0001\n* Objective: Verify Weekly Index displays all 52 weeks.\n* Test Steps:\n - TS1: Navigate to `/blog/weeks/` → Expect page loads\n - TS2: Count table rows → Expect 52 weeks\n - TS3: Verify completed weeks → Expect linked with title\n - TS4: Verify upcoming weeks → Expect not linked, muted styling\n - TS5: Click completed week → Expect navigates to post\n - TS6: Test in w3m → Expect table renders readably\n* Dynamic Content:\n - Verify table updates when new weeks published\n\nTECH_REQ: [BP_REPORTS_0001] - Blog Platform → Reports Section Implementation #BP021\n* Reports section SHALL be at `content/blog/reports/_index.md`.\n* Hugo template SHALL list all report posts (monthly, quarterly).\n* Reports SHALL be tagged or categorized for filtering.\n* Empty state SHALL display friendly message.\n* Report listing SHALL include: title, type (monthly/quarterly), date.\n* References:\n + Hugo Taxonomies\n\nSYSTEST: [BP_REPORTS_TEST_0001] - Blog Platform → Reports Section Verification #BP_REPORTS_0001\n* Objective: Verify Reports section displays correctly.\n* Test Steps:\n - TS1: Navigate to `/blog/reports/` → Expect page loads\n - TS2: Verify report listings → When reports exist\n - TS3: Verify empty state → When no reports, friendly message\n - TS4: Click report → Expect navigates to full report\n - TS5: Verify type indicator → Monthly vs Quarterly distinguishable\n\nTECH_REQ: [BP_COMMUNITY_0001] - Blog Platform → Community Page Implementation #BP022\n* Community page SHALL be at `content/community/_index.md`.\n* Page SHALL contain:\n - Static introduction/description\n - Dynamic repository list (JavaScript-populated)\n - Fallback content when API unavailable\n* JavaScript SHALL fetch from GitHub Search API:\n - Endpoint: `https://api.github.com/search/repositories?q=topic:52vibes`\n* API fetch SHALL be deferred (non-blocking page load).\n* References:\n + GitHub Search API\n\nSYSTEST: [BP_COMMUNITY_TEST_0001] - Blog Platform → Community Page Verification #BP_COMMUNITY_0001\n* Objective: Verify Community page functionality.\n* Test Steps:\n - TS1: Navigate to `/community/` → Expect page loads\n - TS2: Wait for API response → Expect repos displayed (if any)\n - TS3: Verify loading indicator → During fetch\n - TS4: Block API (DevTools) → Expect fallback displayed\n - TS5: Disable JavaScript → Expect fallback link visible\n* API Integration:\n - Verify correct endpoint called\n - Verify topic filter applied\n\nTECH_REQ: [BP_BLOGIDX_0001] - Blog Platform → Blog Index Implementation #BP023\n* Blog index SHALL be at `content/blog/_index.md`.\n* Hugo list template SHALL display all published posts.\n* Each listing SHALL show: title, date, summary/description.\n* Posts SHALL be ordered by date (newest first).\n* Hugo configuration: `[params] mainSections = ["blog"]`.\n* Pagination SHOULD be implemented if posts exceed 10.\n* References:\n + Hugo List Templates\n\nSYSTEST: [BP_BLOGIDX_TEST_0001] - Blog Platform → Blog Index Verification #BP_BLOGIDX_0001\n* Objective: Verify blog index lists all posts.\n* Test Steps:\n - TS1: Navigate to `/blog/` → Expect page loads\n - TS2: Verify all published posts listed → Count matches\n - TS3: Verify each listing → Title, date, summary present\n - TS4: Verify ordering → Newest first\n - TS5: Click post title → Expect navigates to full post\n - TS6: Verify in CLI browser → List readable\n\n### URL Structure and Post Features (BP024, BP025, BP026, BP027, BP028, BP029, BP030)\n\nTECH_REQ: [BP_URL_0001] - Blog Platform → Weekly Post URL Pattern #BP024\n* Weekly posts SHALL use URL pattern: `/blog/week-XX-\u003cslug\u003e/`\n* Week number SHALL be zero-padded (01-52).\n* Slug SHALL be derived from title (lowercase, hyphenated).\n* Hugo front matter SHALL define:\n ```yaml\n slug: "week-01-infrastructure"\n ```\n* Alternatively, file naming: `content/blog/week-01-infrastructure/index.md`\n* References:\n + Hugo URL Management\n\nSYSTEST: [BP_URL_TEST_0001] - Blog Platform → Weekly Post URL Verification #BP_URL_0001\n* Objective: Verify weekly post URLs follow pattern.\n* Test Steps:\n - TS1: Create week 1 post → Verify URL is `/blog/week-01-\u003cslug\u003e/`\n - TS2: Verify zero-padding → Week 1 = 01, Week 10 = 10\n - TS3: Verify slug format → Lowercase, hyphenated\n - TS4: Test URL directly → Expect HTTP 200\n* Boundary:\n - Week 01, Week 10, Week 52 formatting\n\nTECH_REQ: [BP_URL_0002] - Blog Platform → Monthly Report URL Pattern #BP025\n* Monthly reports SHALL use URL pattern: `/blog/reports/YYYY-MM/`\n* Year: 4 digits, Month: 2 digits (zero-padded).\n* Content location: `content/blog/reports/2026-01/index.md`\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_URL_TEST_0002] - Blog Platform → Monthly Report URL Verification #BP_URL_0002\n* Objective: Verify monthly report URLs follow pattern.\n* Test Steps:\n - TS1: Create January 2026 report → Verify URL `/blog/reports/2026-01/`\n - TS2: Verify date format → YYYY-MM\n - TS3: Test URL directly → Expect HTTP 200\n* Boundary:\n - January (01), December (12), year transitions\n\nTECH_REQ: [BP_URL_0003] - Blog Platform → Quarterly Report URL Pattern #BP026\n* Quarterly reports SHALL use URL pattern: `/blog/reports/YYYY-qN/`\n* Year: 4 digits, Quarter: lowercase ‘q’ + 1-4.\n* Content location: `content/blog/reports/2026-q1/index.md`\n* References:\n + Hugo Content Organization\n\nSYSTEST: [BP_URL_TEST_0003] - Blog Platform → Quarterly Report URL Verification #BP_URL_0003\n* Objective: Verify quarterly report URLs follow pattern.\n* Test Steps:\n - TS1: Create Q1 2026 report → Verify URL `/blog/reports/2026-q1/`\n - TS2: Verify quarter format → Lowercase ‘q’ + 1-4\n - TS3: Test all quarters → q1, q2, q3, q4\n* Case Sensitivity:\n - Must be lowercase ‘q’, not ‘Q’\n\nTECH_REQ: [BP_META_0001] - Blog Platform → Post Metadata Display #BP027\n* Post template SHALL display metadata section at top.\n* Required metadata fields:\n - Title (from front matter `title`)\n - Publication date (from `date`, formatted human-readable)\n - Reading time (calculated via Hugo, e.g., `{{ .ReadingTime }} min read`)\n - Quarter/theme (from front matter `quarter` and `theme`)\n* Hugo template SHALL calculate reading time automatically.\n* Format example: "Q1: Agentic Infrastructure • 5 min read • January 5, 2026"\n* References:\n + Hugo Variables\n\nSYSTEST: [BP_META_TEST_0001] - Blog Platform → Post Metadata Verification #BP_META_0001\n* Objective: Verify post metadata is displayed correctly.\n* Test Steps:\n - TS1: Navigate to blog post → Expect metadata section visible\n - TS2: Verify title → Matches front matter\n - TS3: Verify date → Human-readable format\n - TS4: Verify reading time → Reasonable for content length\n - TS5: Verify quarter/theme → Matches front matter\n* Consistency:\n - Check multiple posts for consistent metadata display\n\nTECH_REQ: [BP_POSTNAV_0001] - Blog Platform → Previous/Next Navigation #BP028\n* Post template SHALL include prev/next navigation links.\n* Hugo template SHALL use `.PrevInSection` and `.NextInSection`.\n* Links SHALL only appear when adjacent posts exist:\n - No "Previous" on first post\n - No "Next" on latest post\n* Link text SHALL include week number and/or title.\n* Navigation SHALL be positioned at end of post content.\n* References:\n + Hugo Page Methods\n\nSYSTEST: [BP_POSTNAV_TEST_0001] - Blog Platform → Post Navigation Verification #BP_POSTNAV_0001\n* Objective: Verify prev/next navigation works correctly.\n* Test Steps:\n - TS1: Navigate to middle week → Expect both prev and next links\n - TS2: Click Previous → Expect navigates to prior week\n - TS3: Click Next → Expect navigates to following week\n - TS4: Navigate to Week 1 → Expect NO previous link\n - TS5: Navigate to latest week → Expect NO next link\n* Edge Cases:\n - Single published week → No navigation links\n\nTECH_REQ: [BP_SESSION_0001] - Blog Platform → Session Log Links #BP029\n* Post template SHALL include link to session log.\n* Link SHALL point to GitHub Wiki page for that week.\n* URL pattern: `https://github.com/\u003cowner\u003e/\u003crepo\u003e/wiki/Week-XX-Session-Log`\n* Link SHALL be labeled clearly (e.g., "View Session Log").\n* Link position: After post content, before comments section.\n* Hugo front matter MAY override default wiki URL.\n* References:\n + GitHub Wiki URLs\n\nSYSTEST: [BP_SESSION_TEST_0001] - Blog Platform → Session Log Link Verification #BP_SESSION_0001\n* Objective: Verify session log links are correct.\n* Test Steps:\n - TS1: Navigate to blog post → Expect session log link visible\n - TS2: Verify link label → Expect descriptive text\n - TS3: Click link → Expect opens correct wiki page\n - TS4: Verify wiki content → Expect relates to that week\n* Link Validation:\n - Verify HTTP 200 response from wiki URL\n\nTECH_REQ: [BP_REPO_0001] - Blog Platform → Repository Links #BP030\n* Post template SHALL include link to repository/code.\n* Link SHALL point to GitHub repository or specific directory.\n* URL pattern: `https://github.com/\u003cowner\u003e/\u003crepo\u003e` or subdirectory.\n* Hugo front matter `repo_url` SHALL allow custom repository links.\n* Link SHALL be labeled clearly (e.g., "View Code", "GitHub Repository").\n* References:\n + Hugo Front Matter\n\nSYSTEST: [BP_REPO_TEST_0001] - Blog Platform → Repository Link Verification #BP_REPO_0001\n* Objective: Verify repository links are correct.\n* Test Steps:\n - TS1: Navigate to blog post → Expect repo link visible\n - TS2: Verify link label → Expect descriptive text\n - TS3: Click link → Expect opens correct GitHub repo\n - TS4: Verify repo content → Expect relates to week’s project\n* Link Validation:\n - Verify HTTP 200 response from repo URL\n\n### SEO and Discovery (BP031, BP032, BP033, BP034, BP035, BP036, BP037)\n\nTECH_REQ: [BP_RSS_0001] - Blog Platform → RSS Feed Implementation #BP031\n* Hugo SHALL generate RSS feed automatically.\n* Feed SHALL be accessible at `/blog/index.xml`.\n* Configuration in `hugo.toml`:\n ```toml\n [outputs]\n home = ["HTML", "RSS"]\n section = ["HTML", "RSS"]\n ```\n* Feed SHALL include: title, link, description, pubDate for each item.\n* Feed SHALL validate against RSS 2.0 specification.\n* References:\n + Hugo RSS Templates\n\nSYSTEST: [BP_RSS_TEST_0001] - Blog Platform → RSS Feed Verification #BP_RSS_0001\n* Objective: Verify RSS feed is valid and complete.\n* Test Steps:\n - TS1: Navigate to `/blog/index.xml` → Expect valid XML\n - TS2: Validate with W3C Feed Validator → Expect no errors\n - TS3: Verify items → Expect all published posts included\n - TS4: Test in RSS reader → Expect feed parseable\n - TS5: Check item fields → title, link, description, pubDate present\n* References:\n + W3C Feed Validator\n\nTECH_REQ: [BP_SEO_0001] - Blog Platform → Basic Meta Tags #BP032\n* All pages SHALL include `\u003ctitle\u003e` and `\u003cmeta name="description"\u003e` tags.\n* Hugo template SHALL generate from front matter or defaults.\n* Title pattern: `\u003cPage Title\u003e | 52 Vibes`\n* Description: From front matter `description` or auto-generated summary.\n* Meta tags SHALL be in `\u003chead\u003e` section.\n* References:\n + Hugo SEO\n\nSYSTEST: [BP_SEO_TEST_0001] - Blog Platform → Basic Meta Tags Verification #BP_SEO_0001\n* Objective: Verify SEO meta tags on all pages.\n* Test Steps:\n - TS1: View page source → Expect `\u003ctitle\u003e` tag\n - TS2: Verify title format → Expect pattern `\u003cPage\u003e | 52 Vibes`\n - TS3: Check description meta → Expect relevant content\n - TS4: Test multiple page types → Expect consistent structure\n* Uniqueness:\n - Each page SHOULD have unique title and description\n\nTECH_REQ: [BP_OG_0001] - Blog Platform → Open Graph Meta Tags #BP033\n* All pages SHALL include Open Graph meta tags.\n* Required tags:\n - `og:title`: Page title\n - `og:description`: Page description\n - `og:image`: Social card image URL\n - `og:url`: Canonical page URL\n - `og:type`: "article" for posts, "website" for others\n* Hugo internal template MAY be used: `{{ template "_internal/opengraph.html" . }}`\n* References:\n + Open Graph Protocol\n\nSYSTEST: [BP_OG_TEST_0001] - Blog Platform → Open Graph Verification #BP_OG_0001\n* Objective: Verify Open Graph tags for social sharing.\n* Test Steps:\n - TS1: View page source → Expect `og:title` meta tag\n - TS2: Verify `og:description` → Expect content\n - TS3: Verify `og:image` → Expect valid URL\n - TS4: Verify `og:url` → Expect canonical URL\n - TS5: Verify `og:type` → "article" for posts\n - TS6: Test with Facebook Debugger → Expect preview renders\n* References:\n + Facebook Sharing Debugger\n\nTECH_REQ: [BP_TWITTER_0001] - Blog Platform → Twitter Card Meta Tags #BP034\n* All pages SHALL include Twitter Card meta tags.\n* Required tags:\n - `twitter:card`: "summary_large_image"\n - `twitter:title`: Page title\n - `twitter:description`: Page description\n - `twitter:image`: Social card image URL\n* Hugo internal template MAY be used: `{{ template "_internal/twitter_cards.html" . }}`\n* References:\n + Twitter Cards\n\nSYSTEST: [BP_TWITTER_TEST_0001] - Blog Platform → Twitter Card Verification #BP_TWITTER_0001\n* Objective: Verify Twitter Card tags.\n* Test Steps:\n - TS1: View page source → Expect `twitter:card` meta tag\n - TS2: Verify card type → "summary_large_image"\n - TS3: Verify `twitter:title` → Expect content\n - TS4: Verify `twitter:description` → Expect content\n - TS5: Verify `twitter:image` → Expect valid URL\n* Image:\n - Verify image dimensions meet Twitter requirements (min 300x157)\n\nTECH_REQ: [BP_SITEMAP_0001] - Blog Platform → XML Sitemap #BP035\n* Hugo SHALL generate sitemap automatically.\n* Sitemap SHALL be at `/sitemap.xml`.\n* Configuration in `hugo.toml`:\n ```toml\n [sitemap]\n changeFreq = "weekly"\n priority = 0.5\n ```\n* Sitemap SHALL include all public pages.\n* `\u003clastmod\u003e` dates SHALL be populated from Git info or front matter.\n* References:\n + Hugo Sitemap\n\nSYSTEST: [BP_SITEMAP_TEST_0001] - Blog Platform → Sitemap Verification #BP_SITEMAP_0001\n* Objective: Verify sitemap is valid and complete.\n* Test Steps:\n - TS1: Navigate to `/sitemap.xml` → Expect valid XML\n - TS2: Validate structure → Expect valid sitemap schema\n - TS3: Count URLs → Expect matches page count\n - TS4: Verify `\u003clastmod\u003e` → Expect dates present\n - TS5: Submit to validator → Expect no errors\n* References:\n + Sitemap Validator\n\nTECH_REQ: [BP_JSONLD_0001] - Blog Platform → JSON-LD Structured Data #BP036\n* Blog posts SHALL include JSON-LD structured data.\n* Schema type: `Article` (or `BlogPosting`).\n* Required fields:\n - `headline`: Post title\n - `datePublished`: ISO 8601 date\n - `dateModified`: ISO 8601 date\n - `author`: Author information\n - `publisher`: Site information\n* JSON-LD SHALL be in `\u003cscript type="application/ld+json"\u003e` tag.\n* References:\n + Schema.org Article\n + Google Structured Data\n\nSYSTEST: [BP_JSONLD_TEST_0001] - Blog Platform → JSON-LD Verification #BP_JSONLD_0001\n* Objective: Verify JSON-LD structured data.\n* Test Steps:\n - TS1: View page source → Expect `\u003cscript type="application/ld+json"\u003e`\n - TS2: Parse JSON → Expect valid JSON\n - TS3: Verify @type → Expect "Article" or "BlogPosting"\n - TS4: Verify headline → Expect post title\n - TS5: Verify datePublished → Expect ISO 8601 format\n - TS6: Test with Google Rich Results → Expect validation passes\n* References:\n + Google Rich Results Test\n\nTECH_REQ: [BP_SOCIAL_0001] - Blog Platform → Social Card Image Generation #BP037\n* Social card images SHALL be generated at build time using Hugo.\n* Hugo image processing SHALL create cards from template.\n* Image dimensions: 1200x630 pixels (recommended for social).\n* Card content: Week number, post title, quarter theme.\n* Card design: Gruvbox colors, consistent branding.\n* Output location: Same directory as post or `/images/cards/`.\n* References:\n + Hugo Image Processing\n\nSYSTEST: [BP_SOCIAL_TEST_0001] - Blog Platform → Social Card Image Verification #BP_SOCIAL_0001\n* Objective: Verify social card images are generated correctly.\n* Test Steps:\n - TS1: Build site → Check for card images in output\n - TS2: Verify dimensions → Expect ~1200x630\n - TS3: Verify content → Week number, title visible\n - TS4: Verify `og:image` points to card → Expect valid URL\n - TS5: Load image URL directly → Expect image displays\n* Visual:\n - Cards use Gruvbox colors\n - Text is readable\n\n### Engagement (BP038, BP039)\n\nTECH_REQ: [BP_DISCUSS_0001] - Blog Platform → GitHub Discussion Links #BP038\n* Post template SHALL include link to GitHub Discussions.\n* Link SHALL point to specific discussion thread for that post.\n* URL pattern: `https://github.com/\u003cowner\u003e/\u003crepo\u003e/discussions/\u003cid\u003e`\n* Hugo front matter `discussion_id` SHALL specify thread ID.\n* Link label: "Join Discussion" or "Comments on GitHub".\n* References:\n + GitHub Discussions\n\nSYSTEST: [BP_DISCUSS_TEST_0001] - Blog Platform → Discussion Link Verification #BP_DISCUSS_0001\n* Objective: Verify discussion links are correct.\n* Test Steps:\n - TS1: Navigate to blog post → Expect discussion link visible\n - TS2: Verify link label → Expect descriptive text\n - TS3: Click link → Expect opens specific discussion thread\n - TS4: Verify NOT generic discussions page → Expect specific thread\n\nTECH_REQ: [BP_DISCUSS_0002] - Blog Platform → Discussion Deep Linking #BP039\n* Discussion links SHALL navigate to specific threads, not index.\n* Each post SHALL have dedicated discussion thread.\n* Thread creation MAY be manual or automated via GitHub Actions.\n* Link URL SHALL include discussion ID or number.\n* References:\n + GitHub Discussions API\n\nSYSTEST: [BP_DISCUSS_TEST_0002] - Blog Platform → Deep Link Verification #BP_DISCUSS_0002\n* Objective: Verify discussion links go to specific threads.\n* Test Steps:\n - TS1: Click discussion link → Verify URL contains discussion ID\n - TS2: Verify page content → Expect discussion about that post\n - TS3: Test multiple posts → Each has unique discussion\n\n### Accessibility (BP040, BP041, BP042, BP043, BP044, BP045)\n\nTECH_REQ: [BP_A11Y_0001] - Blog Platform → Semantic HTML Structure #BP040\n* Document structure SHALL use semantic HTML5 elements.\n* Required landmark elements:\n - `\u003cheader\u003e` for site header\n - `\u003cnav\u003e` for navigation regions (with aria-label if multiple)\n - `\u003cmain\u003e` for primary content (exactly one per page)\n - `\u003carticle\u003e` for blog post content\n - `\u003caside\u003e` for supplementary content (TOC, sidebars)\n - `\u003cfooter\u003e` for site footer\n* Heading hierarchy SHALL be logical (h1 → h2 → h3, no skipping).\n* Each page SHALL have exactly one `\u003ch1\u003e` element.\n* References:\n + WCAG 1.3.1 Info and Relationships\n\nSYSTEST: [BP_A11Y_TEST_0001] - Blog Platform → Semantic HTML Verification #BP_A11Y_0001\n* Objective: Verify semantic HTML structure.\n* Test Steps:\n - TS1: Inspect DOM → Expect `\u003cheader\u003e`, `\u003cmain\u003e`, `\u003cfooter\u003e` landmarks\n - TS2: Count `\u003cmain\u003e` elements → Expect exactly 1\n - TS3: Count `\u003ch1\u003e` elements → Expect exactly 1 per page\n - TS4: Verify heading hierarchy → Expect no skipped levels\n - TS5: Run axe accessibility audit → Expect no landmark errors\n* Screen Reader:\n - Navigate by landmarks → Expect all regions identifiable\n\nTECH_REQ: [BP_A11Y_0002] - Blog Platform → Image Alt Text #BP041\n* All `\u003cimg\u003e` elements SHALL have `alt` attribute.\n* Alt text SHALL be descriptive and contextually appropriate.\n* Decorative images SHALL use empty alt (`alt=""`) and `role="presentation"`.\n* Alt text SHALL NOT begin with "image of" or "picture of".\n* Hugo shortcodes for images SHALL require alt parameter.\n* References:\n + WCAG 1.1.1 Non-text Content\n\nSYSTEST: [BP_A11Y_TEST_0002] - Blog Platform → Image Alt Text Verification #BP_A11Y_0002\n* Objective: Verify all images have appropriate alt text.\n* Test Steps:\n - TS1: Inspect all `\u003cimg\u003e` elements → Expect `alt` attribute present\n - TS2: Verify alt content → Expect descriptive, not generic\n - TS3: Check decorative images → Expect `alt=""` or `role="presentation"`\n - TS4: Run axe audit → Expect no missing alt errors\n* Content:\n - Alt text describes image function/purpose\n - No "image of" or "photo of" prefix\n\nTECH_REQ: [BP_A11Y_0003] - Blog Platform → Skip Navigation Link #BP042\n* A skip link SHALL be the first focusable element on each page.\n* Link text: "Skip to content" or "Skip to main content".\n* Link SHALL target `\u003cmain\u003e` element or equivalent.\n* Skip link SHALL be visually hidden until focused.\n* CSS pattern:\n ```css\n .skip-link {\n position: absolute;\n left: -9999px;\n }\n .skip-link:focus {\n left: 0;\n top: 0;\n /* visible styling /\n }\n ```\n References:\n + WCAG 2.4.1 Bypass Blocks\n\nSYSTEST: [BP_A11Y_TEST_0003] - Blog Platform → Skip Link Verification #BP_A11Y_0003\n* Objective: Verify skip link functionality.\n* Test Steps:\n - TS1: Load page, press Tab → Expect skip link is first focusable\n - TS2: Verify link visibility → Hidden by default\n - TS3: Focus skip link → Expect becomes visible\n - TS4: Activate skip link → Expect focus moves to main content\n - TS5: Verify target → Expect `\u003cmain\u003e` or content area\n* Visual:\n - Skip link visible and styled when focused\n\nTECH_REQ: [BP_A11Y_0004] - Blog Platform → Keyboard Navigation #BP043\n* All interactive elements SHALL be keyboard accessible.\n* Focus order SHALL follow logical reading order.\n* Focus indicator SHALL be visible on all focusable elements.\n* No keyboard traps SHALL exist.\n* Custom interactive elements SHALL implement proper keyboard handlers.\n* Tab order SHALL NOT require custom `tabindex` values except for skip link.\n* References:\n + WCAG 2.1.1 Keyboard\n + WCAG 2.4.7 Focus Visible\n\nSYSTEST: [BP_A11Y_TEST_0004] - Blog Platform → Keyboard Navigation Verification #BP_A11Y_0004\n* Objective: Verify complete keyboard accessibility.\n* Test Steps:\n - TS1: Navigate entire page with Tab → Expect all elements reachable\n - TS2: Verify focus visible → Expect ring/outline on focused elements\n - TS3: Activate links with Enter → Expect navigation works\n - TS4: Activate buttons with Enter/Space → Expect activation\n - TS5: Check for keyboard traps → Expect can always Tab away\n - TS6: Verify logical order → Expect follows reading order\n* Elements to Test:\n - Navigation links\n - TOC links\n - Theme toggle\n - External links\n\nTECH_REQ: [BP_A11Y_0005] - Blog Platform → Color Contrast #BP044\n* Text contrast SHALL meet WCAG 2.1 AA standards.\n* Normal text: minimum 4.5:1 contrast ratio.\n* Large text (18pt+ or 14pt bold): minimum 3:1 contrast ratio.\n* Contrast requirements SHALL be met in both themes.\n* UI components and graphics: minimum 3:1 contrast ratio.\n* References:\n + WCAG 1.4.3 Contrast (Minimum)\n\nSYSTEST: [BP_A11Y_TEST_0005] - Blog Platform → Color Contrast Verification #BP_A11Y_0005\n* Objective: Verify WCAG AA contrast compliance.\n* Test Steps:\n - TS1: Run Lighthouse accessibility (dark theme) → Expect no contrast failures\n - TS2: Run Lighthouse accessibility (light theme) → Expect no contrast failures\n - TS3: Check body text contrast → Expect ≥4.5:1\n - TS4: Check link contrast → Expect distinguishable and ≥4.5:1\n - TS5: Check code block contrast → Expect readable\n - TS6: Check border contrast → Expect ≥3:1\n* Tools:\n - axe DevTools\n - Colour Contrast Analyser\n - Lighthouse\n\nTECH_REQ: [BP_A11Y_0006] - Blog Platform → Reading Order #BP045\n* DOM order SHALL match visual reading order.\n* Content SHALL be readable with CSS disabled.\n* Flexbox/grid visual reordering SHALL NOT break reading order.\n* Screen readers SHALL announce content in logical sequence.\n* References:\n + WCAG 1.3.2 Meaningful Sequence\n\nSYSTEST: [BP_A11Y_TEST_0006] - Blog Platform → Reading Order Verification #BP_A11Y_0006\n* Objective: Verify logical reading order.\n* Test Steps:\n - TS1: Disable CSS → Expect content readable in order\n - TS2: Read page top to bottom → Expect logical sequence\n - TS3: Test with screen reader → Expect correct announcement order\n - TS4: Verify in lynx → Expect content order matches expectation\n* Sequence:\n - Header → Navigation → Main content → Footer\n\n### Content Authoring (BP046, BP047, BP048, BP049)\n\nTECH_REQ: [BP_MD_0001] - Blog Platform → Markdown Authoring Format #BP046\n* Blog posts SHALL be authored in Markdown format.\n* Hugo SHALL use Goldmark parser (default).\n* Configuration in `hugo.toml`:\n ```toml\n [markup.goldmark]\n [markup.goldmark.renderer]\n unsafe = true # if HTML in markdown needed\n ```\n* Front matter format: YAML (preferred) or TOML.\n* File extension: `.md`\n* References:\n + Hugo Markdown Configuration\n\nSYSTEST: [BP_MD_TEST_0001] - Blog Platform → Markdown Authoring Verification #BP_MD_0001\n* Objective: Verify Markdown authoring workflow.\n* Test Steps:\n - TS1: Create `.md` file in content directory → Build succeeds\n - TS2: Use standard Markdown syntax → Renders correctly\n - TS3: Use YAML front matter → Metadata parsed correctly\n - TS4: Test Markdown features → Headings, lists, links, images, code\n* Features:\n - Tables, footnotes, task lists (if enabled)\n\nTECH_REQ: [BP_CODE_0001] - Blog Platform → Syntax Highlighting #BP047\n* Code blocks SHALL display syntax highlighting.\n* Hugo Chroma highlighter SHALL be used (built-in).\n* Language specification via fenced code blocks: ```language\n* Configuration in `hugo.toml`:\n ```toml\n [markup.highlight]\n style = "gruvbox" # or custom Gruvbox-compatible style\n lineNos = false\n codeFences = true\n guessSyntax = true\n ```\n* Supported languages: Go, JavaScript, Python, Bash, JSON, YAML, HTML, CSS.\n* Highlighting SHALL work in both themes.\n* References:\n + Hugo Syntax Highlighting\n\nSYSTEST: [BP_CODE_TEST_0001] - Blog Platform → Syntax Highlighting Verification #BP_CODE_0001\n* Objective: Verify code syntax highlighting.\n* Test Steps:\n - TS1: Create post with ```go code block → Build site\n - TS2: Verify syntax colors → Expect keywords highlighted\n - TS3: Test multiple languages → Go, JS, Python, Bash, JSON\n - TS4: Test dark theme → Expect readable highlighting\n - TS5: Test light theme → Expect readable highlighting\n* Edge Cases:\n - Unspecified language (```) → Graceful handling\n - Unknown language → Graceful fallback\n\nTECH_REQ: [BP_CALLOUT_0001] - Blog Platform → Callout Boxes #BP048\n* Posts SHALL support callout boxes for tips, warnings, notes.\n* Implementation using Hugo shortcodes:\n ```\n {{\u003c callout type="tip" \u003e}}\n Callout content here.\n {{\u003c /callout \u003e}}\n ```\n* Types: tip, note, warning, important.\n* Callouts SHALL be visually distinct by type.\n* Callouts SHALL be readable in CLI browsers (content preserved).\n* References:\n + Hugo Shortcodes\n\nSYSTEST: [BP_CALLOUT_TEST_0001] - Blog Platform → Callout Boxes Verification #BP_CALLOUT_0001\n* Objective: Verify callout styling and functionality.\n* Test Steps:\n - TS1: Create post with tip callout → Expect distinct styling\n - TS2: Create warning callout → Expect different from tip\n - TS3: Test all types → tip, note, warning, important\n - TS4: Test in CLI browser → Expect content readable\n - TS5: Test in both themes → Expect visible styling\n\nTECH_REQ: [BP_PREVIEW_0001] - Blog Platform → Local Preview #BP049\n* Hugo local server SHALL support live preview.\n* Command: `hugo server -D` (include drafts).\n* Server SHALL watch for file changes and reload.\n* Local URL: `http://localhost:1313/`.\n* Documentation SHALL include preview instructions in README.\n* References:\n + Hugo Server\n\nSYSTEST: [BP_PREVIEW_TEST_0001] - Blog Platform → Local Preview Verification #BP_PREVIEW_0001\n* Objective: Verify local development workflow.\n* Test Steps:\n - TS1: Run `hugo server -D` → Expect server starts\n - TS2: Access localhost:1313 → Expect site renders\n - TS3: Modify post content → Expect live reload\n - TS4: Compare to production → Expect visual parity\n* Documentation:\n - README includes preview instructions\n\n### Analytics (BP050)\n\nTECH_REQ: [BP_ANALYTICS_0001] - Blog Platform → Server-Side Analytics #BP050\n* Site SHOULD use Cloudflare Analytics (server-side).\n* No client-side analytics scripts SHALL be embedded.\n* Analytics SHALL be enabled in Cloudflare dashboard.\n* This is a SHOULD requirement; implementation is optional.\n* References:\n + Cloudflare Web Analytics\n\nSYSTEST: [BP_ANALYTICS_TEST_0001] - Blog Platform → Analytics Verification #BP_ANALYTICS_0001\n* Objective: Verify server-side analytics (if implemented).\n* Test Steps (if implemented):\n - TS1: Check Cloudflare dashboard → Expect analytics section\n - TS2: View page source → Expect NO analytics scripts\n - TS3: Search for tracking code → Expect none in HTML\n* Note: SHOULD requirement; document if not implemented\n\n### Community Page API (BP051, BP052, BP053, BP054, BP055)\n\nTECH_REQ: [BP_API_0001] - Blog Platform → GitHub API Integration #BP051\n* Community page JavaScript SHALL fetch repositories from GitHub API.\n* API endpoint: `https://api.github.com/search/repositories?q=topic:52vibes`\n* Request SHALL be unauthenticated (public API, 60 requests/hour limit).\n* Fetch SHALL occur on page load (deferred, non-blocking).\n* References:\n + GitHub Search API\n\nSYSTEST: [BP_API_TEST_0001] - Blog Platform → API Integration Verification #BP_API_0001\n* Objective: Verify GitHub API fetch works.\n* Test Steps:\n - TS1: Navigate to `/community/` → Expect API fetch in Network tab\n - TS2: Verify endpoint → Expect correct GitHub Search URL\n - TS3: Verify response → Expect JSON with repository data\n - TS4: Verify topic filter → Expect only 52vibes tagged repos\n\nTECH_REQ: [BP_API_0002] - Blog Platform → Repository Display #BP052\n* Each repository listing SHALL display:\n - Repository name (linked to GitHub repo)\n - Description (if available)\n - Star count\n* Template for repository card:\n ```html\n \u003cdiv class="repo-card"\u003e\n \u003ca href="{repo.html_url}"\u003e{repo.full_name}\u003c/a\u003e\n \u003cp\u003e{repo.description || "No description"}\u003c/p\u003e\n \u003cspan\u003e★ {repo.stargazers_count}\u003c/span\u003e\n \u003c/div\u003e\n ```\n* References:\n + GitHub Repository Object\n\nSYSTEST: [BP_API_TEST_0002] - Blog Platform → Repository Display Verification #BP_API_0002\n* Objective: Verify repository information display.\n* Test Steps:\n - TS1: View repository card → Expect name displayed\n - TS2: Click repository name → Expect opens correct GitHub repo\n - TS3: Verify description → Expect shown (or "No description")\n - TS4: Verify star count → Expect number displayed\n\nTECH_REQ: [BP_API_0003] - Blog Platform → API Error Handling #BP053\n* API failures SHALL display fallback content.\n* Fallback: Link to `https://github.com/topics/52vibes`.\n* No error messages or stack traces SHALL be shown to users.\n* JavaScript SHALL catch fetch errors gracefully.\n* References:\n + Fetch API Error Handling\n\nSYSTEST: [BP_API_TEST_0003] - Blog Platform → Error Handling Verification #BP_API_0003\n* Objective: Verify graceful API error handling.\n* Test Steps:\n - TS1: Block GitHub API (DevTools) → Expect fallback displayed\n - TS2: Verify fallback link → Expect `https://github.com/topics/52vibes`\n - TS3: Verify no error message → Expect user-friendly text\n - TS4: Check console → Expect no unhandled errors visible to user\n\nTECH_REQ: [BP_API_0004] - Blog Platform → Empty State Handling #BP054\n* When API returns zero repositories, display friendly message.\n* Message SHALL encourage community participation.\n* Message SHALL include instructions for adding 52vibes topic.\n* Empty state SHALL NOT appear as error condition.\n* References:\n + Empty State UX Patterns\n\nSYSTEST: [BP_API_TEST_0004] - Blog Platform → Empty State Verification #BP_API_0004\n* Objective: Verify empty state message.\n* Test Steps:\n - TS1: Mock empty API response → Navigate to community\n - TS2: Verify message → Expect friendly, encouraging text\n - TS3: Verify instructions → Expect guidance for adding topic\n - TS4: Verify NOT error → Expect positive framing\n\nTECH_REQ: [BP_API_0005] - Blog Platform → API Response Caching #BP055\n* API responses SHOULD be cached in localStorage.\n* Cache key: `52vibes_community_repos`.\n* Cache duration: 5 minutes (300,000 ms).\n* Cache structure:\n ```javascript\n {\n timestamp: Date.now(),\n data: responseData\n }\n ```\n* On page load: check cache, use if valid, else fetch.\n* This is a SHOULD requirement; implementation is optional.\n* References:\n + localStorage API\n\nSYSTEST: [BP_API_TEST_0005] - Blog Platform → Caching Verification #BP_API_0005\n* Objective: Verify API caching (if implemented).\n* Test Steps (if implemented):\n - TS1: Navigate to community → Observe API request\n - TS2: Inspect localStorage → Expect cache key present\n - TS3: Refresh immediately → Expect NO new API request\n - TS4: Wait 5 minutes → Refresh → Expect new API request\n\n### Branding (BP056, BP057)\n\nTECH_REQ: [BP_BRAND_0001] - Blog Platform → Site Branding Display #BP056\n* "52 VIBES" branding SHALL be prominently displayed in header.\n* Branding SHALL be outside/above tmux-style frame.\n* Branding SHALL use site title from Hugo config.\n* Branding SHALL be visible on all pages.\n* Branding SHALL be readable on mobile viewports.\n* Font size: Larger than body text, consistent with design system.\n* References:\n + Hugo Site Variables\n\nSYSTEST: [BP_BRAND_TEST_0001] - Blog Platform → Branding Verification #BP_BRAND_0001\n* Objective: Verify site branding display.\n* Test Steps:\n - TS1: Navigate to any page → Expect "52 VIBES" visible\n - TS2: Verify position → Outside/above tmux frame\n - TS3: Test multiple pages → Expect consistent branding\n - TS4: Test mobile viewport → Expect readable\n - TS5: Test both themes → Expect visible\n\nTECH_REQ: [BP_BRAND_0002] - Blog Platform → Consistent Header #BP057\n* Header layout SHALL be identical on all pages.\n* Header elements: Branding, week status bar, (optional) theme toggle.\n* Header SHALL be rendered by Hugo partial template.\n* Header position SHALL not shift between pages.\n* Header component file: `layouts/partials/header.html`.\n* References:\n + Hugo Partial Templates\n\nSYSTEST: [BP_BRAND_TEST_0002] - Blog Platform → Header Consistency Verification #BP_BRAND_0002\n* Objective: Verify header consistency across pages.\n* Test Steps:\n - TS1: Navigate to blog index → Capture header appearance\n - TS2: Navigate to blog post → Compare header → Expect identical\n - TS3: Navigate to About → Compare header → Expect identical\n - TS4: Navigate to Community → Compare header → Expect identical\n - TS5: Test mobile viewport → Expect consistent header\n",“id”:“20260105125854”,“path”:"./notes/20260105125854/README.md",“project”:“52vibes”,“title”:“Week 1: Technical Requirements - Blog Platform (BP-TECH)”}`AI: The BP-TECH document is comprehensive. I’ll use the correct
TECHREQformat for CX-TECH and SL-TECH. Let me add the crush-export technical requirements.TOOL-CALL: mcp_note_update_note
{"new_content":"## Technical Requirements\n\n### Core Implementation (CX001)\n\nTECHREQ: [CX_DB_0001] - crush-export \u2192 SQLite Database Connection #CX001\n* Tool SHALL connect to Crush SQLite database at specified path.\n* Default database path:.crush/crush.db\n* SQLite library:modernc.org/sqlite(pure Go, no CGO).\n* Connection SHALL use read-only mode to prevent data corruption.\n* Tool SHALL validate database exists before attempting connection.\n* Error handling SHALL provide clear...TOOL:
{"message":"Updated note 20260105125856","success":true}AI: Now adding Session Log Sync (SL-TECH) technical requirements.
TOOL-CALL: mcp_note_update_note
{"new_content":"## Technical Requirements\n\n### Wiki Publication (SL001)\n\nTECHREQ: [SL_WIKI_0001] - Session Log Sync \u2192 GitHub Wiki Setup #SL001\n* GitHub repository SHALL have Wiki enabled.\n* Wiki SHALL be accessible athttps://github.com// /wiki .\n* Initial wiki structure SHALL include:\n - Home page with navigation\n - Sidebar with session log index\n* Session log pages SHALL be named:Week-XX-Session-Log.\n* References:\n + [GitHub Wiki Documentation](https://docs....TOOL:
{"message":"Updated note 20260105125859","success":true}AI: ## Summary
Created comprehensive technical requirements across all three products:
Product Tech Spec ID TECHREQ Count SYSTEST Count Blog Platform BP-TECH (20260105125854) ~60 ~60 crush-export CX-TECH (20260105125856) 10 10 Session Log Sync SL-TECH (20260105125859) 6 6 Key Technical Decisions Documented:
Blog Platform:
- Hugo v0.139+ (extended) with Cloudflare Pages
- CSS custom properties +
prefers-color-schemefor theming - Google Fonts CDN with
font-display: swap - Build-time social card generation
- localStorage caching (5-min TTL) for Community page
- WCAG 2.2 AA compliance target
crush-export:
- Go 1.21+ with
modernc.org/sqlite(pure Go, no CGO) - Standard library
flagpackage for CLI - GitHub-Flavored Markdown output
Session Log Sync:
- GitHub Actions with
GITHUB_TOKEN - Path-filtered triggers (
sessions/**) - Wiki repository direct manipulation
Note: I used
TECH_REQinstead ofTECHREQin the BP-TECH document (corrected in CX/SL). Should I fix the keyword format in BP-TECH via a batch replace?USER: I fixed it myself using bulk replace.
AI: Good. Technical requirements and system tests are now complete for all three products.
Next step: Mark the 65 REQ and 65 QA items as DONE since their corresponding TECHREQ and SYSTEST entries have been created.
Want me to proceed with updating those task statuses?
USER: Yes
TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"REQ","title":"[BP001]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"QA","title":"[BP_QA_001]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"REQ","title":"[BP002]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"QA","title":"[BP_QA_002]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"REQ","title":"[BP003]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"QA","title":"[BP_QA_003]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"REQ","title":"[BP004]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"QA","title":"[BP_QA_004]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"REQ","title":"[BP005]","new_keyword":"DONE"}TOOL-CALL: mcp_todo_update_task_status
{"project":"52vibes","keyword":"QA","title":"[BP_QA_005]","new_keyword":"DONE"}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}AI: BP001-BP005 done. Continuing…
TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP006]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_006]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP007]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_007]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP008]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_008]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP009]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_009]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP010]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_010]"}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}AI: BP006-BP010 done. Continuing…
TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP011]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_011]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP012]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_012]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP013]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_013]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP014]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_014]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP015]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_015]"}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}AI: BP011-BP015 done. Continuing…
TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP016]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_016]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP017]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_017]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP018]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_018]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP019]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_019]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"REQ","new_keyword":"DONE","project":"52vibes","title":"[BP020]"}TOOL-CALL: mcp_todo_update_task_status
{"keyword":"QA","new_keyword":"DONE","project":"52vibes","title":"[BP_QA_020]"}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: REQ → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}TOOL:
{"message":"Updated task status: QA → DONE","success":true,"valid_keywords":{"Active":["TODO","TASK","NOTE","REMINDER","EVENT","MEETING","CALL","EMAIL","MESSAGE","FOLLOWUP","REVIEW","CHECKIN","CHECKOUT","RESEARCH","READING","WRITING","DRAFT","FINALIZE","SUBMIT","PRESENTATION","NEED","VERIFY","REQ","QA"],"Completed":["ARCHIVED","CANCELED","DELETED","DONE","COMPLETED","CLOSED"],"InProgress":["DOING","INPROGRESS","WIP","WORKING","STARTED","WAITING","DEFERRED","DELEGATED"],"Someday":["SOMEDAY","MAYBE","LATER","FUTURE","WISHLIST"]}}