User Profile Page
Technical Description
The profile page is driven by a three-step data-collection flow that kicks in the
moment the user clicks Start Profile. Each step has its own dedicated
function — runStep1(),
runStep2(), and
runStep3() — called sequentially inside a parent
startProfile() handler. The native
window.prompt() API collects each answer, storing
every response in a shared profile object.
Collected data is written straight to the DOM via
document.getElementById() and
element.textContent, revealing the three profile
cards as the user fills them in. The full object is then persisted with
localStorage.setItem() so the profile survives
page reloads. On first load the page attempts to restore any saved data using
JSON.parse(localStorage.getItem("profile")),
falling back to a clean default object if nothing exists yet.
Once all three steps complete, updateProgress()
counts every non-null answer across the maximum nine questions, calculates a
percentage, and injects both the numeric value and the visual fill into the
native HTML <progress> element. The bar is
styled with ::-webkit-progress-value and
::-moz-progress-bar pseudo-elements to render a
glowing cyan-to-gold gradient consistent with the site's shared design language.
Each card also exposes an Edit button that re-runs only its own prompt
sequence, letting users update any section without restarting the whole flow.
Structurally, the page uses CSS Flexbox to centre the main
profile container both horizontally and vertically within the viewport. The
glass-card effect is created with
backdrop-filter: blur() combined with a
semi-transparent
background: var(--c-surface-2) — the same
glassmorphism pattern used across the site so the page feels cohesive without
needing extra colour overrides.
Accessibility
-
Keyboard Navigation: All interactive elements —
Start Profile and each Edit button — are native
<button> elements, so they receive
focus and can be activated via keyboard without any extra
tabindex or
role attributes.
-
Progress Bar Semantics: The native
<progress value="" max="9"> element
exposes its numeric state to the accessibility tree automatically. An
adjacent <p id="progressText"> provides
a plain-text fallback ("Progress: 67%") for screen readers in browsers that
do not fully support the progress role.
-
Colour Contrast: Card text uses
var(--c-muted) on the dark glass background,
keeping the contrast ratio above the WCAG AA threshold of 4.5:1 for
normal-weight text.
-
Alt Text: The logo carries a descriptive
alt attribute, and all decorative elements
are either CSS-only or marked
aria-hidden="true".
Link to the validation page
Link to the page
Sitemap Page
Technical Description
Instead of a static image, the sitemap is built as inline SVG inside a
responsive viewBox="0 0 1100 750" container.
Every page in the site hierarchy is represented by a
<g class="node"> group that wraps a
rounded <rect rx="15"> and a centred
<text> label. Relationships between pages
are drawn with <line> elements connecting
the midpoints of parent and child nodes.
All colour values are resolved from CSS custom properties —
var(--c-surface-2),
var(--c-border),
var(--c-text) — so the diagram automatically
adapts if the shared theme changes. Hover states are handled purely in CSS:
the .node rect:hover rule shifts the stroke to
the gold accent colour, giving clear interactive feedback without any JavaScript
dependency. Each node's <a> wrapper makes
them clickable links to the real pages, doubling as a quick navigation aid.
Accessibility
-
SVG Accessibility: The root
<svg> element carries a descriptive
aria-label so assistive technologies can
identify its purpose. Individual node groups use
role="img" and their own
aria-label to name each page, allowing
screen-reader users to understand the site structure without any visual
reference.
-
Decorative Lines: The purely visual connector
<line> elements are wrapped in a
group marked aria-hidden="true" so they
do not clutter the accessibility tree with meaningless geometry.
-
Keyboard Navigation: Because each node wraps a native
<a> element, keyboard users can tab
through every page link in the diagram in natural document order.
Link to the validation page
Link to the page
Content Page (Student 4)
Technical Description
The Student 4 content page presents a research article on
Transparency Technology and SDG 16. The article sits inside a single
.article-container div styled with the site's
glassmorphism approach: a semi-transparent background, a hairline border via
var(--glass-border), rounded corners, and
backdrop-filter: blur(10px) for the frosted-glass
effect consistent across the site.
An in-page Table of Contents uses a styled
<nav> block with a coloured
border-left accent, and each anchor link uses the
CSS arrow entity → for a clean
typographic feel. Each of the four main
<section id=""> elements carries
scroll-margin-top: 100px to prevent the sticky
header from obscuring headings when jumping via anchor links.
Article images use the .styled-image class:
width: 100% keeps them responsive,
object-fit: cover maintains consistent
proportions, and a cubic-bezier transition produces a subtle lift-and-zoom on
hover. A fixed Back to Top button is implemented as a plain
<a href="#top"> with
position: fixed; bottom: 30px; right: 30px,
keeping it accessible at all times without requiring JavaScript.
Accessibility
-
Semantic Structure: The page uses
<article>,
<section>, and a
<nav> for the Table of Contents,
giving assistive technologies clear landmarks to navigate between.
-
Image Alt Text: Every
<img> carries a descriptive
alt attribute (e.g.
"Digital data visualisation representing open government data") so
screen-reader users receive meaningful context for each visual.
-
Back-to-Top Accessibility: The fixed button uses
aria-label="Back to top" so its purpose
is communicated to users relying on voice or screen readers rather than
the visible arrow character.
-
Colour Contrast: Body text uses
var(--text-muted) on the dark article
background and headings use var(--accent-cyan),
both meeting WCAG AA contrast requirements.
Link to the validation page
Link to the page
Challenges and Lessons Learned
Challenge 1 — prompt() Returns null, Not an Empty String
When building the profile data-collection flow I assumed pressing
Cancel on a window.prompt() dialogue
would return an empty string. It actually returns the JavaScript literal
null. My initial
if (name) guard correctly skipped the DOM update,
but JSON.stringify was quietly writing the string
"null" into localStorage — which then parsed back as the actual
null value on the next load, causing cards to
display "Name: null" on screen. I fixed this by evaluating the guard
before writing to the paragraph, and only incrementing the completion
counter for genuinely truthy answers. It taught me to treat every
user-cancellable dialogue as a potential source of harmful values that needs
explicit validation.
Challenge 2 — SVG Text Not Centring Consistently Across Browsers
My initial sitemap used only text-anchor="middle"
on node labels. Chrome rendered them perfectly, but Firefox placed text slightly
off-centre vertically. After checking the SVG specification I found that
vertical alignment also requires
dominant-baseline="middle" alongside
text-anchor="middle". Adding both attributes
fixed the inconsistency immediately — a useful reminder that SVG has its own
independent layout model separate from CSS flexbox.
Challenge 3 — Progress Bar Jumping to 100% on Skipped Questions
An early version of updateProgress() measured how
many steps had been triggered rather than how many individual answers
were actually provided. A user who pressed Cancel on every question still saw a
fully filled progress bar — completely misleading. I refactored the logic to
track three separate integer counters
(completed.step1,
completed.step2,
completed.step3), each only incremented for a
truthy answer, then divide the total by 9 for an accurate percentage.
Challenge 4 — SVG Line Coordinates Breaking After Repositioning Nodes
Rearranging the sitemap hierarchy meant every hardcoded
x1 / y1 / x2 / y2 coordinate in my connector
lines became wrong. After recalculating manually three times I developed a
systematic approach: sketch the full layout on paper with precise coordinates
before writing any SVG, so repositioning is planned upfront and the markup is
written correctly from the first draft rather than patched repeatedly.
Challenge 5 — localStorage Persisting Stale Data During Development
Whenever I renamed or restructured the
profile object, the browser kept restoring the
old shape from localStorage, causing
undefined values to appear in the DOM. I learned
to clear localStorage manually in DevTools between structural changes and added
a safe fallback on initialisation:
JSON.parse(localStorage.getItem("profile")) || {step1:{}, step2:{}, step3:{}}.
This ensures the app always starts from a valid structure, treating persisted
data as potentially untrusted.
Compliance
All three pages I authored are designed to be in full compliance with Janet's
Acceptable Use Policy and with relevant UK legal requirements for web publishing.
See the Janet compliance notes for full detail.
-
Content Appropriateness (Janet AUP): All content —
profile prompts, sitemap labels, and the SDG 16 research article — is
original, educational, and directly related to Peace & Justice themes.
No offensive, defamatory, or commercially promotional material appears on
any of my pages.
-
Data Privacy (GDPR / UK Data Protection Act 2018):
Profile data entered by users is stored exclusively in their own browser
via
localStorage. Nothing is transmitted to
any external server, meaning no personal data is processed by the site —
in line with the GDPR data minimisation principle.
-
No Third-Party Tracking: My pages load only the shared
style.css produced by the team and no
external CDN libraries, analytics scripts, or advertising code — consistent
with the Janet AUP requirement for ethical and lawful network use.
-
Accessibility (WCAG 2.1 AA / Equality Act 2010 / Public Sector
Bodies Accessibility Regulations 2018): Semantic HTML landmarks
(
<header>,
<nav>,
<main>,
<footer>,
<article>,
<section>) are used throughout. All
images carry descriptive alt text, all
interactive elements are keyboard-accessible, and text contrast meets the
WCAG AA 4.5:1 threshold. The inline SVG sitemap includes ARIA labels on
all meaningful nodes and marks decorative lines
aria-hidden="true".
-
Copyright Compliance: All images used were sourced from
royalty-free platforms or created specifically for this project. Every
technique and external reference is cited in the References section below
in Harvard referencing style, as required by the coursework brief.
-
Computer Misuse Act 1990 / NIS Regulations 2018:
No malicious code, unauthorised data collection, or network-abusive
behaviour is present on any page. The site is a static, read-only
educational resource with no server-side components.
Group Meetings and Individual Contribution Log
The following log documents my personal engagement with group work over the
course of the project. Each entry reflects my own account of what I contributed
rather than just summarising what the group did.
| Group Meetings and Contribution Log |
| Meeting |
Date & Time |
Format |
Objective |
Attended |
Your Individual Contribution |
| 1 |
12 Feb 2026 |
Face-to-Face |
Agree on SDG topic and assign roles. |
Yes |
I confirmed my role as Student 4, responsible for the User Profile
and Sitemap pages, and proposed using the native
<progress> element for the
profile completion tracker. |
| 2 |
19 Feb 2026 |
Online (Discord) |
Finalise theme and wireframe pages. |
Yes |
I shared my initial wireframe for the three-card profile layout and
the hierarchical sitemap structure, and received feedback to simplify
the SVG connector lines. |
| 3 |
26 Feb 2026 |
Hybrid |
Merge core pages and test routing. |
Yes |
I integrated profile.html and
sitemap.html into the shared
repository, confirmed all navigation links in the header and footer
were consistent, and resolved a CSS conflict with the global
button selector that was overriding
the team's shared styles. |
| 4 |
05 Mar 2026 |
Online (Discord) |
Team code review and bug fixing. |
Yes |
I identified and fixed the null-vs-empty-string bug in the profile
prompt flow and updated the localStorage initialisation to use a safe
fallback default object. |
| 5 |
12 Mar 2026 |
Face-to-Face |
Content review and alignment. |
Yes |
I updated the sitemap SVG to include the Profile page node (initially
omitted from the navigation branch) and verified all node labels
matched the final agreed page titles. |
| 6 |
18 Mar 2026 |
Hybrid |
Final W3C validation and packaging. |
Yes |
I ran profile.html,
sitemap.html, and
content_ST4.html through the W3C
Markup Validation Service, resolved two stray closing
</svg> tags, confirmed zero
errors across all three files, and took the required validation
screenshots. |
References
All technical documentation, guidelines, and sources consulted and applied
during the implementation of my three pages are listed below in Harvard style: