fullstack.rocks skills · demos

I reviewed the Orrisvane House homepage against the client profile, the design spec, and the agency accessibility checklist. I did not change any files. Image review covered the three chair frames, the orchard walk, the breakfast table, and the library. The hero, household portrait, suite, pool, and returning-books files are present, but they did not decode in this pass, so those alts were checked against the spec text only.

ID tag severity where finding fix
A1 a11y high examples/maison-lumen/sites/estate/index.html:151-167; examples/maison-lumen/clients/estate/assets/chair-condition.webp, chair-intervention.webp, chair-finished-detail.webp The alt text describes one walnut writing chair’s rear joint. All three photographs show the same bed: a side rail, an open tenon, and a square post. The middle frame is hands and a chisel with yellow adhesive on that bed joint. The alts fail SC 1.1.1 because they name the wrong object. Keep the three alt strings in design.md (The work of care). Replace the three files with portraits of one walnut writing chair, same rear joint, same grain, same viewpoint, 1000×1250. Condition: the joint has opened and the old surface is visible. Intervention: hands secure that original timber at the bench. Finished: the joint is closed and the old scratches remain. The desktop 1:1 crop and the mobile 3:2 crop must still show the joint.
U1 usability high examples/maison-lumen/sites/estate/index.html:146, :245-246 atelier.html, privacy.html, and accessibility.html are linked and missing. sites/estate/ contains only index.html, styles.css, and main.js. Every image path, styles.css, and main.js resolves. In-page ids #top, #main, #house-and-grounds, #life-here, #the-atelier, and #introduction exist. The mailto action works. Add three real pages beside index.html, each with the same skip link, masthead, and footer. Asset paths stay ../../clients/estate/assets/. Stylesheet is styles.css. Footer DOM order stays: wordmark and “A house to return to.”; “Near Porto Covo · Alentejo, Portugal”; mailto:iria@orrisvane.example; House information nav (Privacy, Accessibility); “A fictional house by Maison Lumen.” atelier.html: title “The atelier — Orrisvane House”; one h1; say the morning is optional, the bench sets the subject, and commissioned work is quoted separately. privacy.html: title “Privacy — Orrisvane House”; say this site does not store the email, and the guest decides which preference notes or inventoried belongings are kept, changed, or deleted. accessibility.html: title “Accessibility — Orrisvane House”; state the WCAG 2.2 AA target and that access needs go to Iria before a proposal, via mailto:iria@orrisvane.example. No forms, prices, or sent-message confirmation. On the homepage, point both “The Atelier” nav hrefs at atelier.html. On atelier.html only, add aria-current="page" to that nav link. Leave id="the-atelier" on the homepage section.
C1 copy high examples/maison-lumen/sites/estate/index.html:133, :145-167 The week sentence, the care heading block, and the three captions describe a walnut writing chair recorded on 4, 6, and 11 March 2026. The pictures are a bed. A sceptic comparing caption to photograph will reject the treatment record. That breaks the “exact” voice in profile section 6. The fictional-record note is required and stays. Keep every design.md sentence, including “Illustrative treatment record for this fictional house.” Do the photograph replacement in A1 so those sentences become true.
X1 ux high examples/maison-lumen/sites/estate/index.html:102, :117-124; examples/maison-lumen/clients/estate/assets/breakfast-table.webp, west-room-library.webp Breakfast is a sea-facing terrace: pergola, bougainvillea, juice, and the horizon behind the table. The library window shows a sea horizon beyond the trees. The copy says the estate is inland near Porto Covo and that coastal access is public and outside the grounds. design.md forbids implying a private beach. The breakfast plate reads as a holiday let. Keep both alt strings. Replace breakfast-table.webp with a courtyard breakfast for six: woven linen, bread, fruit, everyday ceramics, no sea, no logos. Replace or crop west-room-library.webp so the open window shows orchard trees and no sea horizon; book spines stay unreadable and unbranded.
A2 a11y medium examples/maison-lumen/sites/estate/styles.css:182-215; examples/maison-lumen/sites/estate/index.html:19-21, :211, :233-235 The wordmark, emblem, and arrow are <img> SVGs tinted with CSS filters. In forced-colors the filters are removed, and an external SVG stays black, so the footer wordmark and the estuary emblem can disappear on a dark high-contrast canvas. design.md asks for one file used via currentColor. Inline orrisvane-wordmark.svg, courtyard-emblem.svg, and arrow-right.svg. Delete the three --tint-* filters and the filter rules. Keep fill="currentColor". Header link: aria-label="Orrisvane House — home". Footer link: aria-label="Orrisvane House". aria-hidden="true" on each svg, and remove the svg aria-label / role="img". Let the header inherit ink and the footer and emblem inherit paper. Leave the arrow inside the link with no accessible name.
A3 a11y medium examples/maison-lumen/sites/estate/styles.css:192-195, :266-294 Below 1024 px the Menu control is absolutely positioned and the wordmark is at least 10rem wide with a 7rem right margin. At a 320 px viewport with the root font size at 32 px (200% text), that minimum plus the margin is wider than the content box, so the wordmark and Menu overlap. In the max-width: 1023px header rules, lay the masthead out as a wrapping flex row. Wordmark link: min-width: 0, flex: 1 1 auto, margin-right: 1rem, max-width: 100%. Wordmark: width: min(13.75rem, 100%). Nav closed: flex: 0 0 auto. Summary: position: static. Nav open: flex: 1 1 100% so the four links are a full-width stack in normal flow and push the page down. Test at 320 px CSS width with root font-size 32 px, and with WCAG text-spacing: no overlap, no horizontal scrollbar, wordmark and Menu both visible.
X2 ux medium examples/maison-lumen/sites/estate/styles.css:147-148, :319; examples/maison-lumen/sites/estate/index.html:45-62 Arrival has 96 px of bottom padding (64 px on small screens). Household is the first .section, so .section + .section does not remove its top padding. Paper sections that follow each other share one gap; this pair stacks two. The hero-to-household interval is 192 px desktop and 128 px mobile. Add .arrival + .section { padding-top: 0; }. Leave arrival’s bottom padding as the single shared gap.
X3 ux medium examples/maison-lumen/sites/estate/styles.css:551-552, :580; examples/maison-lumen/sites/estate/index.html:49 From 768–1023 px the hero is a 3/5 split, and the break after “house” is still on. The H1 is 64 px. “to return to.” does not fit in three of eight columns, so the designed two-line headline wraps again. design.md asks split sections to become equal halves where the copy fits. Inside the max-width: 1023px query, set .arrival__copy to grid-column: 1 / span 4 and .arrival__figure to grid-column: 5 / -1. Keep the <br class="desktop-break"> visible from 768 px up.
A4 a11y low examples/maison-lumen/sites/estate/main.js:9-16 #copy-status is a polite live region, and a second copy sets the same string. Screen readers stay silent on the repeat. On each click, set status.textContent = "", then in requestAnimationFrame set either “Email address copied.” or “Please select and copy iria@orrisvane.example.” Leave the button label as “Copy email address”.
X4 ux low examples/maison-lumen/sites/estate/styles.css:329-331, :396-398 Household and Returning put the photograph across two rows and the heading and body in different rows. The 3:2 image stretches the heading-to-body gap past the specified 24 px. Returning should be one top-aligned text block. Household should be one block, vertically centred. Add a .household__copy wrapper around .household__head and .household__body, and a .returning__copy wrapper the same way, leaving the figure or image between them in the DOM. Below 768 px set both wrappers to display: contents and give the image order: 2, the head order: 1, and the body order: 3. From 768 px up, make each wrapper one grid item (household columns 8–12, align-self: center; returning columns 7–12, align-self: start) and the image a single row (household columns 1–6; returning columns 1–6). Keep 24 px between heading and body inside the wrapper.
X5 ux low examples/maison-lumen/clients/estate/assets/estate-plan.svg:133-143 The plan has the required ink-on-stone labels (Estate boundary, Arrival road, Courtyard, Three suites, Library, Orchard, Gardens, 16 m pool) and a dashed ink boundary. Nothing outside that boundary shows the public coastline design.md asks for. The HTML text equivalent already says public coastal access lies beyond the grounds. Draw a coastline outside the dashed boundary. Label it “Public coast” in Source Sans 3, 32 px, ink #252C2A, on a solid stone #DDD5C8 plate. Leave out a beach, a private path to the water, and any distance to the sea. Keep the existing HTML text equivalent.
X6 ux low examples/maison-lumen/sites/estate/styles.css:154-158, :238-251, :299-306, :479-495, :514-522 The focus ring is immediate, 2 px, and above 3:1 (ink on paper, ink on stone, paper on estuary). The underline and colour still animate for 400 ms, because .site-nav a, .editorial-link, .button, and .dark-link override :focus-visible { transition: none } by order and specificity. The motion table says the focus underline appears in 0 ms. After those component rules, add .site-nav a:focus-visible, .editorial-link:focus-visible, .button:focus-visible, .dark-link:focus-visible, .wordmark-link:focus-visible { transition: none; }.

CSS text pairs in the six-token palette clear 4.5:1, including 12 px eyebrows; the tight pair is the atelier link, clay #8A4B38 on stone #DDD5C8 at 4.59:1. Headings, landmarks, skip link, reduced motion, and target sizes on the default layout hold, and there is no form: the invitation is a labelled mailto. The sentences match profile section 6, and “Request an introduction” opens the specified email, but the page is not shippable: three links 404, the care sequence names a chair the photographs show as a bed, and breakfast and the library show the sea the copy places outside the estate. Replace those photographs, add the three pages, then fix the header reflow, the doubled hero gap, and the inline-SVG colour.