← All components

Content · 9 of 13

TechnologyCard

Its gradient border is a masked pseudo-element — the technique that makes a gradient stroke possible around a transparent fill. Since the palette rebuild the stroke is violet end to end; the teal survives only in the card's 10% body wash.

Vue island src/components/homepage/technology-card.vue rendered live from compiled/technology-card.js mask-composite

Props

PropTypeNotes
name *stringBoth the label and the routing key — matched against six literal service names.
active *booleanLifts the card and reveals the CTA.
indexnumberOptional in the type, but indexes two six-element position tables unguarded.
classNamestringAppended last.

Stories

Mounted with real slots from the six-position table: the inactive card takes slot 0 (-rotate-4 left-2 top-10), the active card slot 3 (rotate-4 right-2 top-10). On an xl viewport the active card also lifts by a third.

Inactive active={false} index={0} className="w-72 h-72" The CTA is hidden below xl, and opacity-0 above it — present but invisible. The sizing comes entirely from className; the card has none of its own.
Active active={true} index={3} className="w-72 h-72" Lifts by a third (or a half for the bottom two slots) over 500ms and shows the tertiary "Explore service" Button — its href comes from the name switch, here /services/autodesk.

The border technique

Three layers doing one job. This is the only place in the system where the teal appears — --color-technology-gradient-0 (#077689), at 10% alpha inside the body wash. Pre-redesign the cyan #20EFFE was the stroke's middle stop; current brand-400 is #5F3ABD, so the stroke is violet end to end.

LayerValueRole
.card-wrappertechnology-gradient-25 → -0 → -50 (#1A0452 → #077689 → #070312), all at 10% alphaThe faint body wash — the teal's only appearance.
.cardbackdrop-filter: blur(14px)Frosts whatever sits behind, fill stays transparent.
.card::beforebrand-500 @35% → brand-400 @67.5% → brand-500 (#5F20FE / #5F3ABD)The gradient stroke, clipped to a 1px ring by mask-composite: subtract.

Findings

index is optional but indexed unguarded. The type is index?: number, yet the template evaluates rotate[index] and translate[index] directly. Omitting the prop yields rotate[undefined]undefined, which is interpolated into the class string as the literal text. Passing an index above 5 does the same. Neither table has a fallback — and the mobile carousel call site really does omit it (technologies.vue passes :index only on desktop).

Routing is a string match on display copy. getTechnologyUrl switches on the same name that is rendered to the user, returning '' for anything unmatched. So editing a service label — fixing capitalization, translating the site — silently turns the CTA into a link to the current page. The six names are duplicated here, in header/menu.ts, and in footer/links.ts.

The heading level is <h2> for a card title. Six of these render per homepage section, each emitting an h2 alongside the section's own heading. Same outline problem as ArticlePreview.

-webkit-mask-composite is absent from source. Only the standard mask-composite: subtract is declared. Where the prefixed pairing (-webkit-mask-composite: xor) is still required, the mask does not subtract and the pseudo-element fills solid, covering the card with a violet block instead of ringing it. The compiled component above ships the source CSS verbatim, so a browser that needs the prefix reproduces the bug rather than masking it.