1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+
4+ < head >
5+ < meta charset ="UTF-8 ">
6+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
7+ < title > Kanban board</ title >
8+ < style >
9+ body {
10+ font-family : system-ui;
11+ font-size : .9rem ;
12+ margin : 3rem ;
13+ }
14+
15+ .kanban-board {
16+ padding : 2rem ;
17+ background : # eee ;
18+ display : masonry;
19+ grid-template-columns : 1fr repeat (2 , 1.5fr ) 1fr ;
20+ gap : 1rem 2rem ;
21+ max-width : 1500px ;
22+ border-radius : 1rem ;
23+ }
24+
25+ .sticky {
26+ background : # fffa87 ;
27+ border : 1px solid # e0e0e0 ;
28+ border-radius : .5rem ;
29+ padding : 1rem ;
30+ box-shadow : 0 2px 4px rgba (0 , 0 , 0 , 0.1 );
31+ transition : box-shadow 0.2s ease, transform 0.2s ease;
32+ }
33+
34+ .sticky : hover {
35+ box-shadow : 0 4px 8px rgba (0 , 0 , 0 , 0.2 );
36+ transform : translateY (-2px ) translateX (-2px );
37+ }
38+
39+ .sticky h2 {
40+ font-size : 1.3rem ;
41+ margin : 0 ;
42+ }
43+
44+ .sticky .assignee {
45+ font-style : italic;
46+ font-size : smaller;
47+ }
48+ .sticky .assignee ::before {
49+ content : "👤 " ;
50+ }
51+
52+ .sticky : nth-child (4n + 1) {
53+ rotate : -1deg ;
54+ }
55+
56+ .sticky : nth-child (5n + 2) {
57+ rotate : 1deg ;
58+ }
59+
60+ [data-column = "backlog" ] {
61+ grid-column : 1 ;
62+ }
63+
64+ [data-column = "doing" ] {
65+ grid-column : 2 ;
66+ }
67+
68+ [data-column = "review" ] {
69+ grid-column : 3 ;
70+ }
71+
72+ [data-column = "done" ] {
73+ grid-column : 4 ;
74+ }
75+
76+ .sticky [data-column = "backlog" ] {
77+ background : # fffa87 ;
78+ }
79+
80+ .sticky [data-column = "doing" ] {
81+ background : # 87fffa ;
82+ }
83+
84+ .sticky [data-column = "review" ] {
85+ background : # fa87ff ;
86+ }
87+
88+ .sticky [data-column = "done" ] {
89+ background : # 3bffa3 ;
90+ }
91+
92+ .header h3 {
93+ margin : 0 0 0 0 ;
94+ text-align : center;
95+ }
96+
97+ .move {
98+ display : flex;
99+ justify-content : space-between;
100+ }
101+
102+ .move button {
103+ border : none;
104+ border-radius : 50% ;
105+ width : 2rem ;
106+ height : 2rem ;
107+ background : # fffb ;
108+ cursor : pointer;
109+ font-weight : bold;
110+ }
111+
112+ .move button : hover {
113+ background : # fff ;
114+ box-shadow : 0 4px 8px rgba (0 , 0 , 0 , 0.2 );
115+ transform : translateY (-1px );
116+ }
117+
118+ .move button : active {
119+ background : # fff ;
120+ box-shadow : 0 2px 4px rgba (0 , 0 , 0 , 0.2 );
121+ transform : translateY (1px );
122+ }
123+
124+ [data-column = "backlog" ] .move-back {
125+ visibility : hidden;
126+ }
127+
128+ [data-column = "done" ] .move-forward {
129+ visibility : hidden;
130+ }
131+ </ style >
132+ </ head >
133+
134+ < body >
135+ < h1 > Team awesome kanban board</ h1 >
136+
137+ < div class ="kanban-board ">
138+ < div class ="header " data-column ="backlog ">
139+ < h3 > Backlog</ h3 >
140+ </ div >
141+ < div class ="header " data-column ="doing ">
142+ < h3 > In-progress</ h3 >
143+ </ div >
144+ < div class ="header " data-column ="review ">
145+ < h3 > Under review</ h3 >
146+ </ div >
147+ < div class ="header " data-column ="done ">
148+ < h3 > Done</ h3 >
149+ </ div >
150+
151+ < div class ="sticky " data-column ="backlog ">
152+ < h2 > Faster search service</ h2 >
153+ < p > The search service takes at a minimum 500ms to start responding in our perf lab tests.</ p >
154+ < p class ="assignee "> Alice</ p >
155+ < div class ="move ">
156+ < button class ="move-back " title ="Move back "> <</ button >
157+ < button class ="move-forward " title ="Move forward "> ></ button >
158+ </ div >
159+ </ div >
160+ < div class ="sticky " data-column ="backlog ">
161+ < h2 > Fix search widget accessibility</ h2 >
162+ < p > Keyboard nav is broken.</ p >
163+ < p class ="assignee "> Bob</ p >
164+ < div class ="move ">
165+ < button class ="move-back " title ="Move back "> <</ button >
166+ < button class ="move-forward " title ="Move forward "> ></ button >
167+ </ div >
168+ </ div >
169+ < div class ="sticky " data-column ="doing ">
170+ < h2 > Bug sprint #4</ h2 >
171+ < p > See our bug board</ p >
172+ < p class ="assignee "> Charlie</ p >
173+ < div class ="move ">
174+ < button class ="move-back " title ="Move back "> <</ button >
175+ < button class ="move-forward " title ="Move forward "> ></ button >
176+ </ div >
177+ </ div >
178+ < div class ="sticky " data-column ="doing ">
179+ < h2 > Dark theme revamp</ h2 >
180+ < p > Customer report that our dark theme isn't dark enough.</ p >
181+ < p class ="assignee "> Dana</ p >
182+ < div class ="move ">
183+ < button class ="move-back " title ="Move back "> <</ button >
184+ < button class ="move-forward " title ="Move forward "> ></ button >
185+ </ div >
186+ </ div >
187+ < div class ="sticky " data-column ="review ">
188+ < h2 > Backend refactor</ h2 >
189+ < p > See the backend team's proposal to refactor for easier maintenance of the backend code.</ p >
190+ < p class ="assignee "> Alice</ p >
191+ < div class ="move ">
192+ < button class ="move-back " title ="Move back "> <</ button >
193+ < button class ="move-forward " title ="Move forward "> ></ button >
194+ </ div >
195+ </ div >
196+ < div class ="sticky " data-column ="done ">
197+ < h2 > Bug sprint #1</ h2 >
198+ < p > See our bug board</ p >
199+ < p class ="assignee "> Charlie</ p >
200+ < div class ="move ">
201+ < button class ="move-back " title ="Move back "> <</ button >
202+ < button class ="move-forward " title ="Move forward "> ></ button >
203+ </ div >
204+ </ div >
205+ < div class ="sticky " data-column ="done ">
206+ < h2 > Bug sprint #2</ h2 >
207+ < p > See our bug board</ p >
208+ < p class ="assignee "> Bob</ p >
209+ < div class ="move ">
210+ < button class ="move-back " title ="Move back "> <</ button >
211+ < button class ="move-forward " title ="Move forward "> ></ button >
212+ </ div >
213+ </ div >
214+ < div class ="sticky " data-column ="review ">
215+ < h2 > Bug sprint #3</ h2 >
216+ < p > See our bug board</ p >
217+ < p class ="assignee "> Dana</ p >
218+ < div class ="move ">
219+ < button class ="move-back " title ="Move back "> <</ button >
220+ < button class ="move-forward " title ="Move forward "> ></ button >
221+ </ div >
222+ </ div >
223+ < div class ="sticky " data-column ="done ">
224+ < h2 > Ship v0</ h2 >
225+ < p > Ship it! 🚢</ p >
226+ < p class ="assignee "> Alice</ p >
227+ < div class ="move ">
228+ < button class ="move-back " title ="Move back "> <</ button >
229+ < button class ="move-forward " title ="Move forward "> ></ button >
230+ </ div >
231+ </ div >
232+ </ div >
233+
234+ < script >
235+ addEventListener ( "click" , e => {
236+ const backButton = e . target . closest ( "button.move-back" ) ;
237+ const forwardButton = e . target . closest ( "button.move-forward" ) ;
238+ const sticky = e . target . closest ( ".sticky" ) ;
239+
240+ if ( backButton ) {
241+ const column = sticky . dataset . column ;
242+ if ( column === "doing" ) {
243+ sticky . dataset . column = "backlog" ;
244+ } else if ( column === "review" ) {
245+ sticky . dataset . column = "doing" ;
246+ } else if ( column === "done" ) {
247+ sticky . dataset . column = "review" ;
248+ }
249+ }
250+
251+ if ( forwardButton ) {
252+ const column = sticky . dataset . column ;
253+ if ( column === "backlog" ) {
254+ sticky . dataset . column = "doing" ;
255+ } else if ( column === "doing" ) {
256+ sticky . dataset . column = "review" ;
257+ } else if ( column === "review" ) {
258+ sticky . dataset . column = "done" ;
259+ }
260+ }
261+ } ) ;
262+ </ script >
263+ </ body >
264+
265+ </ html >
0 commit comments