diff --git a/shapes/annotation.ttl b/shapes/annotation.ttl
new file mode 100644
index 0000000..d3958cb
--- /dev/null
+++ b/shapes/annotation.ttl
@@ -0,0 +1,111 @@
+@prefix dc: .
+@prefix dct: .
+@prefix oa: .
+@prefix prov: .
+@prefix rdf: .
+@prefix rdfs: .
+@prefix sh: .
+@prefix vs: .
+@prefix xsd: .
+
+@prefix annotation_shape: .
+
+annotation_shape:AnnotationShape
+ a sh:NodeShape ;
+ sh:targetClass oa:Annotation ;
+ sh:name "Annotation Shape" ;
+ sh:description "SHACL shape describing a Web Annotation covering common note, bookmark, comment, and highlight cases." ;
+ dct:created "2026-04-23"^^xsd:date ;
+ vs:term_status "testing" ;
+ dc:source ;
+ prov:wasDerivedFrom ;
+ dct:references ; # references the oa:Annotation class from the W3C Web Annotation Vocabulary, which is the expected type of an annotation node, together with the oa:hasBody, oa:hasTarget, oa:bodyValue, and oa:motivatedBy properties used to relate an annotation to its body, target, textual body content, and motivation respectively.
+ dct:references ; # references the W3C Web Annotation Data Model recommendation which defines the conceptual model used by the Web Annotation Vocabulary.
+ sh:codeIdentifier "Annotation";
+
+ # Type: an annotation should be typed as oa:Annotation.
+ sh:property [
+ sh:path rdf:type ;
+ sh:hasValue oa:Annotation ;
+ sh:name "Type" ;
+ sh:description "The RDF type of the annotation, which must include oa:Annotation." ;
+ sh:codeIdentifier "type";
+ ] ;
+
+ # Inline textual body (for simple comment / note cases).
+ # Per the Web Annotation Data Model (ยง3.2.4), an annotation SHOULD NOT
+ # have both oa:bodyValue and oa:hasBody. This shape does not enforce
+ # the exclusion (favouring interoperability) but consumers SHOULD
+ # populate only one of the two.
+ sh:property [
+ sh:path oa:bodyValue ;
+ sh:datatype xsd:string ;
+ sh:maxCount 1 ;
+ sh:name "Body Value" ;
+ sh:description "Textual content of the annotation body, used for plain-text comments or notes (Web Annotation Vocabulary, oa:bodyValue). SHOULD NOT be combined with oa:hasBody on the same annotation." ;
+ sh:codeIdentifier "bodyValue";
+ ] ;
+
+ # External or embedded body resource(s) (for richer body cases).
+ sh:property [
+ sh:path oa:hasBody ;
+ sh:nodeKind sh:BlankNodeOrIRI ;
+ sh:name "Body" ;
+ sh:description "A resource that provides the content of the annotation (Web Annotation Vocabulary, oa:hasBody). May be repeated when an annotation has multiple bodies. SHOULD NOT be combined with oa:bodyValue on the same annotation." ;
+ sh:codeIdentifier "hasBody";
+ ] ;
+
+ # Target(s) the annotation is about. Required for an annotation to be meaningful.
+ sh:property [
+ sh:path oa:hasTarget ;
+ sh:nodeKind sh:BlankNodeOrIRI ;
+ sh:minCount 1 ;
+ sh:name "Target" ;
+ sh:description "The resource (or specific resource) that the annotation is about (Web Annotation Vocabulary, oa:hasTarget)." ;
+ sh:codeIdentifier "hasTarget";
+ ] ;
+
+ # Motivation. Left open to the full Web Annotation motivation set so that
+ # the shape does not reject conforming annotations using motivations
+ # outside the common note-taking subset (e.g., oa:tagging, oa:replying).
+ # Apps focused on notes/bookmarks/highlights typically use oa:bookmarking,
+ # oa:commenting, or oa:highlighting.
+ sh:property [
+ sh:path oa:motivatedBy ;
+ sh:nodeKind sh:IRI ;
+ sh:name "Motivation" ;
+ sh:description "Why the annotation was created (Web Annotation Vocabulary, oa:Motivation). Common note-taking values are oa:bookmarking, oa:commenting, and oa:highlighting." ;
+ sh:codeIdentifier "motivatedBy";
+ ] ;
+
+ # Creator. Permits a WebID IRI or an embedded agent description, matching
+ # the Web Annotation Data Model which allows the creator to be referenced
+ # or described inline. Cardinality is left open as the data model permits
+ # multiple creators (co-creation).
+ sh:property [
+ sh:path dct:creator ;
+ sh:nodeKind sh:BlankNodeOrIRI ;
+ sh:name "Creator" ;
+ sh:description "The agent that created the annotation. Typically a WebID IRI in Solid, but the Web Annotation Data Model also permits an embedded agent description and multiple creators." ;
+ sh:codeIdentifier "creator";
+ ] ;
+
+ # Created date.
+ sh:property [
+ sh:path dct:created ;
+ sh:datatype xsd:dateTime ;
+ sh:maxCount 1 ;
+ sh:name "Created" ;
+ sh:description "The date and time at which the annotation was created." ;
+ sh:codeIdentifier "created";
+ ] ;
+
+ # Last modified date.
+ sh:property [
+ sh:path dct:modified ;
+ sh:datatype xsd:dateTime ;
+ sh:maxCount 1 ;
+ sh:name "Modified" ;
+ sh:description "The date and time at which the annotation was last modified." ;
+ sh:codeIdentifier "modified";
+ ] .