@atelic-action/ui 0.17.0 → 0.17.2
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 +1 -1
- package/package.json +1 -1
- package/src/artifact/Note.tsx +1 -1
- package/src/artifact/Shot.tsx +8 -2
- package/src/styles/artifact.css +136 -22
package/README.md
CHANGED
|
@@ -248,7 +248,7 @@ export function ArtifactShell(props: Omit<ArtifactShellProps, "currentPath">) {
|
|
|
248
248
|
}
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
-
**The note** is the first touch for a business whose site publishes no email address, served at `/notes` and wrapped in `ArtifactShell` exactly as the writeup is. It is the writeup's sibling, not a variant: a title and a dateline, the opener, two lanes of findings (what the customer sees, what sits under the hood), the steps the work would start with, and the close over the shared `SignOff`. Every prop is plain data, so a routine can write a note as JSON; a paragraph is a string or an array of strings and `{ text, href }` links, and the sign off person's `role` is the one field that also takes a node. A finding is a `Callout` with its `WriteupShot` under it. It reads on a phone first,
|
|
251
|
+
**The note** is the first touch for a business whose site publishes no email address, served at `/notes` and wrapped in `ArtifactShell` exactly as the writeup is. It is the writeup's sibling, not a variant: a title and a dateline, the opener, two lanes of findings (what the customer sees, what sits under the hood), the steps the work would start with, and the close over the shared `SignOff`. Every prop is plain data, so a routine can write a note as JSON; a paragraph is a string or an array of strings and `{ text, href }` links, and the sign off person's `role` is the one field that also takes a node. A finding is a `Callout` with its `WriteupShot` under it. Its column is the writeup's 920px, centered under the header with the header's `--gutter`, and its text runs the column's full width. A finding sets its screen under its words on a phone and beside them, on the right, when wide and on paper. It reads on a phone first, stacks the two lanes as separate sections top to bottom at every width and on paper, never side by side, and prints to one letter sheet under the writeup's `@page`.
|
|
252
252
|
|
|
253
253
|
The documents import no stylesheet of their own. A site imports `@atelic-action/ui/styles/artifact.css` in its base sheet after `gate.css` and before its `theme.css`, so every page carries the rules whichever route it is. The sheet holds two `@page` rules, the monthly page's and then the writeup's, and the later one wins for every page a site prints; the order inside the sheet is the order the template's build bundled them in and is load bearing.
|
|
254
254
|
|
package/package.json
CHANGED
package/src/artifact/Note.tsx
CHANGED
|
@@ -121,7 +121,7 @@ function Paragraph({ paragraph, className }: { paragraph: NoteParagraph; classNa
|
|
|
121
121
|
|
|
122
122
|
function Finding({ finding }: { finding: NoteFinding }) {
|
|
123
123
|
return (
|
|
124
|
-
<li className="nt-finding">
|
|
124
|
+
<li className={finding.shot ? "nt-finding has-shot" : "nt-finding"}>
|
|
125
125
|
<Callout
|
|
126
126
|
tone="warn"
|
|
127
127
|
title={
|
package/src/artifact/Shot.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Maximize2 } from "lucide-react";
|
|
1
2
|
import { newTabProps } from "../lib/newTabProps";
|
|
2
3
|
|
|
3
4
|
export interface WriteupShot {
|
|
@@ -12,14 +13,19 @@ export interface WriteupShot {
|
|
|
12
13
|
/**
|
|
13
14
|
* The owner's own screen: the crop, opening the full screenshot in a new tab
|
|
14
15
|
* when it has one, over its caption. The writeup and the note both wear it;
|
|
15
|
-
* its styles (.op-shot) are the writeup's, and the note only sizes it.
|
|
16
|
+
* its styles (.op-shot) are the writeup's, and the note only sizes it. A
|
|
17
|
+
* linked crop says it opens: a hover title, and an expand badge the note
|
|
18
|
+
* shows on its thumbnails and the writeup keeps hidden.
|
|
16
19
|
*/
|
|
17
20
|
export function Shot({ shot }: { shot: WriteupShot }) {
|
|
18
21
|
return (
|
|
19
22
|
<figure className="op-shot">
|
|
20
23
|
{shot.href ? (
|
|
21
|
-
<a href={shot.href} {...newTabProps(shot.href, true)}>
|
|
24
|
+
<a href={shot.href} title="Open the full picture" {...newTabProps(shot.href, true)}>
|
|
22
25
|
<img src={shot.src} alt={shot.alt} loading="lazy" />
|
|
26
|
+
<span className="op-shot-open" aria-hidden="true">
|
|
27
|
+
<Maximize2 size={12} />
|
|
28
|
+
</span>
|
|
23
29
|
</a>
|
|
24
30
|
) : (
|
|
25
31
|
<span className="op-shot-frame">
|
package/src/styles/artifact.css
CHANGED
|
@@ -1392,6 +1392,10 @@
|
|
|
1392
1392
|
:is(.mkt, .atelic-ui) .op-shot a {
|
|
1393
1393
|
cursor: zoom-in;
|
|
1394
1394
|
}
|
|
1395
|
+
/* The expand badge on a linked crop: off here, the note turns it on. */
|
|
1396
|
+
:is(.mkt, .atelic-ui) .op-shot-open {
|
|
1397
|
+
display: none;
|
|
1398
|
+
}
|
|
1395
1399
|
:is(.mkt, .atelic-ui) .op-shot img {
|
|
1396
1400
|
width: 100%;
|
|
1397
1401
|
height: auto;
|
|
@@ -1863,11 +1867,18 @@
|
|
|
1863
1867
|
|
|
1864
1868
|
/* =================================================================
|
|
1865
1869
|
THE NOTE: the first touch set as a page (Note.tsx). A letter, not a
|
|
1866
|
-
report
|
|
1870
|
+
report, read on a phone first. Its column is the writeup's 920px,
|
|
1871
|
+
centered under the header with the header's own gutters, and every
|
|
1872
|
+
line of text runs the column's full width.
|
|
1867
1873
|
|
|
1868
|
-
-
|
|
1869
|
-
|
|
1870
|
-
-
|
|
1874
|
+
- The two lanes are separate sections stacked top to bottom at
|
|
1875
|
+
every width and on paper, never side by side.
|
|
1876
|
+
- Phone first: a finding is its Callout with the owner's screen
|
|
1877
|
+
under it. Wide (721px and up) and on paper, a finding with a
|
|
1878
|
+
screen is one row, the words left and the screen right, top
|
|
1879
|
+
aligned; the screen's column sizes to the picture, a phone crop
|
|
1880
|
+
about 260px and a wide card up to 45% of the row. A finding
|
|
1881
|
+
with no screen takes the full width.
|
|
1871
1882
|
- Print: one letter sheet. The chrome steps aside (the writeup's print
|
|
1872
1883
|
rules already hide the header and the credit band on any artifact
|
|
1873
1884
|
page), the type comes down, and the screens shrink. The note sets
|
|
@@ -1887,10 +1898,12 @@
|
|
|
1887
1898
|
color: var(--ink);
|
|
1888
1899
|
background: var(--surface);
|
|
1889
1900
|
}
|
|
1901
|
+
/* The writeup's column (.op-doc, 920px), centered under the header and
|
|
1902
|
+
held off the edges by the header's gutters (chrome.css, .nav-inner). */
|
|
1890
1903
|
:is(.mkt, .atelic-ui) .nt-doc {
|
|
1891
|
-
max-width:
|
|
1904
|
+
max-width: calc(920px + 2 * var(--gutter));
|
|
1892
1905
|
margin: 0 auto;
|
|
1893
|
-
padding: calc(var(--nav-height) + 22px)
|
|
1906
|
+
padding: calc(var(--nav-height) + 22px) var(--gutter) 48px;
|
|
1894
1907
|
font-size: 17px;
|
|
1895
1908
|
line-height: 1.6;
|
|
1896
1909
|
print-color-adjust: exact;
|
|
@@ -1941,7 +1954,8 @@
|
|
|
1941
1954
|
text-wrap: pretty;
|
|
1942
1955
|
}
|
|
1943
1956
|
|
|
1944
|
-
/* ---- the two lanes, each a heading and its findings
|
|
1957
|
+
/* ---- the two lanes, each a heading and its findings, one above the
|
|
1958
|
+
other at every width ---- */
|
|
1945
1959
|
:is(.mkt, .atelic-ui) .nt-lanes {
|
|
1946
1960
|
display: grid;
|
|
1947
1961
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -1973,9 +1987,9 @@
|
|
|
1973
1987
|
font-size: 16px;
|
|
1974
1988
|
line-height: 1.5;
|
|
1975
1989
|
}
|
|
1976
|
-
/* The screen
|
|
1977
|
-
with the words. It keeps its own shape,
|
|
1978
|
-
never
|
|
1990
|
+
/* The screen is a thumbnail under its finding, set in from the icon so it
|
|
1991
|
+
lines up with the words. It keeps its own shape, held to 200px tall and
|
|
1992
|
+
never the lane's full width; a click opens the full picture. */
|
|
1979
1993
|
:is(.mkt, .atelic-ui) .nt-finding .op-shot {
|
|
1980
1994
|
margin: 10px 0 0 28px;
|
|
1981
1995
|
}
|
|
@@ -1986,10 +2000,45 @@
|
|
|
1986
2000
|
}
|
|
1987
2001
|
:is(.mkt, .atelic-ui) .nt-finding .op-shot img {
|
|
1988
2002
|
width: auto;
|
|
1989
|
-
max-width: 100
|
|
1990
|
-
max-height:
|
|
2003
|
+
max-width: min(100%, 280px);
|
|
2004
|
+
max-height: 200px;
|
|
2005
|
+
}
|
|
2006
|
+
/* A linked thumbnail says it opens: the badge in its corner, and the
|
|
2007
|
+
frame takes the accent on hover and focus. */
|
|
2008
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot a {
|
|
2009
|
+
position: relative;
|
|
2010
|
+
color: inherit;
|
|
2011
|
+
text-decoration: none;
|
|
2012
|
+
transition:
|
|
2013
|
+
border-color 0.15s ease,
|
|
2014
|
+
box-shadow 0.15s ease;
|
|
2015
|
+
}
|
|
2016
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot a:hover,
|
|
2017
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot a:focus-visible {
|
|
2018
|
+
border-color: var(--primary);
|
|
2019
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
|
|
1991
2020
|
}
|
|
2021
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot-open {
|
|
2022
|
+
position: absolute;
|
|
2023
|
+
right: 4px;
|
|
2024
|
+
bottom: 4px;
|
|
2025
|
+
display: flex;
|
|
2026
|
+
align-items: center;
|
|
2027
|
+
justify-content: center;
|
|
2028
|
+
width: 20px;
|
|
2029
|
+
height: 20px;
|
|
2030
|
+
border-radius: 50%;
|
|
2031
|
+
background: color-mix(in srgb, var(--ink) 72%, transparent);
|
|
2032
|
+
color: var(--surface);
|
|
2033
|
+
}
|
|
2034
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot a:hover .op-shot-open,
|
|
2035
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot a:focus-visible .op-shot-open {
|
|
2036
|
+
background: var(--primary);
|
|
2037
|
+
}
|
|
2038
|
+
/* The caption wraps to the picture's width and never sets the column's. */
|
|
1992
2039
|
:is(.mkt, .atelic-ui) .nt-finding .op-shot figcaption {
|
|
2040
|
+
width: 0;
|
|
2041
|
+
min-width: 100%;
|
|
1993
2042
|
font-size: 12.5px;
|
|
1994
2043
|
line-height: 1.45;
|
|
1995
2044
|
color: var(--neutral-500);
|
|
@@ -2057,21 +2106,49 @@
|
|
|
2057
2106
|
text-decoration: none;
|
|
2058
2107
|
}
|
|
2059
2108
|
|
|
2060
|
-
/* ---- wide, and
|
|
2061
|
-
@media
|
|
2109
|
+
/* ---- wide: more room, and each screen beside its finding ---- */
|
|
2110
|
+
@media (min-width: 721px) {
|
|
2062
2111
|
:is(.mkt, .atelic-ui) .nt-doc {
|
|
2063
|
-
padding: calc(var(--nav-height) + 36px)
|
|
2112
|
+
padding-top: calc(var(--nav-height) + 36px);
|
|
2113
|
+
padding-bottom: 64px;
|
|
2064
2114
|
}
|
|
2065
2115
|
:is(.mkt, .atelic-ui) .nt-lanes {
|
|
2066
|
-
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
2067
2116
|
gap: 32px;
|
|
2068
2117
|
}
|
|
2069
2118
|
}
|
|
2070
2119
|
|
|
2071
|
-
/*
|
|
2120
|
+
/* A finding with a screen is one row: the words left, the screen right,
|
|
2121
|
+
top aligned. The screen is a thumbnail about as tall as a three line
|
|
2122
|
+
finding, so a phone crop reads as a tall one about 80px wide and a
|
|
2123
|
+
wide card as a short wide one; the column shrinks to it, held to 45%
|
|
2124
|
+
of the row, with room enough for the caption under it. */
|
|
2125
|
+
@media print, (min-width: 721px) {
|
|
2126
|
+
:is(.mkt, .atelic-ui) .nt-finding.has-shot {
|
|
2127
|
+
display: grid;
|
|
2128
|
+
grid-template-columns: minmax(0, 1fr) fit-content(45%);
|
|
2129
|
+
column-gap: 32px;
|
|
2130
|
+
align-items: start;
|
|
2131
|
+
}
|
|
2132
|
+
:is(.mkt, .atelic-ui) .nt-finding.has-shot .op-shot {
|
|
2133
|
+
margin: 0;
|
|
2134
|
+
min-width: 150px;
|
|
2135
|
+
}
|
|
2136
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot img {
|
|
2137
|
+
max-width: 100%;
|
|
2138
|
+
max-height: 170px;
|
|
2139
|
+
}
|
|
2140
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot figcaption {
|
|
2141
|
+
font-size: 12px;
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
/* ---- print: one letter sheet ----
|
|
2146
|
+
The rows hold on paper, since they are shorter than the stacked page.
|
|
2147
|
+
The sheet is the page at the writeup's three quarters, the thumbnails
|
|
2148
|
+
are held short with room for their captions, and the badge drops. */
|
|
2072
2149
|
@media print {
|
|
2073
2150
|
html:has(:is(.mkt, .atelic-ui) .nt-doc) {
|
|
2074
|
-
zoom: 0.
|
|
2151
|
+
zoom: 0.74;
|
|
2075
2152
|
}
|
|
2076
2153
|
:is(.mkt, .atelic-ui) .nt {
|
|
2077
2154
|
background: none;
|
|
@@ -2080,26 +2157,63 @@
|
|
|
2080
2157
|
max-width: none;
|
|
2081
2158
|
padding: 0;
|
|
2082
2159
|
font-size: 15px;
|
|
2083
|
-
line-height: 1.
|
|
2160
|
+
line-height: 1.45;
|
|
2161
|
+
}
|
|
2162
|
+
:is(.mkt, .atelic-ui) .nt h1 {
|
|
2163
|
+
font-size: 32px;
|
|
2084
2164
|
}
|
|
2085
2165
|
:is(.mkt, .atelic-ui) .nt-opener {
|
|
2166
|
+
margin-top: 12px;
|
|
2086
2167
|
font-size: 16px;
|
|
2087
2168
|
}
|
|
2088
2169
|
:is(.mkt, .atelic-ui) .nt-lanes,
|
|
2089
2170
|
:is(.mkt, .atelic-ui) .nt-start,
|
|
2090
2171
|
:is(.mkt, .atelic-ui) .nt-close {
|
|
2091
|
-
margin-top:
|
|
2092
|
-
padding-top:
|
|
2172
|
+
margin-top: 16px;
|
|
2173
|
+
padding-top: 14px;
|
|
2174
|
+
}
|
|
2175
|
+
:is(.mkt, .atelic-ui) .nt-lanes {
|
|
2176
|
+
gap: 18px;
|
|
2177
|
+
}
|
|
2178
|
+
:is(.mkt, .atelic-ui) .nt-lane h2 {
|
|
2179
|
+
margin-bottom: 10px;
|
|
2180
|
+
break-after: avoid;
|
|
2181
|
+
}
|
|
2182
|
+
:is(.mkt, .atelic-ui) .nt-findings {
|
|
2183
|
+
gap: 14px;
|
|
2093
2184
|
}
|
|
2094
2185
|
:is(.mkt, .atelic-ui) .nt-finding .callout {
|
|
2095
2186
|
font-size: 14.5px;
|
|
2096
2187
|
}
|
|
2188
|
+
:is(.mkt, .atelic-ui) .nt-finding.has-shot {
|
|
2189
|
+
grid-template-columns: minmax(0, 1fr) fit-content(40%);
|
|
2190
|
+
column-gap: 24px;
|
|
2191
|
+
}
|
|
2192
|
+
:is(.mkt, .atelic-ui) .nt-finding.has-shot .op-shot {
|
|
2193
|
+
min-width: 1.6in;
|
|
2194
|
+
}
|
|
2097
2195
|
:is(.mkt, .atelic-ui) .nt-finding .op-shot img {
|
|
2098
|
-
max-height: 1.
|
|
2196
|
+
max-height: 1.5in;
|
|
2197
|
+
}
|
|
2198
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot-open {
|
|
2199
|
+
display: none;
|
|
2200
|
+
}
|
|
2201
|
+
:is(.mkt, .atelic-ui) .nt-finding .op-shot figcaption {
|
|
2202
|
+
font-size: 11.5px;
|
|
2203
|
+
line-height: 1.35;
|
|
2099
2204
|
}
|
|
2100
2205
|
:is(.mkt, .atelic-ui) .nt-finding .op-shot a {
|
|
2101
2206
|
cursor: auto;
|
|
2102
2207
|
}
|
|
2208
|
+
:is(.mkt, .atelic-ui) .nt-start ul {
|
|
2209
|
+
gap: 4px;
|
|
2210
|
+
}
|
|
2211
|
+
:is(.mkt, .atelic-ui) .nt-close p {
|
|
2212
|
+
margin-bottom: 10px;
|
|
2213
|
+
}
|
|
2214
|
+
:is(.mkt, .atelic-ui) .nt-close .op-who {
|
|
2215
|
+
margin-top: 14px;
|
|
2216
|
+
}
|
|
2103
2217
|
:is(.mkt, .atelic-ui) .nt-finding,
|
|
2104
2218
|
:is(.mkt, .atelic-ui) .nt-start,
|
|
2105
2219
|
:is(.mkt, .atelic-ui) .nt-close {
|