@super-ic/web-patterns 0.0.0-oidc-bootstrap.0 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +309 -1
- package/contracts/contact-section.json +23 -0
- package/contracts/neighborhood-landing.json +162 -0
- package/contracts/public-content-refinement.json +38 -0
- package/css/case-study-card.css +29 -0
- package/css/contact-section.css +39 -0
- package/css/neighborhood-landing.css +143 -0
- package/css/powered-by-superic.css +33 -0
- package/css/public-content.css +187 -0
- package/css/tailwind.css +6 -0
- package/dist/case-study-card-types.d.ts +16 -0
- package/dist/case-study-card-types.js +1 -0
- package/dist/case-study-card.d.ts +66 -0
- package/dist/case-study-card.js +72 -0
- package/dist/contact-form.d.ts +56 -0
- package/dist/contact-form.js +75 -0
- package/dist/contact-section.d.ts +23 -0
- package/dist/contact-section.js +11 -0
- package/dist/editorial-image.d.ts +10 -0
- package/dist/editorial-image.js +18 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/neighborhood-landing.d.ts +129 -0
- package/dist/neighborhood-landing.js +26 -0
- package/dist/powered-by-superic.d.ts +10 -0
- package/dist/powered-by-superic.js +20 -0
- package/dist/public-content.d.ts +152 -0
- package/dist/public-content.js +48 -0
- package/dist/surface-radius.d.ts +20 -0
- package/dist/surface-radius.js +30 -0
- package/package.json +50 -8
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/* NeighborhoodLanding owns layout, not theme values or application authority. */
|
|
2
|
+
.sic-neighborhood {
|
|
3
|
+
container: neighborhood / inline-size;
|
|
4
|
+
background: var(--background);
|
|
5
|
+
color: var(--foreground);
|
|
6
|
+
font-family: var(--type-body-medium-family);
|
|
7
|
+
font-size: var(--type-body-medium-size);
|
|
8
|
+
line-height: var(--type-body-medium-line-height);
|
|
9
|
+
overflow-wrap: anywhere;
|
|
10
|
+
}
|
|
11
|
+
.sic-neighborhood *, .sic-neighborhood *::before, .sic-neighborhood *::after { box-sizing: border-box; }
|
|
12
|
+
.sic-neighborhood h1, .sic-neighborhood h2, .sic-neighborhood h3, .sic-neighborhood h4, .sic-neighborhood p, .sic-neighborhood figure { margin: 0; }
|
|
13
|
+
.sic-neighborhood a { color: inherit; text-decoration: none; }
|
|
14
|
+
.sic-neighborhood a:focus-visible { outline: 2px solid var(--ring); outline-offset: 4px; border-radius: var(--radius-xs); }
|
|
15
|
+
.sic-neighborhood__width { width: calc(100% - var(--space-unit) * 16); max-width: 90rem; margin-inline: auto; }
|
|
16
|
+
.sic-neighborhood__skip { position: absolute; top: 0; left: 1rem; z-index: 5; transform: translateY(-150%); padding: 1rem; background: var(--background); }
|
|
17
|
+
.sic-neighborhood__skip:focus { transform: translateY(0); }
|
|
18
|
+
.sic-neighborhood__header { display: flex; align-items: center; justify-content: space-between; gap: calc(var(--space-unit) * 8); min-height: 104px; border-bottom: 1px solid var(--border); }
|
|
19
|
+
.sic-neighborhood__brand { display: flex; align-items: center; min-height: 44px; flex-shrink: 0; }
|
|
20
|
+
.sic-neighborhood__brand img, .sic-neighborhood__brand svg { width: 174px; max-height: 48px; object-fit: contain; }
|
|
21
|
+
.sic-neighborhood__nav { display: flex; align-items: center; flex-wrap: wrap; gap: calc(var(--space-unit) * 8); font-size: var(--type-body-small-size); }
|
|
22
|
+
.sic-neighborhood__nav span { display: contents; }
|
|
23
|
+
.sic-neighborhood__nav a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
|
|
24
|
+
.sic-neighborhood__account-link { border: 1px solid var(--border); border-radius: var(--radius-xs); padding-inline: calc(var(--space-unit) * 4); }
|
|
25
|
+
.sic-neighborhood__menu-trigger { display: none; }
|
|
26
|
+
.sic-neighborhood__nav a:hover, .sic-neighborhood__footer a:hover { text-decoration: underline; text-underline-offset: 4px; }
|
|
27
|
+
.sic-neighborhood__main:focus, .sic-neighborhood section:focus { outline: none; }
|
|
28
|
+
.sic-neighborhood section[id] { scroll-margin-block-start: calc(var(--space-unit) * 8); }
|
|
29
|
+
.sic-neighborhood__hero { display: grid; grid-template-columns: 0.9fr 1.1fr; align-items: center; gap: calc(var(--space-unit) * 12); padding-block: calc(var(--space-unit) * 12) calc(var(--space-unit) * 24); }
|
|
30
|
+
.sic-neighborhood__eyebrow { display: block; font-size: var(--type-overline-size); font-weight: var(--type-overline-weight); letter-spacing: var(--type-overline-tracking); line-height: 1.4; color: var(--muted-foreground); }
|
|
31
|
+
.sic-neighborhood h1 { font-family: var(--type-display-large-family); font-size: var(--type-display-large-size); line-height: 1.04; letter-spacing: var(--type-display-large-tracking); font-weight: var(--type-display-large-weight); text-wrap: balance; margin-top: calc(var(--space-unit) * 6); max-width: 9.5em; }
|
|
32
|
+
.sic-neighborhood__intro { margin-top: calc(var(--space-unit) * 6) !important; font-size: var(--type-body-large-size); line-height: var(--type-body-large-line-height); max-width: 33ch; color: var(--muted-foreground); }
|
|
33
|
+
.sic-neighborhood .sic-neighborhood__join-action { min-height: 48px; gap: calc(var(--space-unit) * 3); padding-inline: calc(var(--space-unit) * 6); margin-top: calc(var(--space-unit) * 8); white-space: normal; text-align: center; text-decoration: none; }
|
|
34
|
+
.sic-neighborhood a.sic-neighborhood__join-action { color: var(--primary-foreground); }
|
|
35
|
+
.sic-neighborhood__availability { margin-top: calc(var(--space-unit) * 3) !important; font-size: var(--type-body-small-size); color: var(--muted-foreground); }
|
|
36
|
+
.sic-neighborhood__hero-figure { position: relative; min-width: 0; padding-bottom: calc(var(--space-unit) * 12); }
|
|
37
|
+
.sic-neighborhood__hero-image, .sic-neighborhood__hero-figure > :first-child:not(.sic-neighborhood__example-note) { display: block; width: 100%; aspect-ratio: 1.25; height: auto; object-fit: cover; object-position: 50% 50%; border-radius: var(--radius-card); }
|
|
38
|
+
.sic-neighborhood__hero-media { display: block; width: 100%; aspect-ratio: 21 / 9; overflow: clip; border-radius: var(--radius-card); }
|
|
39
|
+
.sic-neighborhood__hero-media > :where(video,img) { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
40
|
+
.sic-neighborhood__example-note { position: relative; width: 86%; margin: calc(var(--space-unit) * -12) 0 0 auto; padding: calc(var(--space-unit) * 6) calc(var(--space-unit) * 6); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card-inset); }
|
|
41
|
+
.sic-neighborhood__example-note > p { font-family: var(--type-h3-family); font-size: var(--type-h3-size); letter-spacing: var(--type-h3-tracking); line-height: var(--type-h3-line-height); font-weight: 500; margin-block: calc(var(--space-unit) * 2); }
|
|
42
|
+
.sic-neighborhood__example-note > span:last-child { font-size: var(--type-body-small-size); color: var(--muted-foreground); }
|
|
43
|
+
.sic-neighborhood__hero-figure figcaption { position: absolute; bottom: calc(var(--space-unit) * 5); right: 0; text-align: right; font-size: var(--type-caption-size); color: var(--muted-foreground); }
|
|
44
|
+
.sic-neighborhood h2 { font-family: var(--type-display-small-family); font-size: var(--type-display-small-size); line-height: var(--type-display-small-line-height); letter-spacing: var(--type-display-small-tracking); font-weight: var(--type-display-small-weight); text-wrap: balance; }
|
|
45
|
+
.sic-neighborhood__section-intro > .sic-neighborhood__eyebrow + h2 { margin-top: calc(var(--space-unit) * 4); }
|
|
46
|
+
.sic-neighborhood__section-intro > h2 + p { margin-top: calc(var(--space-unit) * 6); max-width: 46ch; color: var(--muted-foreground); }
|
|
47
|
+
.sic-neighborhood__sharing { border-top: 1px solid var(--border); padding-block: calc(var(--space-unit) * 24); }
|
|
48
|
+
.sic-neighborhood__sharing > .sic-neighborhood__section-intro { max-width: 43rem; }
|
|
49
|
+
.sic-neighborhood__sharing > .sic-neighborhood__section-intro > h2 + p { max-width: 56ch; }
|
|
50
|
+
.sic-neighborhood__examples { margin-top: calc(var(--space-unit) * 8); }
|
|
51
|
+
.sic-neighborhood .sic-neighborhood__tabs { display: inline-grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: min(100%, 24rem); max-width: 100%; height: auto; padding: var(--space-unit); border: 1px solid var(--border); border-radius: var(--radius-xl); background: var(--surface-2); }
|
|
52
|
+
/* Theme and selection colors switch together. Interpolating foreground against
|
|
53
|
+
an already-switched canvas can briefly hide a label during hydration. */
|
|
54
|
+
.sic-neighborhood .sic-neighborhood__tabs [role=tab] { min-height: 44px; padding: calc(var(--space-unit) * 2) calc(var(--space-unit) * 6); border-radius: calc(var(--radius-xl) - 5px); white-space: normal; color: var(--muted-foreground); transition: none; }
|
|
55
|
+
.sic-neighborhood .sic-neighborhood__tabs [role=tab][data-active] { background: var(--background); color: var(--foreground); border-color: var(--muted-foreground); box-shadow: none; }
|
|
56
|
+
.sic-neighborhood__example-panel { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--space-unit) * 24); margin-top: calc(var(--space-unit) * 6); min-width: 0; }
|
|
57
|
+
.sic-neighborhood__example-panel[hidden] { display: none; }
|
|
58
|
+
.sic-neighborhood__example-message { --sic-neighborhood-example-radius: var(--radius-card); --sic-neighborhood-example-inset: calc(var(--space-unit) * 4); --sic-neighborhood-example-media-radius: max(0px, calc(var(--sic-neighborhood-example-radius) - var(--sic-neighborhood-example-inset))); background: var(--background); padding: var(--sic-neighborhood-example-inset); border-radius: var(--sic-neighborhood-example-radius); display: flex; flex-direction: column; align-items: start; justify-content: center; min-height: 300px; }
|
|
59
|
+
.sic-neighborhood__example-message h3 { font-family: var(--type-h1-family); font-size: var(--type-h1-size); font-weight: 500; letter-spacing: var(--type-h1-tracking); line-height: var(--type-h1-line-height); margin-top: calc(var(--space-unit) * 6); max-width: 18ch; }
|
|
60
|
+
.sic-neighborhood__example-message > p:last-child { margin-top: calc(var(--space-unit) * 6); font-size: var(--type-body-medium-size); max-width: 36ch; }
|
|
61
|
+
.sic-neighborhood__example-context { color: var(--muted-foreground); margin-top: calc(var(--space-unit) * 3) !important; font-size: var(--type-body-small-size); }
|
|
62
|
+
.sic-neighborhood__steps { list-style: none; padding: 0; margin: 0; display: grid; align-content: center; }
|
|
63
|
+
.sic-neighborhood__steps li { display: grid; grid-template-columns: auto 1fr; align-items: start; gap: calc(var(--space-unit) * 6); padding-block: calc(var(--space-unit) * 6); border-bottom: 1px solid var(--border); }
|
|
64
|
+
.sic-neighborhood__steps li:first-child { padding-top: 0; }
|
|
65
|
+
.sic-neighborhood__steps li:last-child { border: 0; padding-bottom: 0; }
|
|
66
|
+
.sic-neighborhood__step-number { font-family: var(--type-numeric-family); font-size: var(--type-body-small-size); line-height: 1.6; color: var(--muted-foreground); }
|
|
67
|
+
.sic-neighborhood__steps h3 { font-size: var(--type-body-large-size); font-weight: 500; line-height: var(--type-body-large-line-height); }
|
|
68
|
+
.sic-neighborhood__steps p { color: var(--muted-foreground); font-size: var(--type-body-medium-size); margin-top: calc(var(--space-unit) * 2); }
|
|
69
|
+
.sic-neighborhood__quiet { display: flex; gap: calc(var(--space-unit) * 4); align-items: flex-start; margin-top: calc(var(--space-unit) * 8); padding-block: calc(var(--space-unit) * 6); border-top: 1px solid var(--border); }
|
|
70
|
+
.sic-neighborhood__quiet svg { flex-shrink: 0; margin-top: var(--space-unit); }
|
|
71
|
+
.sic-neighborhood__quiet h3 { font-size: var(--type-body-medium-size); font-weight: 500; }
|
|
72
|
+
.sic-neighborhood__quiet p { margin-top: var(--space-unit); color: var(--muted-foreground); max-width: 82ch; font-size: var(--type-body-small-size); }
|
|
73
|
+
.sic-neighborhood__membership { background: var(--brand-accent-quiet, var(--surface-2)); padding-block: calc(var(--space-unit) * 24); }
|
|
74
|
+
.sic-neighborhood__membership-grid { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--space-unit) * 24); }
|
|
75
|
+
.sic-neighborhood__membership h2 { max-width: 12ch; }
|
|
76
|
+
.sic-neighborhood__join-state { margin-top: calc(var(--space-unit) * 8); padding-top: calc(var(--space-unit) * 6); border-top: 1px solid var(--border); }
|
|
77
|
+
.sic-neighborhood__join-state h3 { font-size: var(--type-body-medium-size); font-weight: 500; }
|
|
78
|
+
.sic-neighborhood__join-state p { font-size: var(--type-body-small-size); color: var(--muted-foreground); margin-top: calc(var(--space-unit) * 2); max-width: 40ch; }
|
|
79
|
+
.sic-neighborhood .sic-neighborhood__join-state .sic-neighborhood__join-action { margin-top: 0; }
|
|
80
|
+
.sic-neighborhood__text-link { display: inline-flex; align-items: center; min-height: 44px; gap: calc(var(--space-unit) * 2); font-size: var(--type-body-small-size); text-decoration: underline !important; text-underline-offset: 4px; margin-top: calc(var(--space-unit) * 3); }
|
|
81
|
+
.sic-neighborhood__residency > h3 { font-size: var(--type-body-small-size); color: var(--muted-foreground); font-weight: 500; }
|
|
82
|
+
.sic-neighborhood__residency ul { margin: calc(var(--space-unit) * 2) 0 0; padding: 0; list-style: none; }
|
|
83
|
+
.sic-neighborhood__residency li { padding-block: calc(var(--space-unit) * 6); border-bottom: 1px solid var(--border); }
|
|
84
|
+
.sic-neighborhood__residency h4 { font-size: var(--type-body-large-size); font-weight: 500; }
|
|
85
|
+
.sic-neighborhood__residency li p { color: var(--muted-foreground); margin-top: calc(var(--space-unit) * 2); font-size: var(--type-body-small-size); }
|
|
86
|
+
.sic-neighborhood__limitation { color: var(--muted-foreground); margin-top: calc(var(--space-unit) * 6) !important; font-size: var(--type-body-small-size); }
|
|
87
|
+
.sic-neighborhood__essentials { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: calc(var(--space-unit) * 24); padding-block: calc(var(--space-unit) * 24); }
|
|
88
|
+
.sic-neighborhood .sic-neighborhood__faq [data-slot=accordion-trigger] { min-height: 64px; padding-block: calc(var(--space-unit) * 6); font-size: var(--type-body-medium-size); font-weight: 500; align-items: center; gap: calc(var(--space-unit) * 6); }
|
|
89
|
+
.sic-neighborhood .sic-neighborhood__faq [data-slot=accordion-content] > div { padding-bottom: calc(var(--space-unit) * 6); padding-right: calc(var(--space-unit) * 8); font-size: var(--type-body-small-size); line-height: var(--type-body-small-line-height); color: var(--muted-foreground); }
|
|
90
|
+
.sic-neighborhood__faq a { display: inline-block; min-height: 44px; padding-block: calc(var(--space-unit) * 3); }
|
|
91
|
+
.sic-neighborhood__footer { border-top: 1px solid var(--border); padding-block: calc(var(--space-unit) * 8); display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--space-unit) * 6); font-size: var(--type-body-small-size); color: var(--muted-foreground); }
|
|
92
|
+
.sic-neighborhood__footer-brand { color: var(--foreground); font-size: var(--type-body-large-size); font-weight: 500; margin-bottom: calc(var(--space-unit) * 4) !important; }
|
|
93
|
+
.sic-neighborhood__footer > div { max-width: 48ch; }
|
|
94
|
+
.sic-neighborhood__footer nav { display: flex; flex-wrap: wrap; gap: 0 calc(var(--space-unit) * 6); align-content: start; justify-content: end; }
|
|
95
|
+
.sic-neighborhood__footer nav a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
|
|
96
|
+
.sic-neighborhood__footer-note { grid-column: 1 / -1; font-size: var(--type-caption-size); }
|
|
97
|
+
@container neighborhood (max-width: 760px) {
|
|
98
|
+
.sic-neighborhood__width { width: calc(100% - var(--space-unit) * 8); }
|
|
99
|
+
.sic-neighborhood__header { min-height: 88px; gap: calc(var(--space-unit) * 4); flex-wrap: wrap; padding-block: calc(var(--space-unit) * 4); }
|
|
100
|
+
.sic-neighborhood__brand img, .sic-neighborhood__brand svg { width: 144px; }
|
|
101
|
+
.sic-neighborhood__nav--desktop { display: none; }
|
|
102
|
+
.sic-neighborhood__menu-trigger { display: inline-flex; flex: 0 0 auto; min-width: 44px; min-height: 44px; }
|
|
103
|
+
.sic-neighborhood__menu-content { display: flex; }
|
|
104
|
+
.sic-neighborhood__nav--mobile { display: grid; gap: calc(var(--space-unit) * 2); padding: 0 calc(var(--space-unit) * 4) calc(var(--space-unit) * 6); }
|
|
105
|
+
.sic-neighborhood__nav--mobile a { width: 100%; min-height: 48px; }
|
|
106
|
+
.sic-neighborhood__hero { grid-template-columns: 1fr; gap: calc(var(--space-unit) * 8); padding-block: calc(var(--space-unit) * 8) calc(var(--space-unit) * 12); }
|
|
107
|
+
.sic-neighborhood h1 { font-size: clamp(var(--type-h2-size), 9.6cqw, var(--type-display-large-size)); max-width: 100%; }
|
|
108
|
+
.sic-neighborhood__intro { max-width: 36ch; font-size: var(--type-body-medium-size); }
|
|
109
|
+
.sic-neighborhood .sic-neighborhood__join-action { margin-top: calc(var(--space-unit) * 6); }
|
|
110
|
+
.sic-neighborhood__hero-image, .sic-neighborhood__hero-figure > :first-child:not(.sic-neighborhood__example-note) { aspect-ratio: 1.6; }
|
|
111
|
+
.sic-neighborhood__hero-media { aspect-ratio: 16 / 10; }
|
|
112
|
+
.sic-neighborhood__hero-figure { padding-bottom: calc(var(--space-unit) * 12); }
|
|
113
|
+
.sic-neighborhood__example-note { padding: calc(var(--space-unit) * 6); margin-top: calc(var(--space-unit) * -8); width: 89%; }
|
|
114
|
+
.sic-neighborhood__hero-figure figcaption { font-size: var(--type-caption-size); bottom: 0; max-width: 32ch; }
|
|
115
|
+
.sic-neighborhood__sharing, .sic-neighborhood__membership, .sic-neighborhood__essentials { padding-block: calc(var(--space-unit) * 12); }
|
|
116
|
+
.sic-neighborhood__example-panel, .sic-neighborhood__membership-grid, .sic-neighborhood__essentials { grid-template-columns: 1fr; gap: calc(var(--space-unit) * 8); }
|
|
117
|
+
.sic-neighborhood__example-message { --sic-neighborhood-example-inset: calc(var(--space-unit) * 3); padding: var(--sic-neighborhood-example-inset); min-height: 280px; }
|
|
118
|
+
.sic-neighborhood__steps li { padding-block: calc(var(--space-unit) * 6); }
|
|
119
|
+
.sic-neighborhood__membership h2 { max-width: 15ch; }
|
|
120
|
+
.sic-neighborhood__footer { grid-template-columns: 1fr; padding-block: calc(var(--space-unit) * 8); }
|
|
121
|
+
.sic-neighborhood__footer nav { justify-content: start; gap: 0 calc(var(--space-unit) * 6); }
|
|
122
|
+
}
|
|
123
|
+
@media (prefers-reduced-motion: reduce) {
|
|
124
|
+
.sic-neighborhood *, .sic-neighborhood *::before, .sic-neighborhood *::after { animation-duration: 0s !important; transition-duration: 0s !important; scroll-behavior: auto !important; }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Original artwork keeps the people, hands and exchange visible at every width. */
|
|
128
|
+
.sic-neighborhood__hero-image[data-fit="contain"] { aspect-ratio: auto; object-fit: contain; }
|
|
129
|
+
|
|
130
|
+
.sic-neighborhood__possibilities { border-top: 1px solid var(--border); padding-block: calc(var(--space-unit) * 24); }
|
|
131
|
+
.sic-neighborhood__possibilities > ul { list-style: none; padding: 0; margin: calc(var(--space-unit) * 8) 0 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: calc(var(--space-unit) * 8); row-gap: calc(var(--space-unit) * 8); }
|
|
132
|
+
.sic-neighborhood__possibilities li { min-width: 0; }
|
|
133
|
+
.sic-neighborhood__possibility-media { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: contain; border: 1px solid var(--border); border-radius: var(--radius-card); }
|
|
134
|
+
.sic-neighborhood__possibilities li > .sic-neighborhood__eyebrow { margin-top: calc(var(--space-unit) * 4); }
|
|
135
|
+
.sic-neighborhood__possibilities li > h3 { margin-top: calc(var(--space-unit) * 2); font-family: var(--type-h3-family); font-size: var(--type-h3-size); line-height: var(--type-h3-line-height); font-weight: var(--type-h3-weight); }
|
|
136
|
+
.sic-neighborhood__possibilities li > p:last-child { margin-top: calc(var(--space-unit) * 2); color: var(--muted-foreground); }
|
|
137
|
+
.sic-neighborhood__example-media { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: contain; border-radius: var(--sic-neighborhood-example-media-radius); margin-bottom: calc(var(--space-unit) * 6); }
|
|
138
|
+
@container neighborhood (max-width: 760px) { .sic-neighborhood__possibilities { padding-block: calc(var(--space-unit) * 12); } .sic-neighborhood__possibilities > ul { grid-template-columns: 1fr; } }
|
|
139
|
+
|
|
140
|
+
/* Portal content owns its layout independently of the marketing container. */
|
|
141
|
+
.sic-neighborhood__nav--mobile { display: grid; gap: calc(var(--space-unit) * 2); padding: 0 calc(var(--space-unit) * 4) calc(var(--space-unit) * 6); }
|
|
142
|
+
.sic-neighborhood__nav--mobile a { display: inline-flex; align-items: center; width: 100%; min-height: var(--control-target-min); min-width: var(--control-target-min); }
|
|
143
|
+
@container neighborhood (max-width: 1120px) { .sic-neighborhood__nav--desktop { display: none; } .sic-neighborhood__menu-trigger { display: inline-flex; } }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Neutral attribution only. Theme roles inherit at the nearest explicit scope. */
|
|
2
|
+
.sic-powered-by-superic {
|
|
3
|
+
--powered-by-ink: var(--foreground);
|
|
4
|
+
--powered-by-label: var(--muted-foreground);
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
white-space: nowrap;
|
|
8
|
+
gap: var(--space-unit);
|
|
9
|
+
min-block-size: var(--control-target-min);
|
|
10
|
+
min-inline-size: var(--control-target-min);
|
|
11
|
+
font-family: var(--font-body, var(--font-sans));
|
|
12
|
+
font-size: var(--type-micro-size);
|
|
13
|
+
font-weight: var(--type-button-weight);
|
|
14
|
+
letter-spacing: 0.02em;
|
|
15
|
+
color: var(--powered-by-label);
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
transition: color var(--motion-hover-duration) var(--motion-ease-quiet);
|
|
18
|
+
}
|
|
19
|
+
.sic-powered-by-superic[data-size="md"] {
|
|
20
|
+
gap: var(--space-unit);
|
|
21
|
+
font-size: var(--type-caption-size);
|
|
22
|
+
}
|
|
23
|
+
.sic-powered-by-superic[data-variant="light"] {
|
|
24
|
+
--powered-by-ink: var(--light-content-primary);
|
|
25
|
+
--powered-by-label: var(--light-content-secondary);
|
|
26
|
+
}
|
|
27
|
+
.sic-powered-by-superic[data-variant="dark"] {
|
|
28
|
+
--powered-by-ink: var(--dark-content-primary);
|
|
29
|
+
--powered-by-label: var(--dark-content-secondary);
|
|
30
|
+
}
|
|
31
|
+
.sic-powered-by-superic:hover { color: var(--powered-by-ink); }
|
|
32
|
+
.sic-powered-by-superic:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
|
|
33
|
+
@media (prefers-reduced-motion: reduce) { .sic-powered-by-superic { transition: none; } }
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/* Public reading and recovery surfaces. Product copy and authority are supplied. */
|
|
2
|
+
.sic-public { container: public-site / inline-size; position: relative; background: var(--background); color: var(--foreground); font-family: var(--type-body-medium-family); font-size: var(--type-body-medium-size); line-height: var(--type-body-medium-line-height); overflow-wrap: anywhere; }
|
|
3
|
+
.sic-public *, .sic-public *::before, .sic-public *::after { box-sizing: border-box; }
|
|
4
|
+
.sic-public :where(h1,h2,h3,p,ul,ol,dl,figure) { margin: 0; }
|
|
5
|
+
.sic-public a { color: inherit; text-underline-offset: .22em; text-decoration-thickness: 1px; }
|
|
6
|
+
.sic-public :where(a,summary):focus-visible { outline: 2px solid var(--ring); outline-offset: 4px; border-radius: var(--radius-xs); }
|
|
7
|
+
.sic-public__width { width: min(calc(100% - 4rem), 69rem); margin-inline: auto; }
|
|
8
|
+
.sic-public__width--marketing { width: min(calc(100% - 4rem), 90rem); }
|
|
9
|
+
.sic-public__skip { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); clip-path: inset(50%); white-space: nowrap; }
|
|
10
|
+
.sic-public__skip:focus-visible { z-index: 10; top: 1rem; left: 1rem; width: auto; height: auto; margin: 0; padding: 1rem; overflow: visible; clip: auto; clip-path: none; background: var(--background); }
|
|
11
|
+
.sic-public__header { display: flex; justify-content: space-between; align-items: center; gap: 1.5rem; min-height: 6rem; border-bottom: 1px solid var(--border); }
|
|
12
|
+
.sic-public__brand { display: inline-flex; align-items: center; flex: 0 0 auto; min-height: 44px; }
|
|
13
|
+
/* Consumer brand assets may have mutually exclusive theme visibility. */
|
|
14
|
+
.sic-public__brand :where(img,svg) { width: 100px; height: auto; }
|
|
15
|
+
.sic-public__header nav { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem 1.5rem; }
|
|
16
|
+
.sic-public__header nav a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; text-decoration: none; font-size: var(--type-body-small-size); }
|
|
17
|
+
.sic-public__menu-trigger { display: none; }
|
|
18
|
+
.sic-public__header a[aria-current=page] { text-decoration: underline; font-weight: 600; }
|
|
19
|
+
.sic-public__main { min-height: 55dvh; padding-block: 3rem 6rem; outline: none; }
|
|
20
|
+
.sic-public :where(h1,h2,h3) { font-family: var(--type-h1-family); text-wrap: balance; }
|
|
21
|
+
.sic-public h1 { font-size: var(--type-display-small-size); font-weight: var(--type-display-small-weight); line-height: var(--type-display-small-line-height); letter-spacing: var(--type-display-small-tracking); }
|
|
22
|
+
.sic-public h2 { font-size: var(--type-h2-size); line-height: var(--type-h2-line-height); font-weight: var(--type-h2-weight); letter-spacing: var(--type-h2-tracking); }
|
|
23
|
+
.sic-public h3 { font-size: var(--type-h3-size); line-height: var(--type-h3-line-height); font-weight: var(--type-h3-weight); }
|
|
24
|
+
.sic-public__page-heading { max-width: 48rem; }
|
|
25
|
+
.sic-public__intro { margin-top: 1rem !important; color: var(--muted-foreground); max-width: 62ch; font-size: var(--type-body-large-size); line-height: var(--type-body-large-line-height); }
|
|
26
|
+
.sic-public__back { margin-bottom: 1rem !important; font-size: var(--type-body-small-size); }
|
|
27
|
+
.sic-public__back a { display: inline-flex; min-height: 44px; align-items: center; }
|
|
28
|
+
.sic-public__metadata { margin-top: 1rem !important; color: var(--muted-foreground); font-size: var(--type-body-small-size); }
|
|
29
|
+
.sic-public__footer { border-top: 1px solid var(--border); padding-block: 2rem; display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 3rem; color: var(--muted-foreground); font-size: var(--type-body-small-size); }
|
|
30
|
+
.sic-public__footer-brand { color: var(--foreground); font-weight: 600; margin-bottom: .75rem !important; }
|
|
31
|
+
.sic-public__footer nav { display: flex; flex-wrap: wrap; gap: 0 1.5rem; justify-content: end; align-content: start; }
|
|
32
|
+
.sic-public__footer nav a { display: inline-flex; min-height: 44px; min-width: 44px; align-items: center; }
|
|
33
|
+
.sic-public__footer-note { grid-column: 1 / -1; font-size: var(--type-caption-size); }
|
|
34
|
+
.sic-public-article__layout { display: grid; grid-template-columns: minmax(0,1fr) 14rem; gap: 3rem; margin-top: 3rem; }
|
|
35
|
+
.sic-public-article__contents { grid-column: 2; grid-row: 1; align-self: start; position: sticky; top: 1.5rem; }
|
|
36
|
+
.sic-public-article__contents summary { cursor: pointer; min-height: 44px; display: list-item; font-weight: 600; font-size: var(--type-body-small-size); padding-block: .5rem; }
|
|
37
|
+
.sic-public-article__contents nav { display: grid; padding-top: .25rem; }
|
|
38
|
+
.sic-public-article__contents a { display: flex; align-items: center; min-height: 44px; padding-block: .5rem; color: var(--muted-foreground); font-size: var(--type-body-small-size); text-decoration: none; }
|
|
39
|
+
.sic-public-article__contents a:hover { color: var(--foreground); text-decoration: underline; }
|
|
40
|
+
.sic-public-article__body { min-width: 0; grid-column: 1; grid-row: 1; }
|
|
41
|
+
.sic-public-article__body > section { margin-top: 3rem; scroll-margin-top: 2rem; outline: none; }
|
|
42
|
+
.sic-public-article__body > section:first-child { margin-top: 0; }
|
|
43
|
+
.sic-public__prose { margin-top: 1rem; max-width: 68ch; }
|
|
44
|
+
.sic-public__prose a, .sic-public__back a, .sic-public__related a { text-decoration-line: underline; }
|
|
45
|
+
.sic-public__prose > * + * { margin-top: 1rem; }
|
|
46
|
+
.sic-public__prose :where(ul,ol) { padding-left: 1.5rem; }
|
|
47
|
+
.sic-public__prose li + li { margin-top: .75rem; }
|
|
48
|
+
.sic-public__prose h3 { margin-top: 2rem; }
|
|
49
|
+
.sic-public__prose table { width: 100%; border-collapse: collapse; }
|
|
50
|
+
.sic-public__prose caption { margin-bottom: calc(var(--space-unit) * 4); color: var(--muted-foreground); text-align: left; }
|
|
51
|
+
.sic-public__prose :where(th,td) { padding: calc(var(--space-unit) * 4); border-bottom: 1px solid var(--border); vertical-align: top; text-align: left; }
|
|
52
|
+
.sic-public__prose th { font-weight: 500; }
|
|
53
|
+
.sic-public__prose dl > div { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 1rem; padding-block: 1rem; border-bottom: 1px solid var(--border); }
|
|
54
|
+
.sic-public__prose dd { margin: 0; }
|
|
55
|
+
.sic-public__notice { border-inline-start: 3px solid var(--border); padding: .25rem 1rem; }
|
|
56
|
+
.sic-public__notice h2 { font-size: var(--type-body-medium-size); line-height: var(--type-body-medium-line-height); font-weight: 600; }
|
|
57
|
+
.sic-public__notice p { margin-top: .5rem; color: var(--muted-foreground); }
|
|
58
|
+
.sic-public__notice a { display: inline-flex; min-height: 44px; align-items: center; margin-top: .5rem; }
|
|
59
|
+
.sic-public__related { border-top: 1px solid var(--border); padding-top: 2rem; }
|
|
60
|
+
.sic-public__related ul { list-style: none; padding: .5rem 0 0; }
|
|
61
|
+
.sic-public__related a { display: inline-flex; align-items: center; min-height: 44px; }
|
|
62
|
+
.sic-public-help__search { max-width: 43rem; margin-top: 2rem; }
|
|
63
|
+
.sic-public-help__search label { display: block; font-size: var(--type-body-small-size); font-weight: 600; margin-bottom: .5rem; }
|
|
64
|
+
.sic-public-help__search > div { display: flex; align-items: stretch; gap: .75rem; }
|
|
65
|
+
.sic-public-help__search [data-slot=input] { min-width: 0; min-height: 48px; flex: 1; }
|
|
66
|
+
.sic-public-help__search [data-slot=button] { min-height: 48px; flex-shrink: 0; }
|
|
67
|
+
.sic-public-help__results { margin-top: 2rem; }
|
|
68
|
+
.sic-public-help__groups { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem 3rem; margin-top: 2rem; }
|
|
69
|
+
.sic-public-help__groups h2 { font-size: var(--type-h3-size); }
|
|
70
|
+
.sic-public-help__groups ul { list-style: none; padding: .75rem 0 0; }
|
|
71
|
+
.sic-public-help__groups li { border-bottom: 1px solid var(--border); padding-bottom: 1rem; }
|
|
72
|
+
.sic-public-help__groups li + li { margin-top: .5rem; }
|
|
73
|
+
.sic-public-help__groups li a { display: flex; align-items: center; min-height: 44px; font-weight: 600; text-decoration: none; }
|
|
74
|
+
.sic-public-help__groups li a:hover { text-decoration: underline; }
|
|
75
|
+
.sic-public-help__groups li p { font-size: var(--type-body-small-size); color: var(--muted-foreground); }
|
|
76
|
+
.sic-public-help__empty { max-width: 42rem; padding-block: 1rem; }
|
|
77
|
+
.sic-public-help__empty > * + * { margin-top: 1rem; }
|
|
78
|
+
.sic-public-help__empty a { min-height: 44px; white-space: normal; text-decoration: none; }
|
|
79
|
+
.sic-public-help__contact { border-top: 1px solid var(--border); margin-top: 3rem; padding-top: 2rem; display: flex; justify-content: space-between; align-items: center; gap: 2rem; }
|
|
80
|
+
.sic-public-help__contact h2 { font-size: var(--type-h3-size); }
|
|
81
|
+
.sic-public-help__contact p { margin-top: .5rem; color: var(--muted-foreground); }
|
|
82
|
+
.sic-public-help__contact a { flex-shrink: 0; }
|
|
83
|
+
.sic-public :where(.sic-public-help__contact a,.sic-public__actions a) { min-height: 44px; white-space: normal; text-decoration: none; }
|
|
84
|
+
.sic-public-availability { max-width: 44rem; padding-block: 2rem 3rem; }
|
|
85
|
+
.sic-public-availability > p { margin-top: 1rem; }
|
|
86
|
+
.sic-public__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 1rem 1.5rem; margin-top: 2rem; }
|
|
87
|
+
.sic-public__actions a { display: inline-flex; align-items: center; }
|
|
88
|
+
.sic-public__actions a:not(.sic-public__primary) { text-decoration: underline; }
|
|
89
|
+
.sic-public a.sic-public__primary { color: var(--primary-foreground); }
|
|
90
|
+
@container public-site (max-width: 760px) {
|
|
91
|
+
.sic-public__width { width: calc(100% - 2rem); }
|
|
92
|
+
.sic-public__header { min-height: 5rem; gap: .75rem; flex-wrap: wrap; padding-block: .75rem; }
|
|
93
|
+
.sic-public__nav--desktop { display: none !important; }
|
|
94
|
+
.sic-public__menu-trigger { display: inline-flex; min-width: 44px; min-height: 44px; }
|
|
95
|
+
.sic-public__menu-content { display: flex; }
|
|
96
|
+
.sic-public__nav--mobile { display: grid !important; gap: .25rem; padding: 0 1rem 1.5rem; }
|
|
97
|
+
.sic-public__nav--mobile a { width: 100%; min-height: 48px; }
|
|
98
|
+
.sic-public__main { padding-block: 2rem 3rem; }
|
|
99
|
+
.sic-public h1 { font-size: var(--type-h1-size); line-height: var(--type-h1-line-height); letter-spacing: var(--type-h1-tracking); }
|
|
100
|
+
.sic-public h2 { font-size: var(--type-h3-size); line-height: var(--type-h3-line-height); }
|
|
101
|
+
.sic-public__intro { font-size: var(--type-body-medium-size); }
|
|
102
|
+
.sic-public-article__layout { display: flex; flex-direction: column; gap: 2rem; margin-top: 1.5rem; }
|
|
103
|
+
.sic-public-article__contents { position: static; align-self: stretch; border-block: 1px solid var(--border); padding-block: .25rem; }
|
|
104
|
+
.sic-public-article__contents nav { grid-template-columns: 1fr 1fr; gap: .25rem 1rem; padding-bottom: .75rem; }
|
|
105
|
+
.sic-public-article__body > section { margin-top: 2rem; }
|
|
106
|
+
.sic-public-help__groups { grid-template-columns: 1fr; gap: 2rem; }
|
|
107
|
+
.sic-public-help__contact { align-items: start; flex-direction: column; gap: 1rem; }
|
|
108
|
+
.sic-public__footer { grid-template-columns: 1fr; gap: 1.5rem; }
|
|
109
|
+
.sic-public__footer nav { justify-content: start; }
|
|
110
|
+
.sic-public-availability { padding-block: 1rem 2rem; }
|
|
111
|
+
}
|
|
112
|
+
@media (prefers-reduced-motion: reduce) {
|
|
113
|
+
.sic-public *, .sic-public *::before, .sic-public *::after { scroll-behavior: auto !important; animation-duration: 0s !important; transition-duration: 0s !important; }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* A document reader keeps its heading and return action visible while text scrolls. */
|
|
117
|
+
.sic-public-document-dialog[data-slot="sheet-content"] {
|
|
118
|
+
font-family: var(--type-body-medium-family);
|
|
119
|
+
font-size: var(--type-body-medium-size);
|
|
120
|
+
line-height: var(--type-body-medium-line-height);
|
|
121
|
+
overflow-wrap: anywhere;
|
|
122
|
+
block-size: min(48rem, calc(100dvh - 16px));
|
|
123
|
+
max-block-size: calc(100dvh - 16px);
|
|
124
|
+
display: grid;
|
|
125
|
+
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
126
|
+
gap: 0;
|
|
127
|
+
overflow: clip;
|
|
128
|
+
border-start-start-radius: var(--radius-xl);
|
|
129
|
+
border-start-end-radius: var(--radius-xl);
|
|
130
|
+
}
|
|
131
|
+
.sic-public-document-dialog[data-slot="sheet-content"] [data-slot="sheet-header"] {
|
|
132
|
+
min-block-size: 76px;
|
|
133
|
+
padding-inline-end: 96px;
|
|
134
|
+
border-block-end: 1px solid var(--border);
|
|
135
|
+
justify-content: center;
|
|
136
|
+
}
|
|
137
|
+
.sic-public-document-dialog[data-slot="sheet-content"] [data-slot="sheet-footer"] {
|
|
138
|
+
margin: 0;
|
|
139
|
+
border-block-start: 1px solid var(--border);
|
|
140
|
+
}
|
|
141
|
+
.sic-public-document-dialog[data-slot="sheet-content"] button {
|
|
142
|
+
min-block-size: 44px;
|
|
143
|
+
min-inline-size: 44px;
|
|
144
|
+
}
|
|
145
|
+
.sic-public-document-dialog__body {
|
|
146
|
+
display: grid;
|
|
147
|
+
align-content: start;
|
|
148
|
+
min-block-size: 0;
|
|
149
|
+
overflow: auto;
|
|
150
|
+
gap: 1rem;
|
|
151
|
+
padding: 1rem;
|
|
152
|
+
scroll-padding-block: 1rem;
|
|
153
|
+
outline-offset: -3px;
|
|
154
|
+
}
|
|
155
|
+
.sic-public-document-dialog__body section {
|
|
156
|
+
display: grid;
|
|
157
|
+
gap: 0.25rem;
|
|
158
|
+
}
|
|
159
|
+
@media (min-width: 768px) {
|
|
160
|
+
.sic-public-document-dialog[data-slot="sheet-content"] {
|
|
161
|
+
inline-size: min(48rem, calc(100% - 48px));
|
|
162
|
+
margin-inline: auto;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.sic-public-document-dialog__body :where(h3,p,ul,ol) { margin: 0; }
|
|
167
|
+
.sic-public-document-dialog__body h3 { font-family: var(--type-h3-family); font-size: var(--type-h3-size); line-height: var(--type-h3-line-height); font-weight: var(--type-h3-weight); }
|
|
168
|
+
.sic-public-document-dialog__body section { gap: .75rem; }
|
|
169
|
+
.sic-public-document-dialog__body a { color: inherit; text-decoration: underline; text-underline-offset: .2em; }
|
|
170
|
+
.sic-public-document-dialog__body :where(ul,ol) { padding-inline-start: 1.25rem; }
|
|
171
|
+
|
|
172
|
+
.sic-public-article__media { display: block; max-width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: contain; border-radius: var(--radius-card); margin-top: calc(var(--space-unit) * 6); }
|
|
173
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__layout { display: block; margin-top: calc(var(--space-unit) * 12); }
|
|
174
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__body > section { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: calc(var(--space-unit) * 12); margin-top: calc(var(--space-unit) * 24); }
|
|
175
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__body > section:nth-child(even) .sic-public-article__section-copy { order: 2; }
|
|
176
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__media { width: 100%; max-width: none; margin: 0; aspect-ratio: 16 / 10; object-fit: cover; }
|
|
177
|
+
.sic-public-article[data-presentation=marketing] .sic-public__prose { max-width: 58ch; }
|
|
178
|
+
@container public-site (max-width: 760px) {
|
|
179
|
+
.sic-public__width--marketing { width: calc(100% - 2rem); }
|
|
180
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__layout { margin-top: 2rem; }
|
|
181
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__body > section { grid-template-columns: 1fr; gap: 1.5rem; margin-top: 3rem; }
|
|
182
|
+
.sic-public-article[data-presentation=marketing] .sic-public-article__body > section:nth-child(even) .sic-public-article__section-copy { order: initial; }
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Sheet is portalled outside the page container. */
|
|
186
|
+
.sic-public__nav--mobile { display: grid; gap: calc(var(--space-unit) * 2); padding: 0 calc(var(--space-unit) * 4) calc(var(--space-unit) * 6); }
|
|
187
|
+
.sic-public__nav--mobile a { display: inline-flex; align-items: center; min-height: var(--control-target-min); min-width: var(--control-target-min); }
|
package/css/tailwind.css
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** CaseStudyCard presentation shape. The package ships no card records or slug roster. */
|
|
2
|
+
export type CaseStudyCardProductAccess = "public" | "gated" | "partially-gated";
|
|
3
|
+
/** Consumer-owned slug. The package does not publish a roster or taxonomy. */
|
|
4
|
+
export type LiveCaseStudyCardSlug = string;
|
|
5
|
+
export type CaseStudyCardProvenance = {
|
|
6
|
+
slug: string;
|
|
7
|
+
identity: string;
|
|
8
|
+
wordmark: string | null;
|
|
9
|
+
relationshipLabel?: string;
|
|
10
|
+
productAccess: CaseStudyCardProductAccess;
|
|
11
|
+
headline: string;
|
|
12
|
+
result: string;
|
|
13
|
+
artworkAlt: string;
|
|
14
|
+
sourceAssets: readonly [string, ...string[]];
|
|
15
|
+
reference?: true;
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type ReactNode, type Ref } from "react";
|
|
2
|
+
export type CaseStudyCardAccess = "open" | "locked";
|
|
3
|
+
export type CaseStudyCardDensity = "standard" | "compact";
|
|
4
|
+
export type CaseStudyCardIdentityKind = "text" | "wordmark";
|
|
5
|
+
export type CaseStudyCardPresentation = "tenant" | "superic";
|
|
6
|
+
export type CaseStudyCardOpenControlProps = {
|
|
7
|
+
href: string;
|
|
8
|
+
className: string;
|
|
9
|
+
"data-slot": "case-study-card";
|
|
10
|
+
"data-access": "open";
|
|
11
|
+
"data-density": CaseStudyCardDensity;
|
|
12
|
+
"data-card-presentation": CaseStudyCardPresentation;
|
|
13
|
+
"data-case-study-card"?: string | undefined;
|
|
14
|
+
"aria-label": string;
|
|
15
|
+
"aria-describedby": string;
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Structural case-study card API. Consumer adapters own destination, identity,
|
|
20
|
+
* source-backed approved artwork, claims, and access handling. Typed consumer
|
|
21
|
+
* registries and their art checks preserve each owner-approved composition. The shared pattern owns geometry, hierarchy, focus treatment,
|
|
22
|
+
* and one whole-card control.
|
|
23
|
+
*/
|
|
24
|
+
export type CaseStudyCardProps = {
|
|
25
|
+
href: string;
|
|
26
|
+
/** Used in the one interactive control name. */
|
|
27
|
+
accessibleName: string;
|
|
28
|
+
/** Consumer-supplied identity mark or plain product name. */
|
|
29
|
+
identity: ReactNode;
|
|
30
|
+
/** Keeps text identities visually distinct from approved product wordmarks. */
|
|
31
|
+
identityKind?: CaseStudyCardIdentityKind;
|
|
32
|
+
/** Plain-language relationship, such as a product within a parent brand. */
|
|
33
|
+
relationshipLabel?: string | undefined;
|
|
34
|
+
headline: string;
|
|
35
|
+
result: string;
|
|
36
|
+
/** Owner-approved artwork from the consumer art registry.
|
|
37
|
+
* Consumer adapters enforce provenance and preserve the approved visual baseline;
|
|
38
|
+
* ReactNode preserves that content without letting the shell infer visual truth.
|
|
39
|
+
* Changing the shell or adopting DS controls never authorizes replacing artwork. */
|
|
40
|
+
media: ReactNode;
|
|
41
|
+
/** Consumer-localized visible action text. English fallback is retained. */
|
|
42
|
+
actionLabel?: string | undefined;
|
|
43
|
+
/** Consumer-localized whole interactive control name. Overrides the legacy name wrapper. */
|
|
44
|
+
actionAriaLabel?: string | undefined;
|
|
45
|
+
/** Consumer-localized final screen-reader action sentence. */
|
|
46
|
+
actionDescription?: string | undefined;
|
|
47
|
+
access?: CaseStudyCardAccess;
|
|
48
|
+
density?: CaseStudyCardDensity;
|
|
49
|
+
/** Scopes the recovered SuperIC surface and typography treatment to this card. */
|
|
50
|
+
presentation?: CaseStudyCardPresentation;
|
|
51
|
+
onUnlock?: () => void;
|
|
52
|
+
/** Lets a production adapter provide framework-native navigation. */
|
|
53
|
+
renderOpenControl?: (props: CaseStudyCardOpenControlProps) => ReactNode;
|
|
54
|
+
/** Optional consumer trace id for page-level verification. */
|
|
55
|
+
caseStudyId?: string | undefined;
|
|
56
|
+
/** Consumer-owned ref for returning focus after a locked access dialog closes. */
|
|
57
|
+
lockedControlRef?: Ref<HTMLDivElement>;
|
|
58
|
+
className?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* The package shell deliberately has no knowledge of Next.js, GateModal, or a
|
|
62
|
+
* consumer registry. That keeps every card shell deterministic and lets a
|
|
63
|
+
* production adapter provide the single navigation and access-flow boundary.
|
|
64
|
+
*/
|
|
65
|
+
export declare function CaseStudyCard({ href, accessibleName, identity, identityKind, relationshipLabel, headline, result, media, actionLabel, actionAriaLabel, actionDescription, access, density, presentation, onUnlock, renderOpenControl, caseStudyId, lockedControlRef, className, }: CaseStudyCardProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
|
|
66
|
+
export declare const CaseStudyCardShell: typeof CaseStudyCard;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId } from "react";
|
|
3
|
+
import { Icon } from "@super-ic/icon-contracts";
|
|
4
|
+
import { SURFACE_RADIUS_CLASSES } from "./surface-radius.js";
|
|
5
|
+
const controlClassName = `group block min-h-[44px] w-full ${SURFACE_RADIUS_CLASSES.card} text-left outline-none transition-transform duration-[var(--motion-hover-duration,220ms)] ease-[var(--motion-ease-quiet,ease-out)] hover:-translate-y-0.5 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background motion-reduce:hover:[translate:0_0] motion-reduce:transition-none`;
|
|
6
|
+
function asSentence(value) {
|
|
7
|
+
const trimmed = value.trim().replace(/\.{2,}$/u, ".");
|
|
8
|
+
return /[.!?]$/u.test(trimmed) ? trimmed : `${trimmed}.`;
|
|
9
|
+
}
|
|
10
|
+
function CardBody({ accessibleName, identity, identityKind, relationshipLabel, headline, result, media, access, density, descriptionId, actionLabel, actionDescription, }) {
|
|
11
|
+
const compact = density === "compact";
|
|
12
|
+
const isTextIdentity = identityKind === "text";
|
|
13
|
+
/* One edge law: elevation is the shadow; the dark ramp separates the
|
|
14
|
+
card from the ground, so no hairline doubles the edge. Shadow and
|
|
15
|
+
the link's lift share the quiet-motion pair so the hover reads as
|
|
16
|
+
one movement. */
|
|
17
|
+
return (_jsxs("div", { className: `flex h-full flex-col overflow-hidden ${SURFACE_RADIUS_CLASSES.card} bg-enterprise-bg text-enterprise-fg shadow-[var(--elev-card)] transition-shadow duration-[var(--motion-hover-duration,220ms)] ease-[var(--motion-ease-quiet,ease-out)] group-hover:shadow-[var(--elev-pill)] motion-reduce:transition-none`, "data-slot": "case-study-card-surface", children: [_jsx("div", { className: `aspect-[16/10] w-full shrink-0 overflow-hidden ${SURFACE_RADIUS_CLASSES.cardFrameTop} border-b border-border`, "data-slot": "case-study-card-art", "data-case-study-slot": "art-frame", children: _jsx("div", { className: "size-full overflow-hidden [&_img]:block [&_img]:size-full [&_img]:object-contain", children: media }) }), _jsxs("div", { className: compact
|
|
18
|
+
? "flex min-h-48 flex-1 flex-col gap-3 p-5"
|
|
19
|
+
: "flex flex-1 flex-col gap-4 p-5 sm:p-6", "data-slot": "case-study-card-body", children: [_jsx("div", { className: compact
|
|
20
|
+
? isTextIdentity
|
|
21
|
+
? "min-h-6 text-xl font-semibold leading-none tracking-tight text-enterprise-fg"
|
|
22
|
+
: "flex min-h-7 items-center overflow-hidden text-sm font-semibold text-enterprise-fg [&_[data-slot=case-study-card-wordmark]]:max-h-7 [&_[data-slot=case-study-card-wordmark]]:max-w-40"
|
|
23
|
+
: isTextIdentity
|
|
24
|
+
? "min-h-9 text-3xl font-semibold leading-none tracking-tight text-enterprise-fg"
|
|
25
|
+
: "flex min-h-10 items-center overflow-hidden text-base font-semibold text-enterprise-fg [&_[data-slot=case-study-card-wordmark]]:max-h-10 [&_[data-slot=case-study-card-wordmark]]:max-w-48", "data-slot": "case-study-card-identity", "data-case-study-slot": "logo", "data-identity-kind": identityKind, "data-logo-slot-position": "body-start", "data-logo-slot-size": compact ? "compact" : "standard", children: identity }), relationshipLabel ? (_jsx("p", { className: compact
|
|
26
|
+
? "text-xs font-medium tracking-[0.04em] text-[var(--enterprise-muted)]"
|
|
27
|
+
: "text-xs font-medium tracking-[0.04em] text-[var(--enterprise-muted)] md:text-sm xl:text-base", "data-slot": "case-study-card-relationship", "data-case-study-slot": "eyebrow", children: relationshipLabel })) : null, _jsx("h2", { className: compact
|
|
28
|
+
? "text-lg font-semibold leading-snug tracking-tight text-enterprise-fg"
|
|
29
|
+
: "text-xl font-semibold leading-[1.12] tracking-tight text-enterprise-fg md:text-2xl xl:text-3xl", "data-slot": "case-study-card-headline", "data-case-study-slot": "headline", children: headline }), _jsx("p", { className: compact
|
|
30
|
+
? "text-sm leading-6 text-[var(--enterprise-subtle)]"
|
|
31
|
+
: "text-base leading-7 text-[var(--enterprise-subtle)] md:text-lg md:leading-8 xl:text-xl xl:leading-9", "data-slot": "case-study-card-result", "data-case-study-slot": "proof-line", children: result }), _jsxs("span", { className: compact
|
|
32
|
+
? "mt-auto inline-flex items-center gap-2 pt-1 text-sm font-medium text-enterprise-fg underline-offset-4 group-hover:underline"
|
|
33
|
+
: "mt-auto inline-flex items-center gap-2 pt-1 text-sm font-medium text-enterprise-fg underline-offset-4 group-hover:underline md:text-base", "data-slot": "case-study-card-control-label", "data-case-study-slot": "cta", children: [actionLabel ?? (access === "locked" ? "Unlock case study" : "View case study"), _jsx(Icon, { name: "navigation.forward", decorative: true, size: 16 })] })] }), _jsxs("span", { id: descriptionId, className: "sr-only", children: [relationshipLabel ? `${asSentence(relationshipLabel)} ` : "", asSentence(headline), " ", asSentence(result), " ", actionDescription ?? (access === "locked" ? "Access requires an unlock request." : "Opens the case study.")] })] }));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The package shell deliberately has no knowledge of Next.js, GateModal, or a
|
|
37
|
+
* consumer registry. That keeps every card shell deterministic and lets a
|
|
38
|
+
* production adapter provide the single navigation and access-flow boundary.
|
|
39
|
+
*/
|
|
40
|
+
export function CaseStudyCard({ href, accessibleName, identity, identityKind = "text", relationshipLabel, headline, result, media, actionLabel, actionAriaLabel, actionDescription, access = "open", density = "standard", presentation = "tenant", onUnlock, renderOpenControl, caseStudyId, lockedControlRef, className, }) {
|
|
41
|
+
const descriptionId = useId();
|
|
42
|
+
const content = (_jsx(CardBody, { accessibleName: accessibleName, identity: identity, identityKind: identityKind, relationshipLabel: relationshipLabel, headline: headline, result: result, media: media, actionLabel: actionLabel, actionDescription: actionDescription, access: access, density: density, descriptionId: descriptionId }));
|
|
43
|
+
if (access === "locked") {
|
|
44
|
+
if (!onUnlock) {
|
|
45
|
+
throw new Error("Locked case-study cards require an unlock handler");
|
|
46
|
+
}
|
|
47
|
+
const unlock = onUnlock;
|
|
48
|
+
const onKeyDown = (event) => {
|
|
49
|
+
if (event.key !== "Enter" && event.key !== " ")
|
|
50
|
+
return;
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
unlock();
|
|
53
|
+
};
|
|
54
|
+
return (_jsx("div", { ref: lockedControlRef, role: "button", tabIndex: 0, className: `${controlClassName} ${className ?? ""}`, "data-slot": "case-study-card", "data-access": "locked", "data-density": density, "data-card-presentation": presentation, "data-case-study-card": caseStudyId, "aria-label": actionAriaLabel ?? `Unlock ${accessibleName} case study`, "aria-describedby": descriptionId, "aria-haspopup": "dialog", onClick: unlock, onKeyDown: onKeyDown, children: content }));
|
|
55
|
+
}
|
|
56
|
+
if (renderOpenControl) {
|
|
57
|
+
return renderOpenControl({
|
|
58
|
+
href,
|
|
59
|
+
className: `${controlClassName} ${className ?? ""}`,
|
|
60
|
+
"data-slot": "case-study-card",
|
|
61
|
+
"data-access": "open",
|
|
62
|
+
"data-density": density,
|
|
63
|
+
"data-card-presentation": presentation,
|
|
64
|
+
"data-case-study-card": caseStudyId,
|
|
65
|
+
"aria-label": actionAriaLabel ?? `View ${accessibleName} case study`,
|
|
66
|
+
"aria-describedby": descriptionId,
|
|
67
|
+
children: content,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return (_jsx("a", { className: `${controlClassName} ${className ?? ""}`, "data-slot": "case-study-card", "data-access": "open", "data-density": density, "data-card-presentation": presentation, "data-case-study-card": caseStudyId, href: href, "aria-label": actionAriaLabel ?? `View ${accessibleName} case study`, "aria-describedby": descriptionId, children: content }));
|
|
71
|
+
}
|
|
72
|
+
export const CaseStudyCardShell = CaseStudyCard;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type ContactSectionField = {
|
|
3
|
+
name: string;
|
|
4
|
+
label: string;
|
|
5
|
+
kind: "text" | "email" | "tel" | "textarea";
|
|
6
|
+
required?: boolean;
|
|
7
|
+
autoComplete?: string;
|
|
8
|
+
hint?: string;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
maxLength?: number;
|
|
11
|
+
rows?: number;
|
|
12
|
+
};
|
|
13
|
+
export type ContactSectionState = {
|
|
14
|
+
kind: "idle";
|
|
15
|
+
} | {
|
|
16
|
+
kind: "invalid";
|
|
17
|
+
validationId: string | number;
|
|
18
|
+
message: string;
|
|
19
|
+
errors: Record<string, string>;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "submitting";
|
|
22
|
+
message: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "success";
|
|
25
|
+
title: string;
|
|
26
|
+
message: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: "failure";
|
|
29
|
+
message: string;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "unavailable";
|
|
32
|
+
message: string;
|
|
33
|
+
};
|
|
34
|
+
export type ContactFormProps = {
|
|
35
|
+
formTitle: string;
|
|
36
|
+
formDescription?: string;
|
|
37
|
+
headingLevel?: 2 | 3;
|
|
38
|
+
fields: readonly ContactSectionField[];
|
|
39
|
+
values: Record<string, string>;
|
|
40
|
+
state: ContactSectionState;
|
|
41
|
+
submitLabel: string;
|
|
42
|
+
submittingLabel: string;
|
|
43
|
+
onValueChange: (name: string, value: string) => void;
|
|
44
|
+
onSubmit: () => void;
|
|
45
|
+
reset?: {
|
|
46
|
+
label: string;
|
|
47
|
+
onAction: () => void;
|
|
48
|
+
};
|
|
49
|
+
honeypot?: {
|
|
50
|
+
name: string;
|
|
51
|
+
label: string;
|
|
52
|
+
};
|
|
53
|
+
notice?: ReactNode;
|
|
54
|
+
};
|
|
55
|
+
/** Shared contact behavior; consumers own content, validation and transport. */
|
|
56
|
+
export declare function ContactForm({ formTitle, formDescription, headingLevel, fields, values, state, submitLabel, submittingLabel, onValueChange, onSubmit, reset, honeypot, notice, }: ContactFormProps): import("react").JSX.Element;
|